拿到文件后,先进unbuntu终端checksec一下,发现保护很弱,只开了Partial RELRO,存在栈溢出攻击的可能。
并且,我们发现该文件是64位的,那么我们放到IDA里反汇编一下(转成C语言格式),找到main函数:
发现if ( dword_60106C == 1853186401 ) sub_400686(); 写的有点蹊跷,大概是有东西在里面了,点进去一看,果不其然
查看一下dword_60106C的类型,是int。现在,问题就转变成了如何让dword_60106C的值变为1853186401,以触发sub_400686()函数的执行呢?
我们再次查看一下main函数,发现有一个读入的函数
虽然是从标准流中向unk_601068中输入数据,看似跟dword_60106C并没有关系。但是我们要开动脑筋,灵活利用一切条件!联想到前面checksec发现该程序的弱保护状态,我们可以尝试通过栈溢出来覆盖dword_60106C的值,让我们来看看这是否可行。先查看unk_601068在内存中的位置
果然,不出所料,unk_601068和dword_60106C的位置可以说是近在咫尺,并且我们再次查看read函数,发现其实现似乎是存在漏洞的,read(0, &unk_601068, 0x10uLL),限制写入的长度为0x10uLL,而目标值的长度为1853186401,共10位,给我们的冗余貌似有点小啊,那么我们来计算下,究竟能在限制长度范围内实现覆盖吗?
0x00601068到0x0060106C,中间相差4个QWORD,4+10=14<0x10uLL。
到这里,我们发现read函数确实是存在漏洞的。那么我们可以尝试构造一个攻击载荷发送给该文件,让dword_60106C被修改为目标值,从而触发sub_400686()函数的执行。
分析到这里就差不多结束了,接下来我们执行构造出的攻击程序
发现成功了(请忽略那个文件未找到的情况....他们官网的服务器崩了没法连接到在线场景...所以能触发sub_400686()函数的执行就行了....)
放一下代码(使用python3实现):
from pwn import *
p = process('./T')
import struct
integer_value = 1853186401
payload = b'a'*4 + struct.pack('<I', integer_value)
p.sendline(payload)
p.interactive()
Comments | NOTHING