首页
社区
课程
招聘
[原创]2022KCTF签到WP
2022-5-10 16:28 1267

[原创]2022KCTF签到WP

2022-5-10 16:28
1267

签到-险象环生

拿到题目是一个注册程序,附件文档里有一对用户名和注册码:

1
2
用户名 : 461D7AD538F179EE
序列号 : 40403286341212

通过验证check得到success提示,要求得到KCTF对用应的注册码。

静态分析

ida打开之后主要逻辑部分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
.text:0040154B                 imul    ecx, eax, 3
.text:0040154E                 mov     dl, [ebp+edx-108h]
.text:00401555                 mov     [ebp+ecx-1D0h], dl
.text:0040155C                 lea     eax, [ebp-1D0h]
.text:00401562                 push    eax             ; 序列号后4字节
.text:00401563                 call    sub_4034AD      ; to interger
.text:00401568                 add     esp, 4
.text:0040156B                 mov     [ebp-3ACh], eax
.text:00401571                 mov     dword ptr [ebp-398h], offset loc_4015D2
.text:0040157B                 mov     dword ptr [ebp-3A8h], offset loc_401767
.text:00401585                 mov     ecx, [ebp-3A8h]
.text:0040158B                 sub     ecx, [ebp-398h]
.text:00401591                 mov     [ebp-3B0h], ecx
.text:00401597                 mov     edx, [ebp-398h]
.text:0040159D                 mov     [ebp-3B4h], edx
.text:004015A3                 cmp     dword_413000, 0
.text:004015AA                 jz      short loc_4015C9
.text:004015AC                 mov     eax, [ebp-3ACh]
.text:004015B2                 push    eax
.text:004015B3                 mov     ecx, [ebp-3B0h]
.text:004015B9                 push    ecx
.text:004015BA                 mov     edx, [ebp-3B4h]
.text:004015C0                 push    edx
.text:004015C1                 call    sub_4017E0      ; 此函数运行过程中生成覆盖0x4015d2后的代码,代码由序列号的后四个字节决定
.text:004015C6                 add     esp, 0Ch

到这里就能正常往下调试了,并且通过尝试发现注册码的后四字节必须为1212,这是用来生成代码的。之后就来到了关键的地方:

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
.text:004015D2 loc_4015D2:                             ; DATA XREF: .text:00401571↑o
.text:004015D2 mov     eax, [ebp-39Ch]
.text:004015D8 push    eax
.text:004015D9 lea     ecx, [ebp-2BCh]
.text:004015DF push    ecx
.text:004015E0 call    sub_401260                      ; 通过KCTF生成注册码前10字节
.text:004015E5 add     esp, 8
.text:004015E8 mov     [ebp-3B8h], eax
.text:004015EE mov     edx, [ebp-3A0h]
.text:004015F4 sub     edx, 4
.text:004015F7 push    edx
.text:004015F8 lea     eax, [ebp-108h]
.text:004015FE push    eax
.text:004015FF lea     ecx, [ebp-30h]
.text:00401602 push    ecx
.text:00401603 call    _strncpy                        ; 将注册码前10字节复制到固定地方
.text:00401608 add     esp, 0Ch
.text:0040160B push    0Ah
.text:0040160D lea     edx, [ebp-384h]
.text:00401613 push    edx
.text:00401614 mov     eax, [ebp-3B8h]
.text:0040161A push    eax
.text:0040161B call    __ultoa
.text:00401620 add     esp, 0Ch
.text:00401623 mov     dword_413000, 0
.text:0040162D lea     ecx, [ebp-30h]
.text:00401630 mov     [ebp-394h], ecx
.text:00401636 lea     edx, [ebp-384h]
.text:0040163C mov     [ebp-390h], edx
.text:00401642
.text:00401642 loc_401642:                             ; CODE XREF: .text:00401692↓j
.text:00401642 mov     eax, [ebp-390h]
.text:00401648 mov     cl, [eax]
.text:0040164A mov     [ebp-385h], cl
.text:00401650 mov     edx, [ebp-394h]
.text:00401656 xchg    cl, [edx]
.text:00401658 jnz     short loc_4016A0
.text:0040165A cmp     byte ptr [ebp-385h], 0
.text:00401661

函数sub_401260关键逻辑:

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
int __cdecl sub_401260(char *a1, int a2)
{
  int i; // ecx
  unsigned int v3; // eax
  unsigned int v4; // eax
  unsigned int v5; // eax
  unsigned int v6; // eax
  unsigned int v7; // eax
  unsigned int v8; // eax
  unsigned int v9; // eax
  unsigned int v10; // eax
  int v11; // edx
  unsigned int j; // ecx
  char v14; // al
  int v16[256]; // [esp+0h] [ebp-404h]
 
  for ( i = 0; i < 256; ++i )
  {
    v3 = (unsigned int)i >> 1;
    if ( (i & 1) != 0 )
      v3 ^= 0xEDB88320;
    if ( (v3 & 1) != 0 )
      v4 = (v3 >> 1) ^ 0xEDB88320;
    else
      v4 = v3 >> 1;
    if ( (v4 & 1) != 0 )
      v5 = (v4 >> 1) ^ 0xEDB88320;
    else
      v5 = v4 >> 1;
    if ( (v5 & 1) != 0 )
      v6 = (v5 >> 1) ^ 0xEDB88320;
    else
      v6 = v5 >> 1;
    if ( (v6 & 1) != 0 )
      v7 = (v6 >> 1) ^ 0xEDB88320;
    else
      v7 = v6 >> 1;
    if ( (v7 & 1) != 0 )
      v8 = (v7 >> 1) ^ 0xEDB88320;
    else
      v8 = v7 >> 1;
    if ( (v8 & 1) != 0 )
      v9 = (v8 >> 1) ^ 0xEDB88320;
    else
      v9 = v8 >> 1;
    if ( (v9 & 1) != 0 )
      v10 = (v9 >> 1) ^ 0xEDB88320;
    else
      v10 = v9 >> 1;
    v16[i] = v10;
  }
  v11 = a2;
  for ( j = -1; v11; --v11 )
  {
    v14 = *a1++;
    j = v16[(unsigned __int8)(j ^ v14)] ^ (j >> 8);
  }
  return ~j;
}

图片描述
这里得到了一串注册码,刚好10字节,先记下来1592086348
图片描述
这里调试就会跳往错误逻辑,直接运行是正确的,如何判断呢?我用正确的用户名/注册码调试发现也是走向错误逻辑,所以就判断这里应该是个调试的干扰项,后面就是success和error的分支了,所以根据之前的到的1592086348和固定的后四位1212可以得到KCTF对应的注册码15920863481212

 

这其实就是个由KCTF通过异或移位运算得到的数字。
验证:
图片描述


[CTF入门培训]顶尖高校博士及硕士团队亲授《30小时教你玩转CTF》,视频+靶场+题目!助力进入CTF世界

收藏
点赞0
打赏
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回