-
-
[原创]看雪.TSRC 2017CTF秋季赛第七题WP
-
发表于: 2017-11-6 22:21 3306
-
此题是模拟堆的分配管理。漏洞点比较明显,利用上也不复杂,和堆漏洞的常见利用方法相似。
程序先mmap
了一段大小为4096字节的内存,将开始地址、结束地址保存,具体见代码:
然后进入程序主功能函数,是类似游戏角色管理的功能。有注册、登录、探图、捡装备、丢装备,除此之外,还有一个叫cheat
的一个功能,可以多次往一地址写内容。
再说游戏流程前,先说几个结构体。
账号信息 信息有用户名、密码、角色信息指针。
角色信息 信息有角色名、健康值、体力值、背包剩余空间、位置、装备信息指针。
装备信息 信息有装备序号、装备重量、拥有数目、指向下一件装备的指针、弹药量、威力值。
Note信息 这个是类似note的作弊功能。
游戏流程是先注册账号及角色。
注册时分别创建Account
和Character
类型的结构体变量,存储账户和角色信息。
再登录进游戏主菜单进行操作。主菜单如下:
1.Show my status
2.View the items in the package
3.GO TO..
4.Explore here
5.cheat
0.exit
游戏角色的数据全部保存在模拟的堆空间中,一个结构体变量对应一个堆空间。题目提供自写的模拟堆分配功能,但无释放功能。
模拟堆的分配过程是:根据记录的未用空间开始地址,当前的分配大小,计算出下一次分配的开始地址,写16字节的header
信息并返回当前空间数据块的地址(header_addr+0x10),属于空间连续分配。
与此相关的是一个写模拟chunk地址的功能。此功能可以将申请到的模拟chunk的地址写到目标地址处。包括一些header
等操作,似乎还有些bins管理的意思,实际意义没怎么看明白,利用时注意点就OK。
以上代码看完,很容易就能发现cheat
功能存在溢出。本来Note
数据结构大小为48字节,Note.content
大小为32字节,除首次调用外都能写入不大于300字节的数据。
总感觉此题利用方式不止一种,不过没有深究。
思路是,cheat
功能是唯一可以多次写数据的功能。如果能改写此功能的写入地址,那就能随意写数据。
在此之前,还需要泄露libc等信息。能泄露信息的地方:一是打印角色名时;二是打印装备信息时。后一种比较实际可靠。
由于模拟堆是连续空间分配的,所以先cheat
,申请Note
的变量空间,再explorer
,创建Item
的变量空间,而此空间是落在cheat
的可改写范围内的。可通过构造假的Item
链表,然后通过View the items
功能泄露出信息。为了程序不死,开始泄露的是rand
的地址,查Libc不确定,又泄露了其它的,程序会崩掉。
得到信息下一步就是改写got
表了。先看下一些全局变量的位置,上面的假链表构造也是利用了全局变量位置。
改写的实现第一步,必须把需改写的地址值写入到6050F0
地址处。这样的改写也可以通过构造假链表实现。
改写的目标选择atoi
的got
表。
最后附上我的exp,加上IDB文件(见附件)。