-
-
[原创]CTF2017第7题分析
-
发表于: 2017-6-15 12:02 3963
-
1.调试分析
OD加载,发现入口不是OEP指定的,估计有tls,直接清掉了tls,然后根据正常运行的程序,修复了OEP,这时就能正常断在OEP了,后面调试发现有个文件校验,有修改就退出程序了.
这里修改后,就可以patch程序了.
调试过程中,发现输入后验证就会异常,刚开始根据异常链查了半天,陷进去了,后来翻了下作者之前的帖子,发下之前有个Cm是在顶级异常处理那处理的.
直接IDA找到:
看了下,就是判断异常类型,然后发消息,直接索引ds:Msg,定位到关键点:
调试时候,可以输入字符串后,断在40E3E5,然后设置EIP为40E3ED,就可以跟踪字符串的验证操作了.
大概流程是:
004104FC |. FF15 283E4500 call dword ptr ds:[<&USER32.GetDlgItemTextA>]
先用GetDlgItemTextA读取到输入字符串,然后解码一个函数00411B30并调用
00410558 E8 D3150000 call 7crackme.00411B30
这里面先是对输入字符串依次XOR 0xCC,
然后就是对各个字符查表处理,得到的结果再通过sub_410F75 异或移位处理,然后在sub_411975中每个字符通过对4的商和余数,转化成2个字节,形成的字节流要和已知的一致,相关具体数据见代码.
验证通过后,会再根据输入字符串,解码一段数据,还原成功时候弹框用的函数.
2. 程序实现
程序是边调试边修改的,变量有点乱,不过可能更方便看流程.
function ctf_7() {
//首先根据确定表,反推出一个确定串
var checkBuf = new Buffer([
0x02, 0x02, 0x00, 0x03, 0x00, 0x00, 0x02, 0x03, 0x00, 0x01,
0x02, 0x03, 0x02, 0x00, 0x00, 0x02, 0x02, 0x00, 0x02, 0x02,
0x02, 0x03, 0x02, 0x03, 0x01, 0x00, 0x02, 0x02, 0x02, 0x01,
0x02, 0x03, 0x02, 0x02, 0x02, 0x01, 0x02, 0x03, 0x02, 0x03,
0x02, 0x01, 0x00, 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
0x00, 0x03, 0x01, 0x02, 0x02, 0x03, 0x02, 0x00, 0x00, 0x02,
0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x02, 0x01, 0x00,
0x02, 0x02, 0x02, 0x03, 0x00, 0x02, 0x01, 0x00, 0x00, 0x03]);
var resultBuf = new Buffer(checkBuf.length / 2);
var pattern = new Buffer("0123456789ABCDEF");
for (var i = 0; i < checkBuf.length; i=i+2)
{
var iTemp = checkBuf.readUInt8(i) * 4 + checkBuf.readUInt8(i + 1);
resultBuf[i / 2] = pattern[iTemp];
}
console.log(resultBuf.toString());
var resultBuf2 = Buffer.from(resultBuf.toString(), 'hex');
console.log(resultBuf2);
console.log(resultBuf2.toString('hex').toUpperCase());
//return;
//原始串加密过程
var srcBuf = new Buffer("12345678901234567890");
//2. 查表
var tableBuf = new Buffer([
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)