MozhuCY's blog.

2018看雪ctf第四题-密界寻踪

字数统计: 859阅读时长: 3 min
1970/01/01 Share

密界寻踪

恢复函数

  • ida打开后随便定位了一个字符串,随后定位到一个函数,但是不知道是做什么的,乖乖找main函数
  • 找到_main和_main_0函数,点进去发现_main_0跳到了程序的另一个地方,也就是_main_0_0函数,这里有巨多的花指令,jnz/jz/jno/jo/e8/什么的全用上了QAQ
  • 去花后发现这一段函数其实只有几步,push ebp/mov ebp,esp/sub esp,7Ch,然后一个大跳跳到函数主体,注意这个sub esp,7ch….被这个坑了好久
  • 跟着跳转过去后,刚准备f5,堆栈不平衡了.到函数尾后,发现函数自从add esp,7Ch后就非常不正常,当时想了好久甚至nop了这个指令但是总改不回来,扫了一眼函数体,并没有打乱函数帧栈平衡的函数,因此我又从头到后分析了一下函数,才想起来,原来在跳到这函数之前,有一个sub esp,7Ch的开辟空间的过程,这不正好对应上了吗= =,直接改了这个函数头三个push的帧栈,成功f5..代码如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
int __usercall sub_403136@<eax>(int a1@<ebp>)
{
unsigned __int64 v1; // rax
int v2; // ST08_4
unsigned __int64 v3; // rax
int v4; // eax
int result; // eax

memset((a1 - 124), 0xCCu, 0x7Cu);
*(a1 - 4) = 0;
*(a1 - 8) = 0;
do
{
v1 = __rdtsc();
v2 = v1;
v3 = __rdtsc();
}
while ( (v3 - v2) > 0xFFF );
*(a1 - 20) = 'g`wr';
*(a1 - 16) = 'tu`';
*(a1 - 12) = 0;
*(a1 - 32) = 'kqpd';
*(a1 - 28) = 'w';
*(a1 - 26) = 0;
*(a1 - 56) = 0;
*(a1 - 55) = 0;
*(a1 - 51) = 0;
*(a1 - 47) = 0;
*(a1 - 43) = 0;
*(a1 - 39) = 0;
*(a1 - 35) = 0;
*(a1 - 33) = 0;
*(a1 - 60) = 0;
*(a1 - 59) = 0;
sub_4011E0(); // 打印看雪 ctf2018
sub_40100A(); // 反调试
sub_401078((a1 - 20)); // success
sub_401078((a1 - 32)); // error
scanf("%s", a1 - 56, 24);
if ( strlen((a1 - 56)) > 23 ) // 输入长度小于等于23
{
printf((a1 - 32));
exit(0);
}
v4 = strlen((a1 - 53));
sub_401172(a1 - 53, &input, v4); // input[3:]输入转16进制
*(a1 - 4) = sub_40125D();
memcpy((a1 - 60), (a1 - 56), 3u);
if ( sub_40108C(a1 - 60) ) //判断input[0:3]是否为数字
{
*(a1 - 8) = sub_40128F(a1 - 60);
if ( *(a1 - 8) + *(a1 - 4) == 2 )
printf((a1 - 20)); // success
else
printf((a1 - 32)); // error
system("pause");
result = 0;
}
else
{
printf((a1 - 32));
result = 0;
}
return result;
}
  • 有一堆字符串是简单异或下标+1过的,大概是为了不让函数被定位,sub_401078()函数就是这个作用
  • 随后判断输入长度balabala什么的,然后就是重头戏check函数分析了
  • 字符串被分为2部分进行校验,前三位和余下位数,前三位首先简单校验是否为纯数字,很容易分析
  • 其次就是真的check函数了,比较长的字符串首先转成16进制的字符串转储在全局变量中,这里我把全局变量命名为input
  • 查找交叉引用定位到check这段的函数(其实就是(a1 - 4)后面的那个),因为两个返回值都为真的时候才会输出success,同理定位(a1 - 8)后面的那个函数

check1

  • 里面有成吨的函数…先恢复初始化的数据看看是什么,

208CBB7CD6ECC64516D07D978F5F0681F534EAD235D5C49ADD72D2DB840D5304
7da39de66016477b1afc3dc8e309dc429b5de855f0d616d225b570b68b88a585

  • 恢复出来这两串东西= =,第一组数值是作比较用的也就是strcmp的一个确定参数,还有一个3e9,转了一下发现是10进制的1001,怀疑是rsa
  • 解密出的第二串数字可以被分解为两个大素数pq,第一串应该就是密文了

check2

  • 标志性的置换盒,aes没跑,爆破秘钥搞定
CATALOG
  1. 1. 密界寻踪
    1. 1.1. 恢复函数
    2. 1.2. check1
    3. 1.3. check2