首页
社区
课程
招聘
[原创]kctf 2021 第四题
发表于: 2021-5-15 01:30 6230

[原创]kctf 2021 第四题

2021-5-15 01:30
6230

大概算法:

trans_input把输入转换为数字,然后验证数独,数独比较简单,直接就能解出来:

图片描述

但是前面那个转换输入的函数我疑惑了好久,首先转换的规则是将输入查一个81大小的table,然后把查到的索引%9+1作为填入数独的数字,但是这样一来一个数字对应的输入就有9种可能,那56个数字就有9^56种可能,最后还会多9个字符,那可能性可就太多了,感觉有限时间内爆破不完。

知道后来,我又仔细审了一下tran_input函数,发现末尾有点奇怪的逻辑:
图片描述
当输入是数字时会有一个判断,而每次判断就会把查表的起始索引+9,我突然想到会不会是每一行数字填完之后要输入一个数字把索引+9,而对于的输入就只在起始索引+9的范围内查找,而多的9个数字又正好把多的9个输入覆盖了。试了一下,果然如此:

一开始还以为是爆破题,没想到最后是脑洞题,学到了很多,谢谢出题人。

int __cdecl main(int argc, const char **argv, const char **envp)
{
  int v3; // kr00_4
  int v4; // ecx
  char *v5; // esi
  int v6; // edi
  void (*v8)(void); // [esp+Ch] [ebp-2CCh]
  int v9[22]; // [esp+10h] [ebp-2C8h] BYREF
  int v10[128]; // [esp+68h] [ebp-270h] BYREF
  __int128 v11; // [esp+268h] [ebp-70h] BYREF
  char flag[92]; // [esp+278h] [ebp-60h] BYREF
 
  printf("\t\t\t看雪CTF大赛\r\n");
  printf("\t\t祝愿看雪CTF大赛越办越好\r\n");
  printf("Serial: ");
  scanf_s("%s", flag);
  v3 = strlen(flag);
  if ( v3 <= 64 && trans_input(v3, flag, v10) == 1 && check_sudoku((int)v10, v3 - 9) == 1 )// 数独
  {
    v11 = 0i64;
    memset(v9, 0, sizeof(v9));
    v9[5] = 0;
    v9[4] = 0;
    v9[0] = 0x67452301;                         // md5_init
    v9[1] = 0xEFCDAB89;
    v9[2] = 0x98BADCFE;
    v9[3] = 0x10325476;
    mde_update((int)flag, (int)v9, v3);
    md5_final((int)&v11, (int)v9);
    aes_init(v4, (unsigned __int8 *)&v11);
    v8 = (void (*)(void))VirtualAlloc(0, 0x620u, 0x1000u, 0x40u);
    v5 = (char *)v8;
    v6 = 'b';
    do
    {
      *(__m128i *)v5 = _mm_loadu_si128((const __m128i *)&v5[&byte_4181A0 - (_UNKNOWN *)v8]);
      aes_dec((int)v10, v5);
      v5 += 16;
      --v6;
    }
    while ( v6 );
    v8();
  }
  return 0;
}
int __cdecl main(int argc, const char **argv, const char **envp)
{
  int v3; // kr00_4
  int v4; // ecx
  char *v5; // esi
  int v6; // edi
  void (*v8)(void); // [esp+Ch] [ebp-2CCh]
  int v9[22]; // [esp+10h] [ebp-2C8h] BYREF
  int v10[128]; // [esp+68h] [ebp-270h] BYREF
  __int128 v11; // [esp+268h] [ebp-70h] BYREF
  char flag[92]; // [esp+278h] [ebp-60h] BYREF
 
  printf("\t\t\t看雪CTF大赛\r\n");
  printf("\t\t祝愿看雪CTF大赛越办越好\r\n");
  printf("Serial: ");
  scanf_s("%s", flag);
  v3 = strlen(flag);
  if ( v3 <= 64 && trans_input(v3, flag, v10) == 1 && check_sudoku((int)v10, v3 - 9) == 1 )// 数独
  {
    v11 = 0i64;
    memset(v9, 0, sizeof(v9));
    v9[5] = 0;
    v9[4] = 0;
    v9[0] = 0x67452301;                         // md5_init
    v9[1] = 0xEFCDAB89;
    v9[2] = 0x98BADCFE;
    v9[3] = 0x10325476;
    mde_update((int)flag, (int)v9, v3);
    md5_final((int)&v11, (int)v9);
    aes_init(v4, (unsigned __int8 *)&v11);
    v8 = (void (*)(void))VirtualAlloc(0, 0x620u, 0x1000u, 0x40u);
    v5 = (char *)v8;
    v6 = 'b';
    do
    {

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

收藏
免费 1
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//