首页
社区
课程
招聘
[原创]KCTF2022春季赛第三题 解题过程
发表于: 2022-5-16 00:33 7636

[原创]KCTF2022春季赛第三题 解题过程

2022-5-16 00:33
7636

题目流程比较简洁,初步判断该exe定义了一个大的结构体进行操作,简单根据偏移量进行了结构体判断。

重新对main进行解析,比较友好了。

存在较多的反调试。

流程较为清晰:
1、keys = MD5(Enj0y_1t_4_fuuuN)
2、AES(keys , 16bytes , plain , cipher , 32bytes) == byte_40B200[0:20]

直接进行解密计算发现是乱码,判断算法进行了改变。

直接使用题目中的MD5(Enj0y_1t_4_fuuuN),反正不会改变,看了别人的帖子才注意到这里修改了MD5的常数值。

整个AES算法结构比较标准,在正常的128bit密钥流程中增加了对16字节输入输出的转置操作。

需要找一份类似的代码实现。

密钥扩展函数正常。

字节替换函数中,查表方式没变,但是查看交叉引用时,发现sub_402330函数对其进行了修改。

原S盒中的:SBox[0x71] = 0xa3、SBox[0xa3]=0x0a,
这里修改为了:SBox[0x71] = 0x0a、SBox[0xa3]=0xa3

因此解密inv_sub_bytes的时候,RBox也应该进行相应的修改:
原本RBox[0xA3] = 0x71、RBox[0x0A] = 0xA3
修改为:RBox[0xA3] = 0xA3、RBox[0x0A] = 0x71

反编译时提示401bef无法转换,直接nop掉反调试的指令。

该题目对行变换函数进行了修改。直接分析16字节输入,魔改的变换如下:
0 1 2 3 -> 0 1 2 3
4 5 6 7 -> 7 4 5 6
8 9 10 11 -> 10 11 8 9
12 13 14 15 -> 13 14 15 12

在进行inv_shift_rows直接对如上变换方式进行逆变换即可。

列混淆函数中,计算时取的是state矩阵的转置,在编写Inv_MixColumn时也在取计算结果时,取state矩阵的转置。

加轮密钥中,也对要异或的16字节密钥进行了转置操作ExtendKey[i][j] = u32Extendkey[j] >> (8 * (3 - i))。解密时直接调用该函数即可。

根据对AES加密函数相应的修改,编写对应的解密函数。直接对byte_40B200开始的32字节进行解密,发现不对,直接获取内存值发现有修改,查看交叉引用,发现sub_4023D0对校验值进行修改。求解得到flag。

