参考链接:
https://ctf-wiki.org/pwn/linux/user-mode/stackoverflow/x86/basic-rop/
https://www.jianshu.com/p/450361bce332
首先,查看一下程序的保护机制
可以看出程序是 32 位程序,其仅仅开启了栈不可执行保护。然后,我们使用 IDA 来查看源代码。
可以看出程序在主函数中使用了 gets 函数,显然存在栈溢出漏洞。此后在 secure 函数又发现了存在调用 system(“/bin/sh”) 的代码
那么如果我们直接控制程序返回至 0x0804863A,那么就可以得到系统的 shell 了。
所以我们现在要知道输入多少个字符会导致栈溢出
IDA上静态分析看到的东西有时和实际上运行的情况不一样,所以有时候需要进行动态分析,利用gdb等工具(IDA debug环境也可)
https://blog.lxscloud.top/2021/07/03/2021-06-06-Pwn%E7%9A%84%E4%B8%80%E4%BA%9B%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/
计算偏移量:
①使用pattern:
对pwn1进行gdb调试
$ gdb ret2text
生成溢出字符,需保证其长度能覆盖至RIP
$ pattern create 200
执行 r 或者 start 命令让程序运行。
注意:start 命令执行后,还需执行 contin 命令
在 please input 后,将之前生成的溢出字符串粘贴上去。
注意:不要加‘’
找到RBP的字符串
$ pattern offset MAAi
这里计算出的偏移量。不需要考虑堆栈平衡。构造playload时,直接与系统调用地址相加就可。(64位+8;32位+4)
或者:
由Invalid address 0x41384141,得出偏移地址
$ pattern offset 0x41384141
②使用cyclic
生成200个有序字符
$ cyclic 200
gdb调试
$ gdb ret2text
执行并贴上有序字符
gdb-peda$ r
aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaazaabbaabcaabdaabeaabfaabgaabhaabiaabjaabkaablaabmaabnaaboaabpaabqaabraabsaabtaabuaabvaabwaabxaabyaab
有溢出点,Invalid $PC address: 0x62616164,cyclic -l 地址 计算偏移量
$ cyclic -l 0x62616164
这里计算出偏移量。
③
首先需要确定的是我们能够控制的内存的起始地址距离 main 函数的返回地址的字节数。
.text:080486A7 lea eax, [esp+1Ch]
.text:080486AB mov [esp], eax ; s
.text:080486AE call _gets
可以看到该字符串是通过相对于 esp 的索引,所以我们需要进行调试,将断点下在 call 处,查看 esp,ebp,如下:
可以看到 esp 为 0xffffd0b0,ebp 为 0xffffd138,同时 s 相对于 esp 的索引为 esp+0x1c,因此,我们可以推断:
·s 的地址为 0xffffd0cc
·s 相对于 ebp 的偏移为 0x6c=108
·s 相对于返回地址的偏移为 0x6c+4=112
写exp:
vim ret2texte.py
运行exp: