首页
社区
课程
招聘
[原创] 京东-看雪-2018 春季赛 第七题 密室逃脱
发表于: 2018-6-29 11:17 3092

[原创] 京东-看雪-2018 春季赛 第七题 密室逃脱

aqs 活跃值
5
2018-6-29 11:17
3092

拿到的是一个 win32 程序,跑一下看看

serial 是16byte 长度的字符串,根据题目描述,每个byte对应一个初始密钥
看一下程序逻辑

逻辑不复杂,前面output 一些信息,输入 序列号,然后进入main_logic 函数,main_logic 函数只有一层实现,下面分段看一下

首先会写入一个 16x16 的表
在内存中是这个样子的

这个表在后面会用到,主要是用来确定操作的index 的
先看一下后面的逻辑

首先根据输入的每个byte在一个 table 中找到对应的 index

后面对 变换之后的 index table 进行加密

代码被自己改的有点难看,大概逻辑是:

这么说有点模糊,调试一下,在 0x0401287 这里下个断点,ecx -0x10 就是 table 的位置

这里传入的是 abcdefghijklmnop , 可以看到 index 变换之后变成了 index 0-0xf
接下来在0x0401393, 也就是获取到下一个table 的一个byte回填的时候

找到 三个参数

可以发现是 0 1 2,结合前面的 16x16 的表来看 index 是符合的
但是顺序没搞清楚是怎么变换的,只有 16 个byte,调试看看就行,得到的每次 变换的 三个参数是 对应的 index 是

变换 之后将最后得到的密钥和 一个固定的串进行比较

如果一致就过,还会根据 变换得到的 19 个加密串中间的一个来生成一段字符串
到了这里,整理一下

一开始想到的是 有没有可能反向解密回去回去,但是发现用于变换的table 是 64x64x64 大小的,要变换回去感觉很难, 情况会有很多种
想了很久,后面发现,如果多加密几轮的话就有可能重新得到原来的输入
这就简单了,将 最后密钥多加密几轮,找到重新得到最后密钥的地方,就可以知道他是怎么来的了, 写了一个脚本测试了一下

多循环几次,grep 一下,可以看到重复了,找到重复位置的前19 个密钥,变换一下就可以得到 serial

运行结果

Only 'a'-'z','A'-'Z','0'-'9' accepted.
Only 16 chars accepted.
Serial:zzzzzzzzzzzzzzzz

serial error
int __cdecl main(int argc, const char **argv, const char **envp)
{
  printf("Only 'a'-'z','A'-'Z','0'-'9' accepted.\n");
  printf("Only 16 chars accepted.\n");
  printf("Serial:");
  scanf_s("%s", input_450B80, 17);
  main_logic_401050();
  system("PAUSE");
  return 0;
}
  helpset[0] = 0x10101;
  helpset[1] = 0;
  helpset[2] = 0;
  helpset[3] = 0;
  helpset[4] = 0x1000001;
  helpset[5] = 1;
  helpset[6] = 0;
  helpset[7] = 0;
  helpset[8] = 1;
  helpset[9] = 0x10100;
  helpset[10] = 0;
  helpset[11] = 0;
  helpset[12] = 0x100;
  helpset[13] = 0x1000100;
  helpset[14] = 0;
  helpset[15] = 0;
  helpset[16] = 0x100;
  helpset[17] = 0x10001;
  helpset[18] = 0;
  helpset[19] = 0;
  helpset[20] = 0x1010000;
  helpset[21] = 0;
  helpset[22] = 1;
  helpset[23] = 0;
  helpset[24] = 0x10000;
  helpset[25] = 1;
  helpset[26] = 256;
  helpset[27] = 0;
  helpset[28] = 0x1000000;
  helpset[29] = 0x1000000;
  helpset[30] = 0x10000;
  helpset[31] = 0;
  helpset[32] = 0;
  helpset[33] = 256;
  helpset[34] = 1;
  helpset[35] = 1;
  helpset[36] = 0;
  helpset[37] = 0x10000;
  helpset[38] = 0x1000000;
  helpset[39] = 256;
  helpset[40] = 0;
  helpset[41] = 0x1000000;
  helpset[42] = 0;
  helpset[43] = 257;
  helpset[44] = 0;
  helpset[45] = 0;
  helpset[46] = 16777472;
  helpset[47] = 0x10000;
  helpset[48] = 0;
  helpset[49] = 0;
  helpset[50] = 65537;
  helpset[51] = 0x10000;
  helpset[52] = 0;
  helpset[53] = 0;
  helpset[54] = 65792;
  helpset[55] = 0x1000000;
  helpset[56] = 0;
  helpset[57] = 0;
  helpset[58] = 0x1000000;
  helpset[59] = 16777217;
  helpset[60] = 0;
  helpset[61] = 0;
  helpset[62] = 0;
  helpset[63] = 16843008;
 do
  {                                             // 找到每个key 对应的 index
    for ( offset = 0; ; ++offset )
    {
      if ( offset >= 64 )
      {                                         
        printf("input error\n");
        system("PAUSE");
        exit(-1);
      }
      if ( serial_set_40DA68[offset] == (unsigned __int8)input_450B80[index] )
        break;
    }                                           // 找到每个byte 对应的 offset
    input_index[index++] = offset;             
  }
  while ( index < 16 );
abcdefghijklmnopqrstuvwxyz+-ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

最后于 2018-6-29 15:37 被aqs编辑 ,原因:
上传的附件:
收藏
免费 2
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//