BUUCTF-RE-CrackMe

题目描述:

小张从网上下载到一个黑客软件,然而开发者并不打算共享,所以小张注册了一个用户名叫welcomebeijing,但是密码需要进行逆向计算,请求出密码,进行MD5的32位小写哈希,进行提交。 注意:得到的 flag 请包上 flag{} 提交
运行:

 用户名已经给出是welcomebeijing

需要拿到密码

IDA查看逻辑:

 点进去sub_401830

bool __usercall sub_401830@<al>(int ebx0@<ebx>, int a1, const char *a2)
{
  int v4; // [esp+18h] [ebp-22Ch]
  unsigned int v5; // [esp+1Ch] [ebp-228h]
  unsigned int v6; // [esp+28h] [ebp-21Ch]
  unsigned int v7; // [esp+30h] [ebp-214h]
  char v8; // [esp+36h] [ebp-20Eh]
  char v9; // [esp+37h] [ebp-20Dh]
  char v10; // [esp+38h] [ebp-20Ch]
  unsigned __int8 v11; // [esp+39h] [ebp-20Bh]
  unsigned __int8 v12; // [esp+3Ah] [ebp-20Ah]
  char v13; // [esp+3Bh] [ebp-209h]
  int v14; // [esp+3Ch] [ebp-208h]
  char v15; // [esp+40h] [ebp-204h]
  char v16; // [esp+41h] [ebp-203h]
  char v17; // [esp+140h] [ebp-104h]
  char v18; // [esp+141h] [ebp-103h]

  v5 = 0;
  v6 = 0;
  v12 = 0;
  v11 = 0;
  v17 = 0;
  memset(&v18, 0, 0xFFu);
  v15 = 0;
  memset(&v16, 0, 0xFFu);
  v10 = 0;
  v7 = 0;
  v4 = 0;
  while ( v7 < strlen(a2) )
  {
    if ( isdigit(a2[v7]) )
    {
      v9 = a2[v7] - 48;
    }
    else if ( isxdigit(a2[v7]) )
    {
      if ( *(_DWORD *)(*(_DWORD *)(__readfsdword(0x30u) + 24) + 12) != 2 )
        a2[v7] = 34;
      v9 = (a2[v7] | 0x20) - 87;
    }
    else
    {
      v9 = ((a2[v7] | 0x20) - 97) % 6 + 10;
    }
    v10 = v9 + 16 * v10;
    if ( !((signed int)(v7 + 1) % 2) )
    {
      *(&v15 + v4++) = v10;
      ebx0 = v4;
      v10 = 0;
    }
    ++v7;
  }
  while ( (signed int)v6 < 8 )
  {
    v11 += byte_416050[++v12];
    v13 = byte_416050[v12];
    v8 = byte_416050[v11];
    byte_416050[v11] = v13;
    byte_416050[v12] = v8;
    if ( *(_DWORD *)(__readfsdword(0x30u) + 104) & 0x70 )
      v13 = v11 + v12;
    *(&v17 + v6) = byte_416050[(unsigned __int8)(v8 + v13)] ^ *(&v15 + v5);
    if ( *(_DWORD *)(__readfsdword(0x30u) + 2) & 0xFF )
    {
      v11 = -83;
      v12 = 43;
    }
    sub_401710(&v17, a1, v6++);
    v5 = v6;
    if ( v6 >= &v15 + strlen(&v15) + 1 - &v16 )
      v5 = 0;
  }
  v14 = 0;
  sub_401470(ebx0, &v17, &v14);
  return v14 == 43924;
}

 

 这三个if均为反调试

前面

 这部分对密码操作就是生成v15数组

往下看

 处理byte,生成V17数组

,sub_401710:

 还是处理V17数组

sub_401470:

里面还有一个反调试:

 这个函数的逻辑就是判断V17是否为dbappsec

 最后处理完的a3应该为43924

那么就可以动态调试拿到byte数组,通过异或久可以拿到v15了:

过掉反调试:

 然后dump byte数组

 

 0x2A,0xD7,0x92,0xe9,0x53,0xe2,0xc4,0xcd

写脚本

 算md5:

原文地址:https://www.cnblogs.com/basstorm/p/12662023.html