-
-
[原创]CTF2018第六题分析(qwertyaa)
-
发表于: 2018-6-26 18:53 4540
-
启动程序,首先给你一个串的hash,要你输入对应的串(这个串由获取自/dev/urandom
的随机字节生成)。
这里随机产生的串一共有43^4种可能,这个数字不大,可以进行暴力枚举,将得到的串的hash与给出hash比对,如果相同就可认为暴力产生的串是这个hash所对应的原串。
这里我用C++来暴力:
输入正确串后,我们发现其提供了Malloc、Show、Free、Exit四个功能,这令人联想到去年的几个pwn,但事实上正如题目名称所言,这道题和在heap中申请内存无关(noheap)。
我们跟踪程序,发现程序中有这样的内容:
这里的几个全局变量在.init_array处已经初始化:
我们发现这里的几个值其实都是一些指向函数的常指针经/dev/urandom
产生的随机串异或加密得来,并且在sub_1470
处会自动解密。
接下来代码跳转到sub_1107,这里有点难分析,但既然知道这几个操作必然和malloc
,free
,wrtie
有关,直接从这些函数处用Xref倒着来,我们就可以找到相关函数了。
正如刚才所言free
处的代码似乎没什么问题,于是把关键放在malloc
处:
这里的(unsigned __int8)(v2 - 1)
造成了一个漏洞,如果我们键入的Size是0,显然,这里会读入0xff个字符,这超过了全局变量qword_2030C0的大小,我们可以借此修改qword_203140处的内容。
qword_203140处的内容在.init_array处被初始化,这些部分内容有什么作用呢?排除其他函数后我们回到了sub_1107,而这个函数直接F5很难分析,不过既然是相对熟悉的x86_64代码,我们可以直接动态跟踪。
这里是一个Switch-Case结构,很容易让人想到这里其实是一个VM,而事实上我们可以发现qword_203140就是所执行的VM Code。
动态分析可知各个用到的指令的作用:
其中code为指向VM Code开头的指针;table为指向rbp-40的指针,也就是说我们可以传入64位值和访问stack中一部分内容。
以及整段代码的含义:
01 03
13 sub_1107
01 0f
04 get 40
06 get sub_1107+0x40
01 09
14 table[-9]=lastval
01 02
13 sub_OpById
16
这里到0x14前主要就是将接下来跳转到函数内时的[rsp]改为sub_1107+0x40。
0x14后主要就是跳转到 sub_OpById(即sub_1470中指定的v1)。
主要进行的就是如下两个操作:将栈中一个元素改为另一个元素+x(x可为任意64位值)和跳转到栈中指定元素。我们可以由此构造VM Code。
在Malloc处的"Content"中输入"a"*0x80后可输入如下的VM Code(下面的[rsp]为接下来跳转时的[rsp]):
完整exp如下(其中的./test为前面的C++程序编译后的可执行文件):
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)