首页
社区
课程
招聘
[原创]KCTF2019_q4_第十题_幕后之王
发表于: 2019-12-30 16:12 7593

[原创]KCTF2019_q4_第十题_幕后之王

ccfer 活跃值
16
2019-12-30 16:12
7593
这个迷宫题目还是挺有意思的,后来发现可以多解碰撞crc,就觉得更有意思了

这个程序有tls和几处anti,还是要稍微小心一点
401660  CheckRemoteDebuggerPresent
4015E0  NtQueryInformationProcess
401710  GetThreadContext 检查drx之和
401690  setjmp3/SetUnhandledExceptionFilter

输入处理:
.text:004B5370                 sub     eax, 004BA040h           //"6GxRI4XlsLDQoVfb7pgE8hcYHaUtWZwKBPyNvuCSF3d0e2JA9q5jrTMOzknim1"
.text:004B5375                 test    al, al
.text:004B5377                 mov     [ebp+ebx+var_264], al    //base64 decode
...
.text:004B539E                 sub     eax, 12h                 //前18个字符
.text:004B53A1                 cmp     eax, 5Dh                 //后93个字符
.text:004B53A4                 ja      loc_4B55EC               //输入总长度不超过112
...
.text:004B53AA                 lea     ecx, [ebp+var_1E4]
.text:004B53B0                 mov     [ebp+var_298], 1
.text:004B53BA                 call    sub_4017A0               //初始化迷宫数据
.text:004B53BF                 lea     eax, [ebp+var_25B]
.text:004B53C5                 lea     ecx, [ebp+var_1E4]
.text:004B53CB                 mov     [esp+2C8h+var_2C4], eax
.text:004B53CF                 lea     eax, [ebp+var_264]
.text:004B53D5                 mov     [esp+2C8h+var_2C8], eax
.text:004B53D8                 call    sub_401BD0               //初始化几个大数,主要的是把输入的前18个字符拆分成两个大数x,y,还有一个固定的常数z
加密的迷宫初始数据,四个关卡,每关地图大小是6x5:
.text:004B5370                 sub     eax, 004BA040h           //"6GxRI4XlsLDQoVfb7pgE8hcYHaUtWZwKBPyNvuCSF3d0e2JA9q5jrTMOzknim1"
.text:004B5375                 test    al, al
.text:004B5377                 mov     [ebp+ebx+var_264], al    //base64 decode
...
.text:004B539E                 sub     eax, 12h                 //前18个字符
.text:004B53A1                 cmp     eax, 5Dh                 //后93个字符
.text:004B53A4                 ja      loc_4B55EC               //输入总长度不超过112
...
.text:004B53AA                 lea     ecx, [ebp+var_1E4]
.text:004B53B0                 mov     [ebp+var_298], 1
.text:004B53BA                 call    sub_4017A0               //初始化迷宫数据
.text:004B53BF                 lea     eax, [ebp+var_25B]
.text:004B53C5                 lea     ecx, [ebp+var_1E4]
.text:004B53CB                 mov     [esp+2C8h+var_2C4], eax
.text:004B53CF                 lea     eax, [ebp+var_264]
.text:004B53D5                 mov     [esp+2C8h+var_2C8], eax
.text:004B53D8                 call    sub_401BD0               //初始化几个大数,主要的是把输入的前18个字符拆分成两个大数x,y,还有一个固定的常数z
加密的迷宫初始数据,四个关卡,每关地图大小是6x5:
02 13 00 00 07 
07 04 05 0B 0A 
09 08 0E 0E 0C 
0C 12 13 11 01 
36 16 15 15 1B 
2B 19 18 1E 1C 

1E 1D 32 23 20 
20 27 26 24 24 
2B 3B 29 29 2F 
2F 2D 2C 33 32 
31 30 37 36 34 
34 2A 3B 39 3A 

3C 2F 1C 3C 43 
43 40 40 47 77 
44 44 4B 4A 49 
49 4F 4E 4D 4C 
53 43 50 50 56 
47 54 55 5B 58 

5A 58 5F 5E 6C 
4D 63 73 61 60 
66 66 64 65 6A 
6A 69 68 7E 6E 
6D 6C 72 72 71 
41 76 76 75 76
几个关键函数:
sub_401DE0 会被多处调用的函数,调试分析得知是个寻路判断函数,返回值表示两个点之间是可到达,同时也可看到迷宫数据解密算法,算法比较简单xor个密钥再xor个索引序号
先用初始迷宫密钥3解密出明文迷宫数据,方便后面描述:
02 13 00 00 07 
07 04 05 0B 0A 
09 08 0E 0E 0C 
0C 12 13 11 01 
36 16 15 15 1B 
2B 19 18 1E 1C 

