Pwn学习随笔( 八 )


下面是一些常见指令的指令码

  • movq : The codes for these are shown in Figure 3A.
  • popq : The codes for these are shown in Figure 3B.
  • ret : This instruction is encoded by the single byte 0xc3.
  • nop : This instruction (pronounced “no op,” which is short for “no operation”) is encoded by the single byte 0x90. Its only effect is to cause the program counter to be incremented by 1
一些常见指令对应的机器码,movqpopqmovlnop(2 Bytes)、可以参考CSAPPAttackLab
Pwn学习随笔

文章插图

Pwn学习随笔

文章插图

Pwn学习随笔

文章插图

Pwn学习随笔

文章插图
寻找 gadget理论上,ROP是图灵完备的 。在漏洞利用过程中,比较常用的gadget有以下类型:
  • 保存栈数据到寄存器,如pop rax; ret;
  • 系统调用,如 syscall; ret;int 0x80; ret;
  • 会影响栈帧的gadget,如 leave; ret;pop rbp; ret , leave指令相当于move rsp(目的), rbp;(即rsp = rbp)pop rbp
  • 如果是一个很小的程序 , 首先应该查找有没有syscall这类的gadget,没有的话就要想办法获取一些动态链接库(如libc)的加载地址,再用libc中的gadget构造可以实现任意代码执行的ROP 。程序中常常有putsgetslibc提供的库函数,这些函数在内存中的地址会写在程序的GOT表中,当程序调用库函数时 , 会在GOT表中读出对应函数在内存中的地址,然后跳转到该地址执行 , 所以先利用puts函数打印库函数的地址,减掉该库函数与libc加载基地址的偏移,就可以计算libc的基地址 。然后可以利用libc中的gadget构造可以执行 " /bin/sh" 的ROP , 
ROPgadget使用ROPgadget检查程序中是否存在/bin/sh字符串或某条指令:ROPgadget --binary 文件名 --string="/bin/sh"ROPgadget --binary 文件名 --sting '/bin/sh'命令: ROPgadget --binary 文件名 --sting 'sh'命令: ROPgadget --binary 文件名 --sting 'cat flag'命令: ROPgadget --binary 文件名 --sting 'cat flag.txt'ROPgadget --binary 文件名 --only="pop|ret"用ROPgadget找一下程序里有没有可以用的改变rdi寄存器的值的gadgetsROPgadget --binary 文件名 --only "pop|ret" | grep rdi栈溢出栈溢出指的是程序向栈中某个变量中写入的字节数超过了这个变量本身所申请的字节数,因而导致与其相邻的栈中的变量的值被改变 。这种问题是一种特定的缓冲区溢出漏洞,类似的还有堆溢出,bss 段溢出等溢出方式 。栈溢出漏洞轻则可以使程序崩溃,重则可以使攻击者控制程序执行流程 。此外,我们也不难发现,发生栈溢出的基本前提是
  • 程序必须向栈上写入数据 。
  • 写入的数据大小没有被良好地控制 。
最典型的栈溢出利用是覆盖程序的返回地址为攻击者所控制的地址,当然需要确保这个地址所在的段具有可执行权限 。下面 , 我们举一个简单的例子:
#include <stdio.h>#include <string.h>void success() { puts("You Hava already controlled it."); }void vulnerable() {char s[12];gets(s);puts(s);return;}int main(int argc, char **argv) {vulnerable();return 0;}这个程序的主要目的读取一个字符串,并将其输出 。我们希望可以控制程序执行 success 函数 。
输入gcc -m32 -fno-stack-protector stack1.c -o stack1 -no-pie -z execstack进行编译,可以看见报错了(但仍会生成可执行文件),可以看出 gets 本身是一个危险函数 。它从不检查输入字符串的长度,而是以回车来判断输入是否结束,所以很容易可以导致栈 溢出 , 
Pwn学习随笔

文章插图
gcc 编译指令中,-m32 指的是生成 32 位程序; -fno-stack-protector 指的是不开启堆栈溢出保护,即不生成 canary 。-z execstack表示开启栈的可执行权限,在gcc4.1中默认禁用,此外 , 为了更加方便地介绍栈溢出的基本利用方式 , 这里还需要关闭 PIE(Position Independent Executable),避免加载基址被打乱 。不同 gcc 版本对于 PIE 的默认配置不同 , 我们可以使用命令gcc -v查看 gcc 默认的开关情况 。如果含有

推荐阅读