BUUCTF-RE

ぐ巨炮叔叔 提交于 2019-11-28 16:27:34

crackMe

首先依据你的用户名创建一个xor表,然后用这个表和密码经过异或计算,得到一个长度为8的checksum(unsigned char checksum[8]),最后检查checksum是否满足一些条件。满足则通过注册,不满足不通过。checksum进入check2进行验证,最终得到check_num == 43924则成功。

分析check2:

_DWORD *__usercall check2@<eax>(int a1@<ebx>, _BYTE *key, _DWORD *a3)
{
  int v3; // ST28_4
  int v4; // ecx
  int v6; // edx
  int v8; // ST20_4
  int v9; // eax
  int v10; // edi
  int v11; // ST1C_4
  int v12; // edx
  char v13; // di
  int v14; // ST18_4
  int v15; // eax
  int v16; // ST14_4
  int v17; // edx
  char v18; // al
  int v19; // ST10_4
  int v20; // ecx
  int v23; // ST0C_4
  int v24; // eax
  _DWORD *result; // eax
  int v26; // edx

  if ( *key == 100 )
  {
    *a3 |= 4u;
    v4 = *a3;
  }
  else
  {
    *a3 ^= 3u;
  }
  v3 = *a3;
  if ( key[1] == 98 )
  {
    _EAX = a3;
    *a3 |= 0x14u;
    v6 = *a3;
  }
  else
  {
    *a3 &= 0x61u;
    _EAX = (_DWORD *)*a3;
  }
  __asm { aam }
  if ( key[2] == 97 )
  {
    *a3 |= 0x84u;
    v9 = *a3;
  }
  else
  {
    *a3 &= 0xAu;
  }
  v8 = *a3;
  v10 = ~(a1 >> -91);
  if ( key[3] == 112 )
  {
    *a3 |= 0x114u;
    v12 = *a3;
  }
  else
  {
    *a3 >>= 7;
  }
  v11 = *a3;
  v13 = v10 - 1;
  if ( key[4] == 112 )
  {
    *a3 |= 0x380u;
    v15 = *a3;
  }
  else
  {
    *a3 *= 2;
  }
  v14 = *a3;
  if ( *(_DWORD *)(*(_DWORD *)(__readfsdword(0x30u) + 24) + 12) != 2 )
  {
    if ( key[5] == 102 )
    {
      *a3 |= 0x2DCu;
      v17 = *a3;
    }
    else
    {
      *a3 |= 0x21u;
    }
    v16 = *a3;
  }
  if ( key[5] == 115 )
  {
    *a3 |= 0xA04u;
    v18 = (char)a3;
    v20 = *a3;
  }
  else
  {
    v18 = (char)a3;
    *a3 ^= 0x1ADu;
  }
  v19 = *a3;
  _AL = v18 - v13;
  __asm { daa }
  if ( key[6] == 101 )
  {
    *a3 |= 0x2310u;
    v24 = *a3;
  }
  else
  {
    *a3 |= 0x4Au;
  }
  v23 = *a3;
  if ( key[7] == 99 )
  {
    result = a3;
    *a3 |= 0x8A10u;
    v26 = *a3;
  }
  else
  {
    *a3 &= 0x3A3u;
    result = (_DWORD *)*a3;
  }
  return result;
}

发现满足条件的key值只有[100, 98, 97, 112, 112, 115, 101, 99],即"dbappsec"

xor函数是将key和user每位对应异或。在013b1b3e处下断点动态调试扣出和密码异或计算的值

需要主要的是,动态调试和执行得到的异或值是不一样的,需要把类似反调试的代码nop掉,

    if ( *(_DWORD *)(__readfsdword(48) + 104) & 0x70 )
      v13 = v11 + v12;
    *(&v17 + v6) = byte_13C6050[(unsigned __int8)(v8 + v13)] ^ *(&v15 + v5);
    if ( *(_DWORD *)(__readfsdword(48) + 2) & 0xFF )
    {
      v11 = -83;
      v12 = 43;
    }

 然后得到box是[0x2a,0xd7,0x92,0xe9,0x53,0xe2,0xc4,0xcd],写脚本得到flag。

a=[0x2a,0xd7,0x92,0xe9,0x53,0xe2,0xc4,0xcd]
b=[0x64,0x62,0x61,0x70,0x70,0x73,0x65,0x63] #dbappsec
for i in range(8):
    print hex(a[i]^b[i]),
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!