首页
社区
课程
招聘
[原创]签到题 身在何处
2021-11-15 23:34 4222

[原创]签到题 身在何处

2021-11-15 23:34
4222

拿到题目先运行exe看一下,是通过Name找Serial的题型,且有公开的一组用户名及其对应的序列号,

打开IDA先对EXE进行加密思路分析,按扭check的逻辑如下函数

主要的加密逻辑是:

    1.判断用户名长度不为0;

    2.对用户名使用加密算法alg1进行加密,得到v2;

    3.检查序列号是否为'0'~'9'之间的字符构成;

    4.序列号长度小于等于10;

    5.将序列号里数字由10进制转成16进制数值v3;   如: '653259165'=>0x26EFF19D

    6.将v2^v3的结果的16进制数值,转成16进制字符串a2; 如:0x52A1ED5A=>  '52a1ed5a'

    7.对a2使用加密算法alg1进行加密,得到结果为0x13B88C77,则正确;


解题的关键是第6和第7步,

由于最后的结果是对(v2^v3)的结果D进行加密,且加密结果为固定值,其中D可以由已知的一组用户名及其对应的序列号得到,(先不考虑多解)

假设(题目要求的)用户名为 KCTF经过第2步加密后结果为v2',则可由异域特性可以算出v3'=D^v2',最后根据第5步通过v3'反推出正确的序列号。



--------------------------------------------------------------------------------------------------------------------

加密算法alg1的函数(分析完才发现,不看它也能推导出序列号)

int __cdecl sub_881260(char *a1_val, int a2_val_len)

{

  signed int v2; // 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_len; // edx

  unsigned int v12; // ecx

  char *v13; // esi

  char v14; // al

  int v16[256]; // [esp+0h] [ebp-404h]


  v2 = 0;

  do

  {

    v3 = (unsigned int)v2 >> 1;

    if ( v2 & 1 )

      v3 ^= 0xEDB88320;

    if ( v3 & 1 )

      v4 = (v3 >> 1) ^ 0xEDB88320;

    else

      v4 = v3 >> 1;

    if ( v4 & 1 )

      v5 = (v4 >> 1) ^ 0xEDB88320;

    else

      v5 = v4 >> 1;

    if ( v5 & 1 )

      v6 = (v5 >> 1) ^ 0xEDB88320;

    else

      v6 = v5 >> 1;

    if ( v6 & 1 )

      v7 = (v6 >> 1) ^ 0xEDB88320;

    else

      v7 = v6 >> 1;

    if ( v7 & 1 )

      v8 = (v7 >> 1) ^ 0xEDB88320;

    else

      v8 = v7 >> 1;

    if ( v8 & 1 )

      v9 = (v8 >> 1) ^ 0xEDB88320;

    else

      v9 = v8 >> 1;

    if ( v9 & 1 )

      v10 = (v9 >> 1) ^ 0xEDB88320;

    else

      v10 = v9 >> 1;

    v16[v2++] = v10;                            // 生成256的字典

  }

  while ( v2 < 256 );

  v11_len = a2_val_len;

  v12 = 0xFFFFFFFF;

  if ( a2_val_len )

  {

    v13 = a1_val;

    do

    {

      v14 = *v13++;                             // 遍历输入字符串的字符

      v12 = v16[(unsigned __int8)(v12 ^ v14)] ^ (v12 >> 8);// 取字典值与前一块(>>8)异域,字典值的下标为BYTE(v12 ^ v14)

      --v11_len;

    }

    while ( v11_len );                          // 输入字符串的长度

  }

  return ~v12;

}



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

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