首页
社区
课程
招聘
[原创] KCTF2024 第十题(孩子吃三吃麻了
发表于: 2024-9-4 17:56 3079

[原创] KCTF2024 第十题(孩子吃三吃麻了

2024-9-4 17:56
3079

程序text段内容都与flag无关,data段校验code被释放到RWX段后,修正跳转,执行校验:将输入作为3x3数组下标交换数组元素,和目标数组比较是否一致。

一致则在程序本体中打印解密的结果。

看一下程序入口,看起来没有反调试和异常处理,主体只有23k,非常小巧。

首先是在sub_13c0的字符串解密函数,用第三个参数循环xor第一个参数,一共用过三种XOR Key:

解密出的字符串多是API函数名和输入输出的提示,和flag没什么关系
程序主函数中开了两个线程(sub_930sub_6c0),一个线程读取结果,另一个线程检查flag,但直接看这两个处理函数好像也和flag没什么关系

main里还把3795字节长的数据拷贝到了输入的后面:
图片描述

进去P一下发现像是函数,但是IDA自动分析出的东西不太能看,人肉跟一下可以发现:

要求两个数组最后的(自定义哈希)一致
逻辑大概就是要通过输入x个两字节的坐标,第一位y第二位x,从(0,0)开始,将原始数组置换为目标数组,每次只能替换0和另一个通过输入指定的非零元素

那么我们这样移动:

输入就是011110202122

目标数组 | 原始数组
  123       013
  456       526
  780       478
目标数组 | 原始数组
  123       013
  456       526
  780       478
xcyberchief/CyberChef_v10.5.2.html#recipe=Find_/_Replace(%7B'option':'Simple%20string','string':'E8FFFFFFFFC0'%7D,'E80100000090',true,false,true,false)Find_/_Replace(%7B'option':'Simple%20string','string':'2A'%7D,'00',true,false,true,false)Find_/_Replace(%7B'option':'Regex','string':'83F.F.750D.%7B26%7D'%7D,'909090909090909090909090909090909090',true,false,true,false)From_Hex('Auto')
xcyberchief/CyberChef_v10.5.2.html#recipe=Find_/_Replace(%7B'option':'Simple%20string','string':'E8FFFFFFFFC0'%7D,'E80100000090',true,false,true,false)Find_/_Replace(%7B'option':'Simple%20string','string':'2A'%7D,'00',true,false,true,false)Find_/_Replace(%7B'option':'Regex','string':'83F.F.750D.%7B26%7D'%7D,'909090909090909090909090909090909090',true,false,true,false)From_Hex('Auto')
__int64 sub_A()
{
 ...
 
  v0 = 3751i64;
  v1 = (char *)(v23 + 34);
  do
  {
    v2 = *v1;
    if ( !*v1 )
      v2 = 0;
    *v1++ = v2;
    --v0;
  }
  while ( v0 );
  v26 = v27;
  v25 = v24;
  v3 = (__int64 (__fastcall *)(__int64, _QWORD))sub_5BF(-124919994);
  v28 = sub_5BF(-49588825);
  v30 = (__int64 (__fastcall *)(__int64, __int64, __int64 *, __int64))sub_5BF(37938943);
  v4 = (__int64 (__fastcall *)(__int64, int *))sub_5BF(1060402837);
  v29 = (__int64 (__fastcall *)(__int64, int *))sub_5BF(-1813961927);
  v5 = (void (__fastcall *)(__int64))sub_5BF(480663025);
  v6 = (void (*)(void))sub_5BF(55981281);
  v7 = 0i64;
  v21 = 568;
  v8 = 0;
  v9 = v3(2i64, 0i64);
  v10 = v9;
  if ( v9 == -1 )
    return 0xFFFFFFFFi64;
  v12 = v4(v9, &v21);
  v13 = (__int64 (__fastcall *)(__int64, _QWORD, _QWORD))v28;
  for ( i = v29; v12; v12 = i(v10, &v21) )
  {
    if ( (_DWORD)v22 == ((unsigned int (*)(void))v6)() )
    {
      v7 = v13(0x2000000i64, 0i64, (unsigned int)v22);
      if ( v7 )
      {
        v15 = 0i64;
        while ( v30(v7, v15, &v17, 48i64) )
        {
          v15 = v17 + v19;
          if ( (_DWORD)v20 == 4096 && (_DWORD)v18 == 64 )
          {
            v6();
            v8 = sub_68B(*(_DWORD *)v17);
            v16 = (_BYTE *)v17;
            if ( v8 )
            {
              if ( sub_6CB((_BYTE *)(v17 + 4)) )
              {
                *v16 = 105;
                v16[1] = 111;
                v16[2] = 32;
              }
              else
              {
                *v16 = 109;
                v16[1] = 106;
                v16[2] = 41;
              }
              v16[3] = 0;
              break;
            }
            *(_BYTE *)v17 = 109;
            v16[1] = 106;
            v16[2] = 41;
            v16[3] = 0;
          }
        }
        v13 = (__int64 (__fastcall *)(__int64, _QWORD, _QWORD))v28;
        i = v29;
      }
      if ( v8 )
        break;
    }
  }
  v5(v10);
  return ((__int64 (__fastcall *)(__int64))v5)(v7);
}
__int64 sub_A()
{
 ...
 
  v0 = 3751i64;
  v1 = (char *)(v23 + 34);
  do
  {
    v2 = *v1;
    if ( !*v1 )
      v2 = 0;
    *v1++ = v2;
    --v0;
  }
  while ( v0 );
  v26 = v27;
  v25 = v24;
  v3 = (__int64 (__fastcall *)(__int64, _QWORD))sub_5BF(-124919994);
  v28 = sub_5BF(-49588825);
  v30 = (__int64 (__fastcall *)(__int64, __int64, __int64 *, __int64))sub_5BF(37938943);
  v4 = (__int64 (__fastcall *)(__int64, int *))sub_5BF(1060402837);
  v29 = (__int64 (__fastcall *)(__int64, int *))sub_5BF(-1813961927);
  v5 = (void (__fastcall *)(__int64))sub_5BF(480663025);
  v6 = (void (*)(void))sub_5BF(55981281);
  v7 = 0i64;
  v21 = 568;
  v8 = 0;
  v9 = v3(2i64, 0i64);
  v10 = v9;
  if ( v9 == -1 )
    return 0xFFFFFFFFi64;
  v12 = v4(v9, &v21);
  v13 = (__int64 (__fastcall *)(__int64, _QWORD, _QWORD))v28;
  for ( i = v29; v12; v12 = i(v10, &v21) )
  {
    if ( (_DWORD)v22 == ((unsigned int (*)(void))v6)() )
    {
      v7 = v13(0x2000000i64, 0i64, (unsigned int)v22);
      if ( v7 )
      {
        v15 = 0i64;
        while ( v30(v7, v15, &v17, 48i64) )
        {
          v15 = v17 + v19;
          if ( (_DWORD)v20 == 4096 && (_DWORD)v18 == 64 )
          {
            v6();
            v8 = sub_68B(*(_DWORD *)v17);
            v16 = (_BYTE *)v17;
            if ( v8 )
            {
              if ( sub_6CB((_BYTE *)(v17 + 4)) )
              {
                *v16 = 105;
                v16[1] = 111;
                v16[2] = 32;
              }
              else
              {
                *v16 = 109;
                v16[1] = 106;
                v16[2] = 41;
              }
              v16[3] = 0;
              break;
            }
            *(_BYTE *)v17 = 109;
            v16[1] = 106;
            v16[2] = 41;
            v16[3] = 0;
          }
        }
        v13 = (__int64 (__fastcall *)(__int64, _QWORD, _QWORD))v28;
        i = v29;
      }
      if ( v8 )
        break;
    }
  }
  v5(v10);
  return ((__int64 (__fastcall *)(__int64))v5)(v7);
}
bool __fastcall sub_6CB(char *user_input)
{
  __int64 (__fastcall *malloc)(__int64); // rbx
  int sum_arr_08_b_after_swap; // edi
  __int64 v4; // rcx
  int v5; // edx
  unsigned int index_len_inp; // er12
  unsigned __int64 user_input_len; // rsi
  char *i; // rbx
  char *user_in_ptr1; // r14
  __int64 ri; // r14
  int *a180p1; // rbx
  int sum_180_d409d627fc; // er15
  __int64 ci; // rsi
  __int64 v14; // r15
  int *malloc_space_ptr; // rbx
  __int64 v16; // r14
  unsigned int cnt; // er15
  int *malloc_space_ptrr; // r13
  unsigned int *flag_in_ind1; // rsi
  char v20; // bl
  __int64 v21; // r14
  __int64 v22; // rbx
  unsigned int v23; // eax
  unsigned int v24; // ebx
  __int128 v25; // xmm1
  __int128 v26; // xmm0
  unsigned int raw_arr_shuffered_sum; // esi
  unsigned int *arr_shuffered_deep_cpy; // rbx
  int const_sum; // er14
  __int64 v30; // r12
  __int64 v31; // r15
  int *const_arr180_ptr; // rbx
  __int64 v33; // r12
  __int64 v34; // r15
  unsigned int v35; // ebx
  __int64 v36; // rsi
  unsigned int v37; // er14
  __int64 v38; // r15
  __int64 v39; // r12
  __int64 v40; // rbx
  __int64 v41; // r14
  char v42; // bl
  __int64 v43; // rbx
  __int128 v44; // xmm1
  __int64 v45; // rcx
  __int128 v46; // xmm0
  unsigned int v47; // er12
  bool v48; // zf
  unsigned int flag_len_x; // er15
  __int64 v50; // r14
  int *arr_08_b_after_swap; // rbx
  __int64 v52; // rsi
  unsigned int x; // [rsp+20h] [rbp-E0h]
  unsigned int v55; // [rsp+20h] [rbp-E0h]
  unsigned int flag_len; // [rsp+24h] [rbp-DCh]
  int *malloced_space_base; // [rsp+28h] [rbp-D8h]
  int const_sum_180_d409d627fc; // [rsp+30h] [rbp-D0h]
  int arr_shuffered[10]; // [rsp+38h] [rbp-C8h] BYREF
  __int64 v60; // [rsp+60h] [rbp-A0h]
  int v61; // [rsp+68h] [rbp-98h]
  __int64 v62; // [rsp+6Ch] [rbp-94h]
  int v63; // [rsp+74h] [rbp-8Ch]
  __int64 v64; // [rsp+78h] [rbp-88h]
  int v65; // [rsp+80h] [rbp-80h]
  int v66; // [rsp+84h] [rbp-7Ch]
  __int128 v67[2]; // [rsp+88h] [rbp-78h]
  unsigned int v68[4]; // [rsp+A8h] [rbp-58h]
  unsigned int v69[12]; // [rsp+B8h] [rbp-48h] BYREF
  int const_arr_180[9]; // [rsp+E8h] [rbp-18h] BYREF
  int flag_in[80]; // [rsp+110h] [rbp+10h] BYREF
  unsigned int v72; // [rsp+260h] [rbp+160h]
  unsigned int v73; // [rsp+268h] [rbp+168h]
  unsigned int should_eq_flag_len; // [rsp+270h] [rbp+170h]
  unsigned int y; // [rsp+278h] [rbp+178h]
  unsigned int v76; // [rsp+278h] [rbp+178h]
 
  malloc = (__int64 (__fastcall *)(__int64))sub_5BF(244391216);
  malloced_space_base = (int *)malloc(17418240i64);
  sum_arr_08_b_after_swap = 0;
  v4 = 0i64;
  v5 = 1;
  do
    const_arr_180[v4++] = v5++;
  while ( v4 < 8 );
  const_arr_180[8] = 0;
  arr_shuffered[0] = 0;
  arr_shuffered[1] = 1;
  arr_shuffered[2] = 3;
  arr_shuffered[3] = 5;
  arr_shuffered[4] = 2;
  arr_shuffered[5] = 6;
  arr_shuffered[6] = 4;
  arr_shuffered[7] = 7;
  arr_shuffered[8] = 8;
  index_len_inp = 0;
  flag_len = 0;
  user_input_len = 0i64;
  for ( i = user_input; *i; ++i )
    ++user_input_len;
  if ( (user_input_len & 1) == 0 )
  {
    if ( user_input_len )
    {
      user_in_ptr1 = user_input;
      while ( index_len_inp < 31 )
      {
        flag_in[2 * index_len_inp] = *user_in_ptr1 - 48;
        flag_in[2 * index_len_inp + 1] = user_in_ptr1[1] - 48;
        user_in_ptr1 += 2;
        flag_len = ++index_len_inp;
        if ( user_in_ptr1 - user_input >= user_input_len )
          goto LABEL_10;
      }
    }
    else
    {
LABEL_10:
      y = 0;
      x = 0;
      ri = 3i64;
      a180p1 = const_arr_180;
      sum_180_d409d627fc = 0;
      do
      {
        ci = 3i64;
        do
        {
          sum_180_d409d627fc = *a180p1++ + 31 * sum_180_d409d627fc;
          --ci;
        }
        while ( ci );
        const_sum_180_d409d627fc = sum_180_d409d627fc;
        --ri;
      }
      while ( ri );
      should_eq_flag_len = 0;
      malloced_space_base[9] = 0;
      *((_QWORD *)malloced_space_base + 5) = 0i64;
      v14 = 3i64;
      malloc_space_ptr = malloced_space_base;   // copy 0...8
      do
      {
        v16 = 3i64;
        do
        {
          *malloc_space_ptr = *(int *)((char *)malloc_space_ptr + (char *)arr_shuffered - (char *)malloced_space_base);
          ++malloc_space_ptr;
          --v16;
        }
        while ( v16 );
        --v14;
      }
      while ( v14 );
      v72 = 1;
      cnt = 0;
      malloc_space_ptrr = malloced_space_base;
      if ( index_len_inp )
      {
        flag_in_ind1 = (unsigned int *)&flag_in[1];
        while ( 1 )
        {
          v20 = 0;
          if ( *(flag_in_ind1 - 1) >= 3 || *flag_in_ind1 >= 3 )
            v20 = 1;
          v21 = x + 3i64 * y;
          if ( arr_shuffered[v21] )
            v20 = 1;
          if ( v20 )
            break;
          v22 = *flag_in_ind1 + 3i64 * *(flag_in_ind1 - 1);// 第二位+第一位*3
                                                // 作为下标交换
          arr_shuffered[v21] = arr_shuffered[v22];
          arr_shuffered[v22] = 0;
          y = *(flag_in_ind1 - 1);
          v23 = *flag_in_ind1;
          ++cnt;
          flag_in_ind1 += 2;
          x = v23;
          if ( cnt >= index_len_inp )
            goto LABEL_27;
        }
      }
      else
      {
LABEL_27:
        v24 = 0;
        while ( 1 )
        {
          v25 = *(_OWORD *)&malloc_space_ptrr[12 * v24 + 4];
          *(_OWORD *)v69 = *(_OWORD *)&malloc_space_ptrr[12 * v24];
          v26 = *(_OWORD *)&malloc_space_ptrr[12 * v24 + 8];
          *(_OWORD *)&v69[4] = v25;
          *(_OWORD *)&v69[8] = v26;
          v73 = v24 + 1;
          raw_arr_shuffered_sum = 0;
          arr_shuffered_deep_cpy = v69;
          const_sum = 0;
          v30 = 3i64;
          do
          {
            v31 = 3i64;
            do
            {
              raw_arr_shuffered_sum = *arr_shuffered_deep_cpy++ + 31 * raw_arr_shuffered_sum;
              --v31;
            }
            while ( v31 );
            --v30;
          }
          while ( v30 );
          const_arr180_ptr = const_arr_180;
          v33 = 3i64;
          do
          {
            v34 = 3i64;
            do
            {
              const_sum = *const_arr180_ptr++ + 31 * const_sum;
              --v34;
            }
            while ( v34 );
            --v33;
          }
          while ( v33 );
          if ( const_sum == raw_arr_shuffered_sum )
            break;
          v63 = 0;
          v61 = -1;
          v62 = 1i64;
          v64 = 0i64;
          v65 = -1;
          v66 = 1;
          v35 = v69[9];
          v36 = 0i64;
          v37 = v69[10];
          v60 = 4i64;
          v38 = v69[10] + 3i64 * v69[9];
          do
          {
            v55 = v35 + *(int *)((char *)&v61 + v36);
            v39 = 3i64;
            v40 = 0i64;
            v76 = v37 + *(_DWORD *)((char *)&v64 + v36);
            do
            {
              v41 = 3i64;
              do
              {
                *(_DWORD *)((char *)v67 + v40 * 4) = v69[v40];
                ++v40;
                --v41;
              }
              while ( v41 );
              --v39;
            }
            while ( v39 );
            v42 = 0;
            malloc_space_ptrr = malloced_space_base;
            if ( v55 >= 3 || v76 >= 3 )
              v42 = 1;
            if ( *((_DWORD *)v67 + v38) )
              v42 = 1;
            if ( v42 )
            {
              v47 = v72;
            }
            else
            {
              v43 = v76 + 3i64 * v55;
              *((_DWORD *)v67 + v38) = *((_DWORD *)v67 + v43);
              *((_DWORD *)v67 + v43) = 0;
              *(_QWORD *)&v68[1] = __PAIR64__(v76, v55);
              v68[3] = v69[11] + 1;
              v44 = v67[1];
              v45 = 6i64 * v72;
              *(_OWORD *)&malloced_space_base[2 * v45] = v67[0];
              v46 = *(_OWORD *)v68;
              *(_OWORD *)&malloced_space_base[2 * v45 + 4] = v44;
              *(_OWORD *)&malloced_space_base[2 * v45 + 8] = v46;
              v47 = ++v72;
            }
            v35 = v69[9];
            v36 += 4i64;
            v48 = v60-- == 1;
            v37 = v69[10];
          }
          while ( !v48 );
          v24 = v73;
          if ( v73 >= v47 )
          {
            flag_len_x = 0;
            goto LABEL_54;
          }
        }
        flag_len_x = v69[11];
        should_eq_flag_len = v69[11];
LABEL_54:
        if ( flag_len_x != -1 )
        {
          v50 = 3i64;
          arr_08_b_after_swap = arr_shuffered;
          do
          {
            v52 = 3i64;
            do
            {
              sum_arr_08_b_after_swap = *arr_08_b_after_swap++ + 31 * sum_arr_08_b_after_swap;
              --v52;
            }
            while ( v52 );
            --v50;
          }
          while ( v50 );
          if ( flag_len == should_eq_flag_len )
            return sum_arr_08_b_after_swap == const_sum_180_d409d627fc;
        }
      }
    }
  }
  return 0;
}
bool __fastcall sub_6CB(char *user_input)
{
  __int64 (__fastcall *malloc)(__int64); // rbx
  int sum_arr_08_b_after_swap; // edi
  __int64 v4; // rcx
  int v5; // edx
  unsigned int index_len_inp; // er12
  unsigned __int64 user_input_len; // rsi
  char *i; // rbx
  char *user_in_ptr1; // r14
  __int64 ri; // r14
  int *a180p1; // rbx
  int sum_180_d409d627fc; // er15
  __int64 ci; // rsi
  __int64 v14; // r15
  int *malloc_space_ptr; // rbx
  __int64 v16; // r14
  unsigned int cnt; // er15
  int *malloc_space_ptrr; // r13
  unsigned int *flag_in_ind1; // rsi
  char v20; // bl
  __int64 v21; // r14
  __int64 v22; // rbx
  unsigned int v23; // eax
  unsigned int v24; // ebx
  __int128 v25; // xmm1
  __int128 v26; // xmm0
  unsigned int raw_arr_shuffered_sum; // esi
  unsigned int *arr_shuffered_deep_cpy; // rbx
  int const_sum; // er14
  __int64 v30; // r12
  __int64 v31; // r15
  int *const_arr180_ptr; // rbx
  __int64 v33; // r12
  __int64 v34; // r15
  unsigned int v35; // ebx
  __int64 v36; // rsi
  unsigned int v37; // er14
  __int64 v38; // r15
  __int64 v39; // r12
  __int64 v40; // rbx
  __int64 v41; // r14
  char v42; // bl
  __int64 v43; // rbx
  __int128 v44; // xmm1
  __int64 v45; // rcx
  __int128 v46; // xmm0
  unsigned int v47; // er12
  bool v48; // zf
  unsigned int flag_len_x; // er15
  __int64 v50; // r14
  int *arr_08_b_after_swap; // rbx
  __int64 v52; // rsi
  unsigned int x; // [rsp+20h] [rbp-E0h]
  unsigned int v55; // [rsp+20h] [rbp-E0h]
  unsigned int flag_len; // [rsp+24h] [rbp-DCh]
  int *malloced_space_base; // [rsp+28h] [rbp-D8h]
  int const_sum_180_d409d627fc; // [rsp+30h] [rbp-D0h]
  int arr_shuffered[10]; // [rsp+38h] [rbp-C8h] BYREF
  __int64 v60; // [rsp+60h] [rbp-A0h]
  int v61; // [rsp+68h] [rbp-98h]
  __int64 v62; // [rsp+6Ch] [rbp-94h]
  int v63; // [rsp+74h] [rbp-8Ch]
  __int64 v64; // [rsp+78h] [rbp-88h]
  int v65; // [rsp+80h] [rbp-80h]
  int v66; // [rsp+84h] [rbp-7Ch]
  __int128 v67[2]; // [rsp+88h] [rbp-78h]
  unsigned int v68[4]; // [rsp+A8h] [rbp-58h]
  unsigned int v69[12]; // [rsp+B8h] [rbp-48h] BYREF
  int const_arr_180[9]; // [rsp+E8h] [rbp-18h] BYREF
  int flag_in[80]; // [rsp+110h] [rbp+10h] BYREF
  unsigned int v72; // [rsp+260h] [rbp+160h]
  unsigned int v73; // [rsp+268h] [rbp+168h]
  unsigned int should_eq_flag_len; // [rsp+270h] [rbp+170h]
  unsigned int y; // [rsp+278h] [rbp+178h]
  unsigned int v76; // [rsp+278h] [rbp+178h]
 
  malloc = (__int64 (__fastcall *)(__int64))sub_5BF(244391216);
  malloced_space_base = (int *)malloc(17418240i64);
  sum_arr_08_b_after_swap = 0;
  v4 = 0i64;
  v5 = 1;
  do
    const_arr_180[v4++] = v5++;
  while ( v4 < 8 );
  const_arr_180[8] = 0;
  arr_shuffered[0] = 0;
  arr_shuffered[1] = 1;
  arr_shuffered[2] = 3;
  arr_shuffered[3] = 5;
  arr_shuffered[4] = 2;
  arr_shuffered[5] = 6;
  arr_shuffered[6] = 4;
  arr_shuffered[7] = 7;
  arr_shuffered[8] = 8;
  index_len_inp = 0;
  flag_len = 0;
  user_input_len = 0i64;
  for ( i = user_input; *i; ++i )
    ++user_input_len;
  if ( (user_input_len & 1) == 0 )
  {
    if ( user_input_len )
    {
      user_in_ptr1 = user_input;
      while ( index_len_inp < 31 )
      {
        flag_in[2 * index_len_inp] = *user_in_ptr1 - 48;
        flag_in[2 * index_len_inp + 1] = user_in_ptr1[1] - 48;
        user_in_ptr1 += 2;
        flag_len = ++index_len_inp;
        if ( user_in_ptr1 - user_input >= user_input_len )
          goto LABEL_10;
      }
    }
    else
    {
LABEL_10:
      y = 0;
      x = 0;
      ri = 3i64;
      a180p1 = const_arr_180;
      sum_180_d409d627fc = 0;
      do
      {
        ci = 3i64;
        do
        {
          sum_180_d409d627fc = *a180p1++ + 31 * sum_180_d409d627fc;
          --ci;
        }
        while ( ci );
        const_sum_180_d409d627fc = sum_180_d409d627fc;
        --ri;
      }
      while ( ri );

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

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