栈溢出高级ROP

ret2_dl_runtime_resolve

前置知识:*32位情况下如果return的函数不再使用,便直re + AAAA + 参数,如果需要连续执行的话,就需要用到ROP技术去维持栈平衡(主动清空栈),得以继续运行
下面直接刚一道题来看看:
XDCTF2015的pwn题:bof
查看保护措施,没有栈溢出保护,只有堆栈不可执行保护,爆破出栈大小为112,
这题分为好几步骤:
stage1:
先实现write函数的调用,使用栈迁移的骚操作骗到bss段中去:


image.png

image.png

image.png

发现是可以的:回显成功


image.png

接下来stage2:
先使用命令 objdump -d -j .plt bof看看write函数的plt汇编代码:


image.png

可以知道先跳到write的got表那里,其实存的是push $0x20的地址(源自程序员的自我修养一书),接着跳到那个plt[0]的地址,就是那个ret2_dl_runtime_resolve函数,那么我们简单修改下第二个payload即可实现:
plt[0] + index_offset相当于执行write函数
image.png

可行的操作:回显成功


image.png

stage3:
image.png

一波操作可以知道两个地址的值,然后我们到ida查看那个rel.plt(重定表)
image.png

直接可以知道write函数的got表(尚未有真实地址,0x804a01c)和info(0x607):
这样我们的fake_reloc就出来了:直接got表地址指针+符号表信息(这里是得到write函数的符合表所在地址,这就是write函数的真实调用),根据后面写的payload计算出偏移位置是7,那么占用4*7=28个字节,所以payload:
image.png

回显成功
image.png

说明我们成功地伪造假的重定位项是OK的,这里理解费劲了一些,重点看plt的重定位表,即那个rel.plt(readelf -S bof)
stage4:
中,我们控制了重定位表项,但是重定位表项的内容与 write 原来的重定位表项一致,这次我们需要构造自己的重定位表项,并且伪造该表项对应的符号。
这里的找到了动态链接符号表和动态链接字符串表:


image.png

stage3
接下来
image.png

这里我们可以知道,fake_sym_addr的4个参数。由于符号表每一项都是0x10的大小,所以这里要实现对齐操作,具体看payload

image.png

这样一来一样可以输出/bin/sh
image.png

stage5:
这里直接改st_name为我们知道的write即可:


image.png
image.png

stage6:
最后直接替换write为system即可,然后改相应的参数即可:


image.png

最后getshell成功!


image.png

最后完整的exp是这样的:
image.png

image.png

image.png

这就是ret2_dl_runtime_resolve的exp,之后遇到类似的题目可以套用这个模板去打~
总的来说就是利用了那个函数,控制字符串名指向我们自己写的字符串,然后就能实现调用,其中包含了elf深层的理解,
自我感觉理解的还不是很透彻感觉,之后慢慢有时间再深入了解下~

SROP介绍:
360春秋杯的一题:smallest


image.png

image.png

程序开了堆栈不可执行的保护,有栈溢出漏洞,程序真的很简洁,而且可以知道xor rax,rax,rax = 0,系统调用号为0是read函数,所以是read(0,rsp,400)调用, 向栈中读入400个字节,毫无疑问是有栈溢出的,由于程序中并没有 sigreturn 调用,系统调用号为15(rax = 15),其中,32 位的 sigreturn 的调用号为 77,64 位的系统调用号为 15。所以我们得自己构造,正好这里有 read 函数调用,所以我们可以通过 read 函数读取的字节数来设置 rax 的值。重要思路如下:
通过控制 read 读取的字符数来设置 RAX 寄存器的值,从而执行 sigreturn
通过 syscall 执行 execve("/bin/sh",0,0) 来获取 shell,我们知道execve的系统调用号为59。这样这个payload就出来了:

image.png

你可能感兴趣的:(栈溢出高级ROP)