-
-
[原创]看雪CTF 2019Q3 第六题 神秘刺客
-
发表于: 2019-9-21 19:02 4237
-
保护情况
作者自己实现了堆分配函数malloc() free()
分配出的内存具有可执行属性,因此虽然开了NX
数据执行保护,但是堆上面的数据属性是可执行的
具有分配、释放、写以及打印一个栈地址的操作,而写的时候又输出了堆地址,泄露了栈地址和堆地址可以认为作者在暗示这是一个修改返回地址到堆上的操作,后面围绕着这个目标进行
释放后没有将指针置零,属于UAF
漏洞
分析堆结构需要结合分配与释放函数来分析
根据上图结合代码可发现,作者实现的堆是通过当前堆大小来定位相邻的下一个堆的,空闲堆的尾部保存了BK
和FD
指针
通常利用堆实现任意地址写,都是通过控制堆的BK
、FK
指针,利用堆块在从链表中卸下时的Unlink
操作来实现的,也就是BK->FD = FD; FD->BK = BK
作者实现的这个堆也有Unlink
操作,在malloc
分配内存时
根据上面的代码可以看出,想要进行Unlink
操作,需要满足以下几个条件:
要满足以上需要这样操作,申请4个堆(1-4号大小分别为:32 32 24 xx
),依次释放1号和3号堆,此时3号堆在链表头,再次申请32
字节大小的堆时就只能找到链表中被释放的1号堆,然后从链表卸下,就触发了Unlink
操作
而因为释放后没有将保存堆地址的指针清零,所以就可以修改已释放的3号堆的BK
与FD
,使其在重新分配时可以被我们控制来做任意地址写的操作
控制了BK
与FD
,需要将其指向一个符合堆结构的内存,即该内存前8字节为大小,加上大小到达FD
或BK
指定的位置,再修改
这就意味着必须要再栈中构造一个假的堆才能达到改写返回地址的作用
此时来看分配前的操作
用了一个足够大的buf
来接收用户输入,用完后也没有清空,而atoi()
函数只解析字符串前面可识别的数字部分,也不对对后面非数字字符的数据产生影响或修改
所以现在可被控制的栈空间也有了,剩下的就是计算地址,构造假对进行修改了,详见exp
,需要注意的时第四个堆的大小(哈哈,调一下就知道他是什么作用了)
作者的环境屏蔽了system('/bin/sh'),所以就直接找来读文件的ShellCode了
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)
赞赏
- [分享]教你签到获得更多的雪币 9957
- [原创]看雪CTF 2019总决赛 第六题 三道八佛 6008
- [原创]看雪CTF 2019总决赛 第二题 南充茶坊 6598