1E 1D 32 23 20 
20 27 26 24 24 
2B 3B 29 29 2F 
2F 2D 2C 33 32 
31 30 37 36 34 
34 2A 3B 39 3A 

3C 2F 1C 3C 43 
43 40 40 47 77 
44 44 4B 4A 49 
49 4F 4E 4D 4C 
53 43 50 50 56 
47 54 55 5B 58 

5A 58 5F 5E 6C 
4D 63 73 61 60 
66 66 64 65 6A 
6A 69 68 7E 6E 
6D 6C 72 72 71 
41 76 76 75 76
几个关键函数:
sub_401DE0 会被多处调用的函数,调试分析得知是个寻路判断函数,返回值表示两个点之间是可到达,同时也可看到迷宫数据解密算法,算法比较简单xor个密钥再xor个索引序号
先用初始迷宫密钥3解密出明文迷宫数据,方便后面描述:
几个关键函数:
sub_401DE0 会被多处调用的函数,调试分析得知是个寻路判断函数,返回值表示两个点之间是可到达,同时也可看到迷宫数据解密算法,算法比较简单xor个密钥再xor个索引序号
先用初始迷宫密钥3解密出明文迷宫数据,方便后面描述:
01 11 01 00 00 
01 01 01 00 00 
00 00 01 00 01 
00 01 01 00 11 
21 00 00 01 00 
31 00 00 01 02 

03 01 11 01 01 
00 00 00 01 00 
00 11 00 01 00 
01 00 00 00 00 
00 00 00 00 01 
00 11 01 00 02 

03 11 21 00 00 
01 01 00 00 31 
01 00 00 00 00 
01 00 00 00 00 
00 11 01 00 01 
11 01 01 00 02 

03 00 00 00 31
11 00 11 00 00
01 00 01 01 01
00 00 00 11 00
00 00 01 00 00
31 01 00 00 02
从上面寻路判断函数中可以分析出:地图中的数值低4位是1表示该点可走,如果是0且下一层是1x表示空洞下面被垫高了也可同样可走

sub_402460 走到指定位置,如遇到道具会自动拾取,0x31道具可以改变密钥
01 11 01 00 00 
01 01 01 00 00 
00 00 01 00 01 
00 01 01 00 11 
21 00 00 01 00 
31 00 00 01 02 

03 01 11 01 01 
00 00 00 01 00 
00 11 00 01 00 
01 00 00 00 00 
00 00 00 00 01 
00 11 01 00 02 

03 11 21 00 00 
01 01 00 00 31 
01 00 00 00 00 
01 00 00 00 00 
00 11 01 00 01 
11 01 01 00 02 

03 00 00 00 31
11 00 11 00 00
01 00 01 01 01
00 00 00 11 00
00 00 01 00 00
31 01 00 00 02
从上面寻路判断函数中可以分析出:地图中的数值低4位是1表示该点可走,如果是0且下一层是1x表示空洞下面被垫高了也可同样可走

sub_402460 走到指定位置,如遇到道具会自动拾取,0x31道具可以改变密钥
从上面寻路判断函数中可以分析出:地图中的数值低4位是1表示该点可走,如果是0且下一层是1x表示空洞下面被垫高了也可同样可走

