首页
社区
课程
招聘
[原创]看雪CTF2016第20题原作者解析
发表于: 2016-12-11 22:09 3265

[原创]看雪CTF2016第20题原作者解析

2016-12-11 22:09
3265

作者简介:网名brichfire,职业看门大叔,爱好密码、数论、登山、下海……看雪CTF2016活动开始才初步学习程序逆向破解,出题之前才恶补反逆向技术。

题目设计思路:
1、  通过函数表隐藏调研过程,增加静态分析的难度。
    DWORD (*pfunc[8]) (char *); 
    int (*pfunc4[4]) (void);
2、通过3种反调试手段增加动态分析难度。
    超时退出线程
    CheckRemoteDebuggerPresent
    int 3,调试状态下进入无解的校验函数。
3、验证算法
N(11)阶幻方扣掉对角线的10个数据,该数据由用户输入数据查表覆盖,当N行、N列、2N条循环斜对角线之和相等的条件下验证成功。(出题的时候考虑N取更大值、甚至扣掉更多的数据,但是为了让破解者更加方便,也为了避免多解的情况只取了N为11,抠掉10个数)。

题目破解步骤:
1、  将下处反调试的影响去除,nop掉该指令,或者改为or esi, 1,否则进入无解的校验函数。
 
2、  去除下图中调试超时退出的代码,或者将jle改成jmp
 
3、  去除CheckRemoteDebuggerPresent反调试退出代码,将第一个jnz改为nop,将第二个jnz改为jmp(第二个其实可以不修改)。
 
4、  去除int 3反调试,将int 3的指令0xcc改为0x00,原来exception触发0x80000003异常,修改后触发0xc0000005异常,将异常处理的cmp ecx, 80000003h修改为cmp ecx, c0000005h。此时去除了int 3的反调试。


去除反调试之后调试状态下的exception执行后能够执行到如下代码

Call edx的值取决于ecx,ecx来自如下代码:

无反调试情况下ecx不应该去参与or 2运行,但应该参与or 1的运行,可以猜测ecx就应该为1,且需要构造输入使input[1]%4 == 1成立。ecx为1时执行到0x401500位置的check代码。

5、  校验
Sub_0x401500处的函数是校验代码,校验算法是一个N阶幻方,就是将1,2,3,……,N*N这些数填入一个N*N的方阵,使得N行、N列、2N条循环对角线之和相等。本题中N取11,并且已经将大部分数据填好,剩下的Table[i][i] (i从0到9)位置由用户输入查表生成。N为大于2的素数时,N阶幻方可通过如下公式生成,不知道公式可以由无需填充的右斜对角线计算得到和,再计算需要填充的位置:
  Table[i][j] = ((2*i+j+3)%N)*N + (2*i-j+N+1)%N + 1;  ( i, j 选自 0,1,2,……N-1)
校验矩阵如下
 
标注出来的位置实际应该为:  0x23,0x45,0x67,0x10,0x32,0x54,0x76,0x1f,0x41,0x63
这些值通过table_410ee0[input[i]]获得,根据下图数据,推断出input[i]依次为:
0x43,0x6d,0x4a,0x46,0x39,0x32,0x6f,0x52,0x63,0x75, 对应字符为:CmJF92oRcu
 
最后附上去除反调试之后的程序RmCrackMe和原程序CrackMe。


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

上传的附件:
收藏
免费 1
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//