struct context{
    int iterator1;   //0
    int unknow1;     //1
    unsigned int md5[5];       //2-6
    int unknow7;    //7
    int unknow8;    //8
    byte keys[16];  //9-12
    int unknow13;    //13
    int unknow14;    //14
    int unknow15;    //15
    int iterator2;   //16
    int unknow17;    //17
    unsigned int cipher[10];      //18-27
    int unknow28;    //28
    int unknow29;    //29
    char sn[4000];
    int a3;
    int a4;
};
struct context{
    int iterator1;   //0
    int unknow1;     //1
    unsigned int md5[5];       //2-6
    int unknow7;    //7
    int unknow8;    //8
    byte keys[16];  //9-12
    int unknow13;    //13
    int unknow14;    //14
    int unknow15;    //15
    int iterator2;   //16
    int unknow17;    //17
    unsigned int cipher[10];      //18-27
    int unknow28;    //28
    int unknow29;    //29
    char sn[4000];
    int a3;
    int a4;
};
int __cdecl main_0(int argc, const char **argv, const char **envp)
{
  void *v3; // esp
  int result; // eax
  char v7; // [esp-10h] [ebp-1048h]
  context ctx; // [esp+0h] [ebp-1038h] BYREF
  CPPEH_RECORD ms_exc; // [esp+1020h] [ebp-18h]
 
  v3 = alloca(4128);
  memset(&ctx, 0xCCu, sizeof(ctx));
 
  ms_exc.registration.ScopeTable = (ms_exc.registration.ScopeTable ^ __security_cookie);
 
  memset(ctx.sn, 0, sizeof(ctx.sn));
 
  ctx.cipher[0] = 0;
  ctx.cipher[1] = 0;
  ctx.cipher[2] = 0;
  ctx.cipher[3] = 0;
  ctx.cipher[4] = 0;
  ctx.cipher[5] = 0;
  ctx.cipher[6] = 0;
  ctx.cipher[7] = 0;
  ctx.cipher[8] = 0;
  ctx.cipher[9] = 0;
 
  gets_s(ctx.sn, 4000u);
 
  if ( strlen(ctx.sn) == 32 )
  {
    for ( ctx.iterator2 = 0; ctx.iterator2 < 512; ++ctx.iterator2 )
    {
      ctx.unknow15 = 0;
      MEMORY[0] = ctx.iterator2;
      ms_exc.registration.TryLevel = 0xFFFFFFFE;
    }
 
    strcpy(ctx.keys, "Enj0y_1t_4_fuuuN");       // 16bytes
    _DX = 0x5F00;
    *(&ctx.unknow13 + 1) = 0;
    HIBYTE(ctx.unknow13) = 0;
 
    ctx.md5[0] = 0;
    ctx.md5[1] = 0;
    ctx.md5[2] = 0;
    ctx.md5[3] = 0;
    ctx.md5[4] = 0;
 
    for ( ctx.iterator1 = 0; ctx.iterator1 < 512; ++ctx.iterator1 )
    {
      __asm { insb }
      ms_exc.registration.TryLevel = -2;
      _DX = LOWORD(ctx.iterator1) + 1;
    }
 
    j_MD5_402DB0(ctx.keys, 0x10u, ctx.md5);
 
    j_aes_402070(ctx.md5, 0x10u, ctx.sn, ctx.cipher, 32);
 
    if ( !memcmp(ctx.cipher, byte_40B200, 0x20u) )
      printf_401037("OK\n", v7);
    else
      printf_401037("NO\n", v7);
    result = 0;
  }
  else
  {
    printf_401037("NO\n", v7);
    result = 0;
  }
  return result;
}
int __cdecl main_0(int argc, const char **argv, const char **envp)
{
  void *v3; // esp
  int result; // eax
  char v7; // [esp-10h] [ebp-1048h]
  context ctx; // [esp+0h] [ebp-1038h] BYREF
  CPPEH_RECORD ms_exc; // [esp+1020h] [ebp-18h]
 
  v3 = alloca(4128);
  memset(&ctx, 0xCCu, sizeof(ctx));
 
  ms_exc.registration.ScopeTable = (ms_exc.registration.ScopeTable ^ __security_cookie);
 
  memset(ctx.sn, 0, sizeof(ctx.sn));
 
  ctx.cipher[0] = 0;
  ctx.cipher[1] = 0;
  ctx.cipher[2] = 0;
  ctx.cipher[3] = 0;
  ctx.cipher[4] = 0;
  ctx.cipher[5] = 0;
  ctx.cipher[6] = 0;
  ctx.cipher[7] = 0;
  ctx.cipher[8] = 0;
  ctx.cipher[9] = 0;
 
  gets_s(ctx.sn, 4000u);
 
  if ( strlen(ctx.sn) == 32 )
  {
    for ( ctx.iterator2 = 0; ctx.iterator2 < 512; ++ctx.iterator2 )
    {
      ctx.unknow15 = 0;
      MEMORY[0] = ctx.iterator2;
      ms_exc.registration.TryLevel = 0xFFFFFFFE;
    }
 
    strcpy(ctx.keys, "Enj0y_1t_4_fuuuN");       // 16bytes
    _DX = 0x5F00;
    *(&ctx.unknow13 + 1) = 0;
    HIBYTE(ctx.unknow13) = 0;
 
    ctx.md5[0] = 0;
    ctx.md5[1] = 0;
    ctx.md5[2] = 0;
    ctx.md5[3] = 0;
    ctx.md5[4] = 0;
 
    for ( ctx.iterator1 = 0; ctx.iterator1 < 512; ++ctx.iterator1 )
    {
      __asm { insb }
      ms_exc.registration.TryLevel = -2;
      _DX = LOWORD(ctx.iterator1) + 1;
    }
 
    j_MD5_402DB0(ctx.keys, 0x10u, ctx.md5);
 
    j_aes_402070(ctx.md5, 0x10u, ctx.sn, ctx.cipher, 32);
 
    if ( !memcmp(ctx.cipher, byte_40B200, 0x20u) )
      printf_401037("OK\n", v7);
    else
      printf_401037("NO\n", v7);
    result = 0;
  }
  else
  {
    printf_401037("NO\n", v7);
    result = 0;
  }
  return result;
}
 
 
int sub_402C60()
{
  MD5_Constants_40B298[42] = 0xD4AF3085;
  return 1;
}
int sub_402C60()
{
  MD5_Constants_40B298[42] = 0xD4AF3085;
  return 1;
}
 
