zoukankan      html  css  js  c++  java
  • BUUCTF--crackMe

    测试文件:https://www.lanzous.com/iaxqvbg

    代码分析

     1 int __usercall wmain@<eax>(int a1@<ebx>)
     2 {
     3   FILE *v1; // eax
     4   FILE *v2; // eax
     5   char v4; // [esp+3h] [ebp-405h]
     6   char v5; // [esp+4h] [ebp-404h]
     7   char v6; // [esp+5h] [ebp-403h]
     8   char v7; // [esp+104h] [ebp-304h]
     9   char v8; // [esp+105h] [ebp-303h]
    10   char v9; // [esp+204h] [ebp-204h]
    11   char v10; // [esp+205h] [ebp-203h]
    12   char v11; // [esp+304h] [ebp-104h]
    13   char v12; // [esp+305h] [ebp-103h]
    14 
    15   printf("Come one! Crack Me~~~
    ");
    16   v11 = 0;                                      // user
    17   memset(&v12, 0, 0xFFu);
    18   v9 = 0;                                       // password
    19   memset(&v10, 0, 0xFFu);
    20   while ( 1 )
    21   {
    22     do
    23     {
    24       do
    25       {
    26         printf("user(6-16 letters or numbers):");
    27         scanf("%s", &v11);
    28         v1 = (FILE *)file_ptr();                // 文件流指针
    29         fflush(v1);                             // 更新缓存
    30       }
    31       while ( !check_len_str(&v11) );           // 判断输入长度和类型是否符合要求
    32       printf("password(6-16 letters or numbers):");
    33       scanf("%s", &v9);
    34       v2 = (FILE *)file_ptr();
    35       fflush(v2);
    36     }
    37     while ( !check_len_str(&v9) );
    38     sub_401090(&v11);
    39     v7 = 0;
    40     memset(&v8, 0, 0xFFu);
    41     v5 = 0;
    42     memset(&v6, 0, 0xFFu);
    43     v4 = ((int (__cdecl *)(char *, char *))loc_4011A0)(&v7, &v5);
    44     if ( sub_401830(a1, (int)&v11, &v9) )
    45     {
    46       if ( v4 )
    47         break;
    48     }
    49     printf(&v5);
    50   }
    51   printf(&v7);
    52   return 0;
    53 }

    前面的代码不需要说什么,主要分析sub_401830函数,应该是需要我们返回True的

     1 bool __usercall sub_401830@<al>(int ebx0@<ebx>, int a1, const char *a2)
     2 {
     3   int v4; // [esp+18h] [ebp-22Ch]
     4   signed int v5; // [esp+1Ch] [ebp-228h]
     5   signed int v6; // [esp+28h] [ebp-21Ch]
     6   unsigned int v7; // [esp+30h] [ebp-214h]
     7   char v8; // [esp+36h] [ebp-20Eh]
     8   char v9; // [esp+37h] [ebp-20Dh]
     9   char v10; // [esp+38h] [ebp-20Ch]
    10   unsigned __int8 v11; // [esp+39h] [ebp-20Bh]
    11   unsigned __int8 v12; // [esp+3Ah] [ebp-20Ah]
    12   char v13; // [esp+3Bh] [ebp-209h]
    13   int v14; // [esp+3Ch] [ebp-208h]
    14   char v15; // [esp+40h] [ebp-204h]
    15   char v16; // [esp+41h] [ebp-203h]
    16   char v17; // [esp+140h] [ebp-104h]
    17   char v18; // [esp+141h] [ebp-103h]
    18 
    19   v5 = 0;
    20   v6 = 0;
    21   v12 = 0;
    22   v11 = 0;
    23   v17 = 0;
    24   memset(&v18, 0, 0xFFu);
    25   v15 = 0;
    26   memset(&v16, 0, 0xFFu);
    27   v10 = 0;
    28   v7 = 0;
    29   v4 = 0;
    30   while ( v7 < strlen(a2) )
    31   {
    32     if ( isdigit(a2[v7]) )                      // 判断密码是不是数字
    33     {
    34       v9 = a2[v7] - 48;                         // 字符转整型
    35     }
    36     else if ( isxdigit(a2[v7]) )                // 检测是否为16进制数字
    37     {
    38       if ( *(_DWORD *)(*(_DWORD *)(__readfsdword(0x30u) + 24) + 12) != 2 )
    39         a2[v7] = 34;
    40       v9 = (a2[v7] | 0x20) - 87;                // 转为整型数字
    41     }
    42     else
    43     {
    44       v9 = ((a2[v7] | 0x20) - 97) % 6 + 10;     // 按照字母次序,6个一组,对应10~15
    45     }
    46     v10 = v9 + 16 * v10;
    47     if ( !((signed int)(v7 + 1) % 2) )
    48     {
    49       *(&v15 + v4++) = v10;                     // 存储a2偶数位变换后v9的值
    50       ebx0 = v4;
    51       v10 = 0;
    52     }
    53     ++v7;
    54   }
    55   while ( v6 < 8 )                              // 进行某种变换
    56   {
    57     v11 += byte_416050[++v12];
    58     v13 = byte_416050[v12];
    59     v8 = byte_416050[v11];
    60     byte_416050[v11] = v13;
    61     byte_416050[v12] = v8;
    62     if ( *(_DWORD *)(__readfsdword(0x30u) + 104) & 0x70 )
    63       v13 = v11 + v12;
    64     *(&v17 + v6) = byte_416050[(unsigned __int8)(v8 + v13)] ^ *(&v15 + v5);// v17的生成,通过byte_416050和v15异或
    65     if ( *(_DWORD *)(__readfsdword(0x30u) + 2) & 0xFF )
    66     {
    67       v11 = -83;
    68       v12 = 43;
    69     }
    70     sub_401710((int)&v17, (const char *)a1, v6++);
    71     v5 = v6;
    72     if ( v6 >= (unsigned int)(&v15 + strlen(&v15) + 1 - &v16) )
    73       v5 = 0;
    74   }
    75   v14 = 0;
    76   sub_401470(ebx0, &v17, &v14);
    77   return v14 == 43924;
    78 }

    整体这个函数我们可以分成三部分

    1. 代码第30~54行,将字符串密码转换为两两组合的整型。
    2. 代码第55~74行,生成v17数组
    3. 代码第75~77行,传入v17数组和v14=0,返回的v14需要等于43924

    第三部分

    我们能够反过来推倒,首先查看sub_401470函数

    _DWORD *__usercall sub_401470@<eax>(int a1@<ebx>, _BYTE *a2, _DWORD *a3)
    {
      int v3; // ST28_4
      int v4; // ecx
      _DWORD *_EAX; // eax
      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
      char _AL; // al
      int v23; // ST0C_4
      int v24; // eax
      _DWORD *result; // eax
      int v26; // edx
    
      if ( *a2 == 'd' )
      {
        *a3 |= 4u;
        v4 = *a3;
      }
      else
      {
        *a3 ^= 3u;
      }
      v3 = *a3;
      if ( a2[1] == 'b' )
      {
        _EAX = a3;
        *a3 |= 0x14u;
        v6 = *a3;
      }
      else
      {
        *a3 &= 0x61u;
        _EAX = (_DWORD *)*a3;
      }
      __asm { aam }
      if ( a2[2] == 'a' )
      {
        *a3 |= 0x84u;
        v9 = *a3;
      }
      else
      {
        *a3 &= 0xAu;
      }
      v8 = *a3;
      v10 = ~(a1 >> -91);
      if ( a2[3] == 'p' )
      {
        *a3 |= 0x114u;
        v12 = *a3;
      }
      else
      {
        *a3 >>= 7;
      }
      v11 = *a3;
      v13 = v10 - 1;
      if ( a2[4] == 'p' )
      {
        *a3 |= 0x380u;
        v15 = *a3;
      }
      else
      {
        *a3 *= 2;
      }
      v14 = *a3;
      if ( *(_DWORD *)(*(_DWORD *)(__readfsdword(0x30u) + 24) + 12) != 2 )
      {
        if ( a2[5] == 'f' )
        {
          *a3 |= 0x2DCu;
          v17 = *a3;
        }
        else
        {
          *a3 |= 0x21u;
        }
        v16 = *a3;
      }
      if ( a2[5] == 's' )
      {
        *a3 |= 0xA04u;
        v18 = (char)a3;
        v20 = *a3;
      }
      else
      {
        v18 = (char)a3;
        *a3 ^= 0x1ADu;
      }
      v19 = *a3;
      _AL = v18 - v13;
      __asm { daa }
      if ( a2[6] == 'e' )
      {
        *a3 |= 0x2310u;
        v24 = *a3;
      }
      else
      {
        *a3 |= 0x4Au;
      }
      v23 = *a3;
      if ( a2[7] == 'c' )
      {
        result = a3;
        *a3 |= 0x8A10u;
        v26 = *a3;
      }
      else
      {
        *a3 &= 0x3A3u;
        result = (_DWORD *)*a3;
      }
      return result;
    }

    应该是需要我们满足其中的每一个条件,因此得到v17的值"dbappsec"

    第二部分

    有了v17的值,我们知道第二部分代码第64行,通过byte_416050与变换后的密码异或得到v17。我们已知账号为welcomebeijing,求密码。因此我们需要通过动态调试,获取byte_416050的值

    记录下byte_416050的值为

    0x2a, 0xd7, 0x92, 0xe9, 0x53, 0xe2, 0xc4, 0xcd

    第一部分

    变换后的密码格式为两两组成的十六进制

    脚本

    # -*- coding:utf-8 -*-
    import hashlib
    
    box = [0x2a, 0xd7, 0x92, 0xe9, 0x53, 0xe2, 0xc4, 0xcd]
    s = "dbappsec"
    
    secret = []
    
    for i in range(len(s)):
        secret.append(hex(ord(s[i])^box[i]).replace("0x",''))
    flag = ''.join(secret)
    md = hashlib.md5()
    md.update(flag.encode('utf-8'))
    print ("flag{"+md.hexdigest()+"}")

    get flag!

    flag{d2be2981b84f2a905669995873d6a36c}

  • 相关阅读:
    Mac Pro 安装 Sublime Text 2.0.2,个性化设置,主题 和 插件 收藏
    Mac Pro 编译安装 Nginx 1.8.1
    Mac Pro 解压安装MySQL二进制分发版 mysql-5.6.30-osx10.11-x86_64.tar.gz(不是dmg的)
    Mac Pro 修改主机名
    Mac Pro 软件安装/个性化配置 汇总
    Mac Pro 安装 Homebrew 软件包管理工具
    Mac Pro 使用 ll、la、l等ls的别名命令
    Mac Pro 入门、遇到的问题、个性化设置 汇总
    Linux/UNIX线程(2)
    工作流引擎activiti入门
  • 原文地址:https://www.cnblogs.com/Mayfly-nymph/p/12624018.html
Copyright © 2011-2022 走看看