-
-
[原创]看雪TSRC_2017秋季赛第七题---------WriteUp
-
发表于: 2017-11-7 00:39 4114
-
又是一道pwn题,需要利用程序的漏洞来getshell
然后读取存放在远程服务器上的flag文件
。
有了第四题的经验,这次就不会摸不到头脑不知从何下手了,依然是先看保护情况。
使用checksec pwn
可以查看到以下信息。
只有栈不可执行NX
与栈溢出检查Canary
,PIE
没开,GOT表可修改
,信心大增。接下来看流程。
直接IDA来看,感觉pwn类的题结构都是很清晰的(毕竟就做了这么两题),这题的内容很时髦,正是最近大热的吃鸡
, 程序流程为注册账号->创建角色名->登录->选择跳伞地点->开始拾荒
。
程序内存管理用的mmap
先分配好了空间,之后就是自己分配这些空间,而程序中可以输入的地方只有signup
和cheat
。
那么分别来看下这两部分,首先看signup
。
可以看出先分配了0x30的空间,然后生成一个chunk
,之后根据提示接受用户输入,完成账号创建。里面涉及了两个结构体,分别是accountInfo
和roleInfo
,其实后面的游戏里还有一个物品信息的结构体,不过解题没用上,就不写了。
accountInfo
与 roleInfo
结构体分析如下:
有了这些信息,再来详细看下makeChunk
这个函数。
这两个点没看出来利用的地方,但是在else
条件里的free_chunk
函数,就有点搞头了。
free_chunk
中,会先对chunk头
最开始的地方-1,当为0时,从数据区每次读8字节长度作为地址,并判断是否大于0x400000小于0x7FFFFFFFEFFF,如果满足这个条件,就把全局变量newChunk
的值写入这个地址,在将这个地址写入newChunk
中,最后newChunk
加8。
可能看到这里还没明白为什么这是个利用点,我们回到注册函数处再来看下。
structRole
这个全局指针是一个chunk
,它的数据区保存的有账号
和密码
,而这两个数据是我们可以输入的,所以当发生exchangeAddr
时,我们可以控制将哪里的地址与newChunk
交换,当然也包括got表
。
有了这个点,我们就可以修改got表
中导入函数指向的地址,这样当被修改的函数调用时,就会到我们可控的地址中执行,但是现在还差点东西,我们还没有可以写入数据或shellcode
的能力,改got表
指针也没有意义,不过不要着急,还有一个cheat
函数没有看。
下面来看cheat
的实现:
这里判断当全局变量cheatMem
不为空时,可以写入内容,而且长度为0x12C
,对比它的else
条件写入的长度,这里明显就是专门提供我们写入shellcode
的。只需要用前面的exchangeAddr
先给cheatMem
交换来一个地址,就可以写这个地址从+0x10开始长度0x12C的数据了。
现在我们可以修改got表
,也可以写入shellcode
,那么选择修改哪个函数呢? 由于在shellcode
布置好之前不能调用被修改的函数,找来找去好像只有exit
可以用,exit
在程序里可以被触发到的地方只有getPlace
,下面是getPlace
函数:
这里通过获取structRole
中pRole
结构体的place
成员(place
是pRole
指针偏移0x28
处)来判断选择的地点,而这个指针是个全局的,就在cheatMem
旁边,在利用时可以通过cheatMem
来修改这pRole
指向的地址,让它指到一个偏移0x28
处且肯定不是0~6
的地方就能执行default
流程触发exit
。
至此,利用的点与大致的方案就可以定下来了,总结一下:
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)