sub_402460 走到指定位置,如遇到道具会自动拾取,0x31道具可以改变密钥
sub_402460()
{
  ...
  if ( (v10 & 0xF) == 1 )
  {
    *((_DWORD *)v2 + 2) = x;
    *((_DWORD *)v2 + 3) = y;
    if ( (signed int)v10 >> 4 == 3 )                                    //0x31类型道具
    {
      v23[20] = v19 ^ (v22 + y) ^ ((v22 + y) ^ v9) & 0xF;
      v12 = *((_DWORD *)v2 + 0x65) == 1;
      *((_DWORD *)v2 + 4) = 3 * ((*((_DWORD *)v2 + 4) + 2) >> 1);       //w = (w+2)/2*3,w初始值是3,经过3次迭代会等于十进制的33
      if ( v12 && v19 == 3 )
      {
        v2[0x198] = 0x37;                                               //第一次拾取0x31道具,修改迷宫密钥为k = 0x37
        v13 = 0x37;
      }
      else
      {
        sub_401AB0(v2 + 0x110, v2 + 0x110, v2 + 0x8C);                  //大数乘法 a *= x
        sub_401AB0(v2 + 0x13C, v2 + 0x13C, v2 + 0xB8);                  //大数乘法 b *= y
        sub_401AB0(v2 + 0x168, v2 + 0x168, v2 + 0xE4);                  //大数乘法 c *= z
        sub_4019F0(v2 + 0x194, v2 + 0x110, v2 + 0x13C, v2 + 0x168);     //修改密钥 k = a - b - c
        v13 = v2[0x198];
      }
      //变更密钥后,需要对数据用新密钥重新加密
      v14 = v2 + 0x32;
      v15 = v2 + 0xAA;
      v16 = v13 ^ v19;
      do
      {
        v17 = v14 - 30;
        do
        {
          v18 = (int)(v17 + 5);
          do
            *v17++ ^= v16;
          while ( v17 != (_BYTE *)v18 );
        }
        while ( v17 != v14 );
        v14 += 30;
      }
      while ( v14 != v15 );
    }
  }
  return 0;
}
sub_4026A0 指定位置使用道具,从使用道具的函数里可以分析出:迷宫是逐个关卡从低到高立体层叠的,0x11道具可以从空洞掉落到下一层,下一层是空洞会继续掉落下去

sub_402400 判断是否可进入上一关,如果可到达,则会来到上一关的右下角坐标(5,4)

sub_402380 判断是否可进入下一关,如果可到达,则会来到下一关的左上角坐标(0,0)
.text:004023CE                 movzx   eax, byte ptr [ebx+198h]
.text:004023D5                 cmp     [ebx+10h], eax                   //检查最终密钥 if (k == w)
.text:004023D8                 jnz     short loc_4023F0
这个检查的含义是输入的前18个字符组成的大数需要特定的值

所有游戏的主体就用输入的key控制走路过程,从每层的左上角走到右下角进入下一关,直到第4关通关
单独看每一关的话,6x5的地图,似乎也并不复杂,就手动走着玩玩
因为高层的道具会掉落下去的原因,有时需要返回前面低级关卡,处理给适当的位置垫高的问题
开始也是拾取过第一关的道具,走到第三关后没路走不下去了

多次尝试后,发现拾取道具是个负担,无视道具反而容易看清路线,就想到了试试不拾取0x31道具能不能走通,
竟然真的走通了,路线步骤,如下:
01 12 13 06 3B 0B 0D 1E 06 17 3B 02 12 3B 01 10 1E 1E 10 06 3B 0D 0B 1E 06 10 17 0C 3B 0B 10 1E 10 1C 0C 17 3B 1A 12 1E 1C 11 3B 12 10 3B 19 17 15 17 3B 05 06 07 17 12 18 3B
每个步骤转成平面坐标表示是(v/5,v%5)
其中那些小于0x1E步骤都是两个一组,从一个位置拿到0x11类型的箱子,扔到另一个位置的0x00空洞里
0x1E是回到上一关,0x3B是进入下一关

迷宫虽然走通了,但是后面却有个crc判断:
sub_402460()
{
  ...
  if ( (v10 & 0xF) == 1 )
  {
    *((_DWORD *)v2 + 2) = x;
    *((_DWORD *)v2 + 3) = y;
    if ( (signed int)v10 >> 4 == 3 )                                    //0x31类型道具
    {
      v23[20] = v19 ^ (v22 + y) ^ ((v22 + y) ^ v9) & 0xF;
      v12 = *((_DWORD *)v2 + 0x65) == 1;
      *((_DWORD *)v2 + 4) = 3 * ((*((_DWORD *)v2 + 4) + 2) >> 1);       //w = (w+2)/2*3,w初始值是3,经过3次迭代会等于十进制的33
      if ( v12 && v19 == 3 )
      {
        v2[0x198] = 0x37;                                               //第一次拾取0x31道具,修改迷宫密钥为k = 0x37
        v13 = 0x37;
      }
      else
      {
        sub_401AB0(v2 + 0x110, v2 + 0x110, v2 + 0x8C);                  //大数乘法 a *= x
        sub_401AB0(v2 + 0x13C, v2 + 0x13C, v2 + 0xB8);                  //大数乘法 b *= y
        sub_401AB0(v2 + 0x168, v2 + 0x168, v2 + 0xE4);                  //大数乘法 c *= z
        sub_4019F0(v2 + 0x194, v2 + 0x110, v2 + 0x13C, v2 + 0x168);     //修改密钥 k = a - b - c
        v13 = v2[0x198];
      }
      //变更密钥后,需要对数据用新密钥重新加密
      v14 = v2 + 0x32;
      v15 = v2 + 0xAA;
      v16 = v13 ^ v19;
      do
      {
        v17 = v14 - 30;
        do
        {
          v18 = (int)(v17 + 5);
          do
            *v17++ ^= v16;
          while ( v17 != (_BYTE *)v18 );
        }
        while ( v17 != v14 );
        v14 += 30;
      }
      while ( v14 != v15 );
    }
  }
  return 0;
}
sub_4026A0 指定位置使用道具,从使用道具的函数里可以分析出:迷宫是逐个关卡从低到高立体层叠的,0x11道具可以从空洞掉落到下一层,下一层是空洞会继续掉落下去

