zoukankan      html  css  js  c++  java
  • 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:

  • 相关阅读:
    Uva 10779 collector's problem
    poj 2728 最优比率树(最小生成树问题)
    LA 3126 二分图匹配 最小路径覆盖
    poj 1149 最大流构图
    Step By Step(Java XML篇)
    Step By Step(Java 输入输出篇)
    Step By Step(Java 集合篇)
    Step By Step(Java 线程篇)
    Step By Step(Java 反射篇)
    Step By Step(Java 国际化篇)
  • 原文地址:https://www.cnblogs.com/basstorm/p/12662023.html
Copyright © 2011-2022 走看看