首页
社区
课程
招聘
[原创]2017HCTF第一题WP
发表于: 2017-11-12 21:01 6514

[原创]2017HCTF第一题WP

2017-11-12 21:01
6514

0x0 初探
先用PEID查看一下CM的信息
这里写图片描述
这里写图片描述
从图中可以发现,程序使用Debug的编译方式编译且有一个TLS回调函数。
因为程序有ASLR,不方便分析,因此我用FFI去掉后再继续分析。
这里写图片描述
1x0 分析TLS回调函数
OD载入,断在TLS入口处。
这里写图片描述
一共有四个函数,其中前两个我们需要关注一下。因为这两个函数是反调试的函数。
1x1 分析函数 0041141A
CM先创建一个进程快照
这里写图片描述
然后就开始枚举进程,取出进程名,如果进程名字符合如下进程名中的其中一个,就直接报错退出。

ollyice.exe
ollydbg.exe
peid.exe
ida.exe
idaq.exe

对应的检测代码如下:

1x2 分析函数 00411186
这段函数其实就是IsDebuggerPresent。检测了PEB的BeingDebugged,若BeingDebugged为0则未被调试,否则被调试。
函数代码如下:
这里写图片描述
1x3 一次性全部拆解
这两个检测函数都位于TLS回调函数内,因此删掉即可。
这里写图片描述
这样系统就不会去执行TLS回调函数了,而是直接执行入口点处的代码了。
2x0 分析第一个输入
OD来到main函数00412E20处,单步调试一阵发现第一个算法函数 00411316
因为这个函数的代码很长,所以使用IDA来分析。
IDA来到00411316处,使用F5插件查看反编译好后的C代码。
首先将注册码的顺序颠倒(123456789 -> 987654321)
这里写图片描述
然后将循环次数作为密匙,加密颠倒后的Key
这里写图片描述
最后和一串密文比较,若全部相等则通过第一个Key的验证。
这里写图片描述
v8处的数据如下:
这里写图片描述
计算注册码的办法很简单,写一个逆运算即可。
代码如下:
这里写图片描述
运行以后得到结果:M.KATSURAGI
3x0 分析第二个输入
第二个输入就有点复杂了,其中还夹杂着反调试(ntdll!NtQueryInformationProcess查询DebugPort)。x86用StrongOD插件,x64用xjun师傅的SharpOD插件都可以绕过(我是Windows7 x64)
首先程序判断输入的Key是否是0x23个字节,如果不是则失败。
这里写图片描述
构造一个key,使大小为0x23即可通过。我构造的是0123456789ABCDEFGHIJKLMNOPQRSTUVWXY
继续分析,来到第一个计算的函数(一共有四个),我先将这个计算的函数和将要出现的计算的函数分别标记,到最后一起分析。
第一个计算的函数我命名为First。
这里写图片描述
加密以后,CM做了一些操作以后(包括调试器的检测)来到第二个计算的函数,我命名为Second。
这里写图片描述
然后执行第三个计算的函数,我命名为Third
这里写图片描述
然后执行第四个计算的函数,我命名为Fourth
这里写图片描述
然后将First计算的数据的第八个字节开始用Second计算的七个字节替换,第十五个字节开始用Third计算的七个字节替换,第二十二个字节开始用Fourth的计算的七个字节替换。
这里写图片描述
最后和内置好的一串数据比较,如果相等就成功。
这里写图片描述
其中,内置好的正确数据如下:
这里写图片描述
3x1 四个计算函数之First的分析
First函数比较简单,将Key的每个字节和0x76异或。
这里写图片描述
3x2 四个计算函数之Second的分析
代码如下:
这里写图片描述
3x3 四个计算函数之Third的分析
这个和Second进行的运算差不多。代码如下:
这里写图片描述
3x4 四个计算函数之Fourth的分析
代码如下:
这里写图片描述
3x5 计算第二个注册码
这个注册码一共经历了四次变换(First Second Third Fourth)
其中,First运算可逆,Second Third Fourth都不是可逆的函数。
观察一下计算后的数据,容易发现注册码被分成了如下的五个部分:
这里写图片描述
其中有高亮的(第二个到第四个)都是被替换后的,而没有高亮的(第一个和最后一个)都是不被替换的,因此没有高亮的部分可以直接用First运算来还原。
而有高亮的部分我没有找到好的办法去还原,只有枚举了。
总体的计算思路如下:
1.先不考虑没有高亮的部分(第一个和最后一个),枚举第二个,用Second运算来枚举,尝试一个字节一个字节枚举,考虑到注册码都是可显示字符,scanf又有遇到空格截断的特性,因此从0x21开始枚举。若Second返回的的数据是正确的,则开始第二个字节的枚举。
2.枚举第三个,用Third运算来枚举,尝试一个字节一个字节枚举,若Third返回的的数据是正确的,则开始第二个字节的枚举。
3.枚举第四个,用Fourth运算来枚举,尝试一个字节一个字节枚举,若Fourth返回的的数据是正确的,则开始第二个字节的枚举。
4.这步中的数据应该是正确的Key经过First运算后的数据了,因为First运算是xor运算,故将这部分的数据再用First运算一次即可得到Key。
计算代码如下:

运行以后得到结果:hctf{>>D55_CH0CK3R_B0o0M!-037444eb}
4x0 最后一个输入
这个就很简单了,问你输入Y或者N,若输入Y则成功(不区分大小写),否则失败。
这里写图片描述
4x1 完整的计算代码
将上述代码写到一起,然后再加上输出最后一个注册码的代码即可。
代码如下:

运行以后得到完整的Key:
这里写图片描述
用原版CM注册,得到结果如下:
这里写图片描述
全文完。

附件中的RuntimeLibrary.zip是CM的运行库,作者没有打包在CM中,如果打开CM提示缺少DLL的话就下载RuntimeLibrary.zip中的文件解压到CM目录下

上传的附件:
收藏
免费 1
支持
分享
最新回复 (5)
雪    币: 1720
活跃值: (1205)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
2
星斗师傅666
2017-11-12 21:14
0
雪    币: 1355
活跃值: (334)
能力值: ( LV13,RANK:920 )
在线值:
发帖
回帖
粉丝
3
感谢分享,很有意思。
2017-11-12 23:25
0
雪    币: 5676
活跃值: (1303)
能力值: ( LV17,RANK:1185 )
在线值:
发帖
回帖
粉丝
4
感觉作为签到题有点难了。。。做了几个小时。。。可能是我菜吧(逃
2017-11-13 07:59
0
雪    币: 350
活跃值: (51)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
5



holing

感觉作为签到题有点难了。。。做了几个小时。。。可能是我菜吧(逃
四篇精华的大牛谦虚啥。
2017-11-13 20:28
0
雪    币: 1036
活跃值: (1296)
能力值: ( LV3,RANK:35 )
在线值:
发帖
回帖
粉丝
6
厉害厉害!
2017-11-14 10:48
0
游客
登录 | 注册 方可回帖
返回
//