sub_402400 判断是否可进入上一关,如果可到达,则会来到上一关的右下角坐标(5,4)

sub_402380 判断是否可进入下一关,如果可到达,则会来到下一关的左上角坐标(0,0)
.text:004023CE                 movzx   eax, byte ptr [ebx+198h]
.text:004023D5                 cmp     [ebx+10h], eax                   //检查最终密钥 if (k == w)
.text:004023D8                 jnz     short loc_4023F0
这个检查的含义是输入的前18个字符组成的大数需要特定的值

所有游戏的主体就用输入的key控制走路过程,从每层的左上角走到右下角进入下一关,直到第4关通关
单独看每一关的话,6x5的地图,似乎也并不复杂,就手动走着玩玩
因为高层的道具会掉落下去的原因,有时需要返回前面低级关卡,处理给适当的位置垫高的问题
开始也是拾取过第一关的道具,走到第三关后没路走不下去了

多次尝试后,发现拾取道具是个负担,无视道具反而容易看清路线,就想到了试试不拾取0x31道具能不能走通,
竟然真的走通了,路线步骤,如下:
01 12 13 06 3B 0B 0D 1E 06 17 3B 02 12 3B 01 10 1E 1E 10 06 3B 0D 0B 1E 06 10 17 0C 3B 0B 10 1E 10 1C 0C 17 3B 1A 12 1E 1C 11 3B 12 10 3B 19 17 15 17 3B 05 06 07 17 12 18 3B
每个步骤转成平面坐标表示是(v/5,v%5)
其中那些小于0x1E步骤都是两个一组,从一个位置拿到0x11类型的箱子,扔到另一个位置的0x00空洞里
0x1E是回到上一关,0x3B是进入下一关

迷宫虽然走通了,但是后面却有个crc判断:
sub_4026A0 指定位置使用道具,从使用道具的函数里可以分析出:迷宫是逐个关卡从低到高立体层叠的,0x11道具可以从空洞掉落到下一层,下一层是空洞会继续掉落下去

sub_402400 判断是否可进入上一关,如果可到达,则会来到上一关的右下角坐标(5,4)

sub_402380 判断是否可进入下一关,如果可到达,则会来到下一关的左上角坐标(0,0)
.text:004023CE                 movzx   eax, byte ptr [ebx+198h]
.text:004023D5                 cmp     [ebx+10h], eax                   //检查最终密钥 if (k == w)
.text:004023D8                 jnz     short loc_4023F0
这个检查的含义是输入的前18个字符组成的大数需要特定的值

所有游戏的主体就用输入的key控制走路过程,从每层的左上角走到右下角进入下一关,直到第4关通关
单独看每一关的话,6x5的地图,似乎也并不复杂,就手动走着玩玩
因为高层的道具会掉落下去的原因,有时需要返回前面低级关卡,处理给适当的位置垫高的问题
开始也是拾取过第一关的道具,走到第三关后没路走不下去了


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

最后于 2019-12-30 20:46 被ccfer编辑 ,原因:
收藏
免费 5
支持
分享
最新回复 (3)
雪    币: 23080
活跃值: (3432)
能力值: (RANK:648 )
在线值:
发帖
回帖
粉丝
2
感觉这道题的作者要女装一下才能补偿你呀
2019-12-30 18:17
0
雪    币: 11705
活跃值: (975)
能力值: ( LV12,RANK:779 )
在线值:
发帖
回帖
粉丝
3
很强大,膜拜
2019-12-30 23:02
0
雪    币: 6051
活跃值: (1441)
能力值: ( LV15,RANK:1473 )
在线值:
发帖
回帖
粉丝
4
对ccfer的膜拜有如涛涛江水
2019-12-31 13:47
0
游客
登录 | 注册 方可回帖
返回
//