int __cdecl aes_402070(void *Src, size_t KeySize, unsigned __int8 input[], unsigned __int8 uccipher[], int iLen)
{
  int j; // [esp+4h] [ebp-1C8h]
  unsigned int i; // [esp+8h] [ebp-1C4h]
  int state[6]; // [esp+10h] [ebp-1BCh] BYREF
  int key[11]; // [esp+28h] [ebp-1A4h] BYREF
  unsigned int *iKeyOffset; // [esp+54h] [ebp-178h]
  unsigned __int8 *__attribute__((__org_arrdim(0,0))) output; // [esp+58h] [ebp-174h]
  unsigned int KeyExtend[90]; // [esp+60h] [ebp-16Ch] BYREF
 
  output = uccipher;
  iKeyOffset = KeyExtend;
  key[6] = 0;
  key[7] = 0;
  key[8] = 0;
  key[9] = 0;
  key[0] = 0;
  key[1] = 0;
  key[2] = 0;
  key[3] = 0;
  state[0] = 0;
  state[1] = 0;
  state[2] = 0;
  state[3] = 0;
 
  if ( !Src || !input || !uccipher )
    return -1;
  if ( KeySize > 0x10 )
    return -1;
  if ( iLen % 0x10u )
    return -1;
 
  memcpy(key, Src, KeySize);
 
  KeyExtend_4010BE(key, 16, KeyExtend);
 
  for ( i = 0; i < iLen; i += 16 )
  {
    input_transpose_401145(state, input);
    AddRoundKey_401186(state, iKeyOffset);
 
    for ( j = 1; j < 10; ++j )
    {
      iKeyOffset += 4;
      ByteSub_401172(state);
      ShiftRow_40122B(state);
      MixColumn_40100F(state);
      AddRoundKey_401186(state, iKeyOffset);
    }
    ByteSub_401172(state);
    ShiftRow_40122B(state);
    AddRoundKey_401186(state, iKeyOffset + 4);
 
    output_transpose_40125D(state, output);
 
    output += 16;
    input += 16;
    iKeyOffset = KeyExtend;
  }
  return 0;
}
int __cdecl aes_402070(void *Src, size_t KeySize, unsigned __int8 input[], unsigned __int8 uccipher[], int iLen)
{
  int j; // [esp+4h] [ebp-1C8h]
  unsigned int i; // [esp+8h] [ebp-1C4h]
  int state[6]; // [esp+10h] [ebp-1BCh] BYREF
  int key[11]; // [esp+28h] [ebp-1A4h] BYREF
  unsigned int *iKeyOffset; // [esp+54h] [ebp-178h]
  unsigned __int8 *__attribute__((__org_arrdim(0,0))) output; // [esp+58h] [ebp-174h]
  unsigned int KeyExtend[90]; // [esp+60h] [ebp-16Ch] BYREF
 
  output = uccipher;
  iKeyOffset = KeyExtend;
  key[6] = 0;
  key[7] = 0;
  key[8] = 0;
  key[9] = 0;
  key[0] = 0;
  key[1] = 0;
  key[2] = 0;
  key[3] = 0;
  state[0] = 0;
  state[1] = 0;
  state[2] = 0;
  state[3] = 0;
 
  if ( !Src || !input || !uccipher )
    return -1;
  if ( KeySize > 0x10 )
    return -1;
  if ( iLen % 0x10u )
    return -1;
 
  memcpy(key, Src, KeySize);
 
  KeyExtend_4010BE(key, 16, KeyExtend);
 
  for ( i = 0; i < iLen; i += 16 )
  {
    input_transpose_401145(state, input);
    AddRoundKey_401186(state, iKeyOffset);
 
    for ( j = 1; j < 10; ++j )
    {
      iKeyOffset += 4;
      ByteSub_401172(state);
      ShiftRow_40122B(state);

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

最后于 2022-5-16 20:50 被kanxue编辑 ,原因:
收藏
免费 2
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//