首页
社区
课程
招聘
[原创]KCTF2021 春季赛 第二题 南冥神功 WP
2021-5-12 21:44 4224

[原创]KCTF2021 春季赛 第二题 南冥神功 WP

2021-5-12 21:44
4224

程序丢IDA F5+F12一下,逻辑比较简单,稍微分析一下就能理清

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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
int __cdecl main(int argc, const char **argv, const char **envp)
{
  char v3; // al
  int inputidx; // esi
  int tableidx; // ecx
  int v7; // edx
  int v8; // eax
  unsigned int x; // ecx
  int op; // eax
  int i; // edx
  int v12; // eax
  char *v13; // eax
  char *v14; // eax
  int v15; // edx
  char *v16; // ecx
  int v17; // eax
  int v18; // eax
  int v19; // eax
  int v20; // [esp+1Ch] [ebp-60h]
  unsigned int y; // [esp+20h] [ebp-5Ch]
  unsigned int v22; // [esp+24h] [ebp-58h]
  char chr; // [esp+2Bh] [ebp-51h]
  int v24; // [esp+2Ch] [ebp-50h]
  char v25[76]; // [esp+30h] [ebp-4Ch] BYREF
 
  sub_40AD70();
  _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKa((std::ostream::sentry *)&dword_4B8860, "Input your code: ");
  sub_4B0AB0((int)&dword_4B8680, v25);
  if ( strlen(v25) <= 0x30 )
  {
    v3 = v25[0];
    if ( v25[0] )
    {
      inputidx = 0;
      y = 0;
      v22 = 0;
      v24 = dword_4B7020;
      chr = a0123456789abcd[0];
LABEL_4:
      if ( v24 > 0 )
      {
        tableidx = 0;
        if ( chr == v3 )
        {
LABEL_11:
          v7 = (inputidx + tableidx / 6) % 6;   // 将输入拆分成两个迷宫步骤
          v8 = tableidx + inputidx;
          x = v22;
          v20 = v7;
          op = 5 - v8 % 6;
          for ( i = 0; ; i = 1 )                // 走迷宫
          {
            switch ( op )
            {
              case 1:
                ++x;
                break;
              case 2:
                v17 = (y++ & 1) == 0;
                x += v17;
                break;
              case 3:
                v12 = (y++ & 1) != 0;
                x -= v12;
                break;
              case 4:
                --x;
                break;
              case 5:
                v19 = (y-- & 1) != 0;
                x -= v19;
                break;
              default:
                v18 = (y-- & 1) == 0;
                x += v18;
                break;
            }
            if ( x > 9 )
              break;
            if ( y > 8 )
              break;
            v13 = &maze[10 * y + x];
            if ( *v13 )
              break;
            *v13 = 1;
            if ( i == 1 )
            {
              ++inputidx;
              v22 = x;
              v3 = v25[inputidx];
              if ( v3 )
                goto LABEL_4;
              goto LABEL_19;
            }
            op = v20;
          }
        }
        else
        {
          while ( v24 != ++tableidx )
          {
            if ( a0123456789abcd[tableidx] == v3 )
              goto LABEL_11;
          }
        }
      }
    }
    else
    {
LABEL_19:
      v14 = maze;                               // 迷宫里没有0则成功
      v15 = 0;
      do
      {
        v16 = v14 + 10;
        do
          v15 += *v14++ == 0;
        while ( v16 != v14 );
      }
      while ( &unk_4B70DA != (_UNKNOWN *)v16 );
      if ( !v15 )
      {
        sub_4ABF30(&dword_4B8860, "Good job!", 9);
        _ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_(&dword_4B8860);
        return 0;
      }
    }
  }
  sub_4ABF30(&dword_4B8860, "Try again...", 12);
  _ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_(&dword_4B8860);
  return 0;
}

从伪代码里能看出是一个10*9的迷宫,从S出发,最后全部不为0即可

1
2
3
4
5
6
7
8
9
[S, 0, 1, 0, 0, 1, 0, 0, 1, 1]
[1, 1, 0, 0, 1, 0, 0, 1, 0, 0]
[0, 0, 1, 0, 1, 1, 1, 1, 1, 0]
[0, 1, 1, 0, 1, 0, 0, 1, 0, 0]
[0, 0, 1, 0, 0, 1, 0, 0, 1, 1]
[1, 1, 0, 1, 1, 1, 0, 1, 0, 1]
[0, 0, 1, 1, 1, 1, 0, 1, 0, 1]
[0, 1, 1, 0, 0, 1, 0, 1, 0, 1]
[0, 0, 0, 1, 0, 0, 1, 1, 0, 0]

人肉解出迷宫的步骤,结合伪代码的switch得到结果

1
1,2,3,4,3,2,1,2,3,4,3,2,1,1,0,1,2,1,0,0,5,0,5,4,3,4,5,0,5,0,1,2,1,0,1,2,1,2,3,4,3,2,2,3,2,1

最后随便撸份python穷举一下解出flag

1
2
3
4
5
6
7
8
9
10
11
tablestr='0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
flag=''
resultarr=[1,2,3,4,3,2,1,2,3,4,3,2,1,1,0,1,2,1,0,0,5,0,5,4,3,4,5,0,5,0,1,2,1,0,1,2,1,2,3,4,3,2,2,3,2,1]
i=0
while len(flag)<23:
    for j in range(36):
        if (i+j//6)%6==resultarr[i*2+1] and 5-(i+j)%6==resultarr[i*2]:
            flag+=tablestr[j]
            i+=1
            break
print(flag)

解出flag为:GJ0V4LA4VKEVQZSVCNGJ00N


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

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