首页
社区
课程
招聘
[原创]2017看雪CTF第一题WP
发表于: 2017-6-3 00:40 2352

[原创]2017看雪CTF第一题WP

2017-6-3 00:40
2352

题目拿到手,先跑下,

惯例PEID查下壳,恩啥也没有。

strings扫一遍字符串,发现有Registration和error字眼,OD载入程序,右键分析字符串可以看到判断处,点击进入:

向上可以看到整个判断的代码部分,bp GetDlgItemTextA下断点(该函数用于获取输入框文本),F9运行,输入注册码1234,断在这里: 

注意这里是系统领空,内存窗口对代码段下断,F9返回程序领空:

结合IDA分析可知此处调用strlen函数对输入注册码长度判断,长度必须为4:

接下来程序对输入的注册码判断是否存在0,存在则跳转到注册失败处:(0x30是‘0’的ascii码)

然后把注册码转换为数字(如:'1'-0x30=1):(ecx值为0x30)

其中涉及到了几个浮点运算指令

指令格式指令含义执行操作
FILD src装入整数到st(0)st(0) <- src
FIDIV src除以一个整数st(0) <- st(0) /src
FSUBP st(i),st相减st(i) <-st(i) - st(0),然后执行一次出栈操作
FIMUL src乘上一个整数st(0) <- st(0) * src
FSTP dest目标地址赋st(0)值dest <- st(0)
FLD src装入实数到st(0)st(0) <- src
FCOMP src比较将st(0)和src比较

分析程序,逻辑很简单,依次读入CABD并转化为数字(设注册码格式为A-B-C-D),其中读入CA到st(1)和st(0)寄存器后,存储B除以A的结果到st(0),将C减去st(0)的值并存入st(0),将D的值和st(0)相乘,之后乘一个常数16,得到结果和常数384相比,相同则注册成功,伪代码如下:

C=C-0x30;
st(0)=C;
A=A-0x30;
st(0)=A;
st(1)=C;
st(0)=st(0)/B;
st(0)=st(1)-st(0);
st(0)=st(0)*D;
st(0)=st(0)*16;
if st(0)==384
    goto success;
else
    goto fail;

核心验证方程为:

16*(D*(C-A/B))=384

写个脚本:

for a in range(0,10):
    for b in range(1,10):
        for c in range(0,10):
            for d in range(0,10):
                if d*(c-a/b)==24:
                    break
print 'Found it!The code is: ',a,b,c,d

最后结果:

注:此题存在严重多解情况,满足该方程的值不只一个,大家可以试试。



[培训]科锐逆向工程师培训第53期2025年7月8日开班!

收藏
免费 0
支持
分享
打赏 + 1.00雪花
打赏次数 1 雪花 + 1.00
 
赞赏  CCkicker   +1.00 2017/06/06
最新回复 (0)
游客
登录 | 注册 方可回帖
返回