首页
社区
课程
招聘
[原创] 看雪.安恒2020 KCTF春季赛 > 第二题 子鼠开天 WP
发表于: 2020-4-17 00:59 4042

[原创] 看雪.安恒2020 KCTF春季赛 > 第二题 子鼠开天 WP

2020-4-17 00:59
4042
本题是考密码学,用到了AES,RSA,SHA512,MD5,不过算法还是很简单的,只要RSA的大数分解能完成,就很容易做出来,分析如下:

IDA中F5,主函数:
int __cdecl main(int argc, const char **argv, const char **envp)
{
  time_t v3; // eax
  unsigned int v4; // kr04_4
  int result; // eax
  char v6; // [esp+8h] [ebp-12Ch]
  char v7; // [esp+9h] [ebp-12Bh]
  __int16 v8; // [esp+69h] [ebp-CBh]
  char v9; // [esp+6Bh] [ebp-C9h]
  char v10; // [esp+6Ch] [ebp-C8h]
  char v11; // [esp+6Dh] [ebp-C7h]
  __int16 v12; // [esp+131h] [ebp-3h]
  char v13; // [esp+133h] [ebp-1h]

  v6 = 0;
  v10 = 0;
  memset(&v7, 0, 0x60u);
  v8 = 0;
  v9 = 0;
  memset(&v11, 0, 0xC4u);
  v12 = 0;
  v13 = 0;
  v3 = time(0);
  sub_411AD8(v3);
  sub_411A90(aEnterYourName);
  scanf(aS, &v6);
  v4 = strlen(&v6) + 1;
  if ( v4 - 1 < 3 || v4 - 1 > 0x14 ) //名字长度判断
  {
    sub_411A90(aBadName);
    result = -1;
  }
  else
  {
    sub_411A90(aEnterYourSn);
    scanf(aS, &v10);
    if ( strlen(&v10) == 64 ) //SN长度判断
    {
      sub_401380((int)&v6, v4 - 1, (int)&v10, 64); //验证
      result = 0;
    }
    else
    {
      sub_411A90(aBadSn);
      result = -1;
    }
  }
  return result;
}
可以看出输入的名字长度可以在3-20这间,SN长度为64,验证函数是sub_401380:
void __cdecl sub_401380(char *name, unsigned int lenName, char *sSn, int lenSN)
{
  char v4; // [esp+4h] [ebp-70h]
  BYTE sn2[32]; // [esp+14h] [ebp-60h]
  BYTE sn[32]; // [esp+34h] [ebp-40h]
  BYTE sn1[32]; // [esp+54h] [ebp-20h]

  if ( lenName >= 3 && lenName <= 0x14 && lenSN == 64 )
  {
    if ( sub_401000(sSn, 64, (int)sn) != 32     // 16进制串sSn转BYTE sn[32]
      || (AESCode(sn, 32, (int)sn1, keyAES, 128, 0), RSACode((int)sn1, 32, (int)sn2), sn2[0])// sn2[0]要等于0
      || sn2[1] != 2                            // sn2[1]要等于2
      || sn2[15] )                              // sn2[15]要等于0,这儿sn2前16字节只判断了三个字节,另13个字节可以为任意,就出现了多解
    {
      sub_411A90(aBadSn);
    }
    else
    {
      hashCode(name, lenName, (int)&v4);        // 计算name的hash值
      if ( !memcmp(&v4, &sn2[16], 0x10u) )      // 比较sn2后16字节要等于name的hash
        sub_411A90(aCongratulation);            // 成功
    }
  }
}

AESCode是AES算法,通过一个函数,由参数bEncode来指定完成加密或解密
int __cdecl AESCode(BYTE *bufOut, int lenOut, BYTE *bufIn, BYTE *keyAES, int lenBit, BOOL bEncode)
{
  BYTE *v6; // esi
  int v7; // ebx
  char v9; // [esp+4h] [ebp-F4h]

  if ( bEncode == 1 )                           // 同一个函数完成加密解密,由bEncode判断是加密还是解密
    sub_404FE0(keyAES, lenBit, (unsigned int *)&v9);
  else
    sub_4053A0(keyAES, lenBit, (unsigned int *)&v9);
  if ( lenOut / 16 <= 0 )
    return lenOut;
  v6 = bufOut;
  v7 = lenOut / 16;
  do
  {
    sub_404FB0(v6, &v6[bufIn - bufOut], &v9, bEncode);
    v6 += 16;
    --v7;
  }
  while ( v7 );
  return lenOut;
}

RSACode对输入完成RSA解密,返回值高位在前
signed int __cdecl RSACode(BYTE *bufIn, int lenIn, BYTE *bufOut)
{
  _DWORD *N; // esi
  _DWORD *e; // edi
  _DWORD *m; // ebx
  _DWORD *c; // ebp
  signed int v8; // eax
  _DWORD *lpMem; // [esp+0h] [ebp-24h]
  BYTE bN[32]; // [esp+4h] [ebp-20h]
  BYTE *lenIna; // [esp+2Ch] [ebp+8h]

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

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