zoukankan      html  css  js  c++  java
  • [BUUCTF]REVERSE——crackMe

    crackMe

    附件

    步骤:

    1. 例行检查,32位程序,无壳
      在这里插入图片描述

    2. 32位ida载入,已知用户名welcomebeijing,解密码,直接看main函数
      在这里插入图片描述
      可以看到程序是个死循环,只有满足sub_404830函数的条件,才能跳出循环

    3. sub_404830函数里要让sub_404830函数返回1,必须要让v13=43924,v13经过了sub_401470的变换,先看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 |= 20u;
        v6 = *a3;
      }
      else
      {
        *a3 &= 97u;
        _EAX = (_DWORD *)*a3;
      }
      __asm { aam }
      if ( a2[2] == 'a' )
      {
        *a3 |= 132u;
        v9 = *a3;
      }
      else
      {
        *a3 &= 0xAu;
      }
      v8 = *a3;
      v10 = ~(a1 >> -91);
      if ( a2[3] == 'p' )
      {
        *a3 |= 276u;
        v12 = *a3;
      }
      else
      {
        *a3 >>= 7;
      }
      v11 = *a3;
      v13 = v10 - 1;
      if ( a2[4] == 'p' )
      {
        *a3 |= 896u;
        v15 = *a3;
      }
      else
      {
        *a3 *= 2;
      }
      v14 = *a3;
      if ( *(_DWORD *)(*(_DWORD *)(__readfsdword(0x30u) + 24) + 12) != 2 )
      {
        if ( a2[5] == 'f' )
        {
          *a3 |= 732u;
          v17 = *a3;
        }
        else
        {
          *a3 |= 0x21u;
        }
        v16 = *a3;
      }
      if ( a2[5] == 's' )
      {
        *a3 |= 2564u;
        v18 = (char)a3;
        v20 = *a3;
      }
      else
      {
        v18 = (char)a3;
        *a3 ^= 0x1ADu;
      }
      v19 = *a3;
      _AL = v18 - v13;
      __asm { daa }
      if ( a2[6] == 'e' )
      {
        *a3 |= 8976u;
        v24 = *a3;
      }
      else
      {
        *a3 |= 0x4Au;
      }
      v23 = *a3;
      if ( a2[7] == 'c' )
      {
        result = a3;
        *a3 |= 35344u;
        v26 = *a3;
      }
      else
      {
        *a3 &= 931u;
        result = (_DWORD *)*a3;
      }
      return result;
    }
    

    经过计算得知,a2必须要满足所有条件才会返回43924
    在这里插入图片描述
    此时a2数组里的值是[100, 98, 97, 112, 112, 115, 101, 99] -->(dbappsec)

    1. sub_401470函数分析结束,返回到sub_401830函数
      在这里插入图片描述
      v16就是我们刚刚在sub_401470函数里得到的a2=[100, 98, 97, 112, 112, 115, 101, 99]
      可以看到v16的值主要是在第63行赋予的,byte_416050是通过与变换后的密码异或得到v16,我们得要知道byte_416050里的值,静态分析点进去全是问号,动调看一下里面的值

    调了半天没找到里面的值,原来这里有反调试语句,关于反调试具体的看下面给的文章链接
    https://www.cnblogs.com/Crisczy/p/7575521.html
    https://www.cnblogs.com/15157737693zsp/p/4663339.html
    https://blog.csdn.net/a709046532/article/details/108323936

    这边有3条反调试语句
    在这里插入图片描述
    其实就是寻找PEB结构体中的特定字段来判断是否处于被调试的状态

    if ( *(_DWORD *)(*(_DWORD *)(__readfsdword(0x30u) + 24) + 12) != 2 )-->Flags字段
    if ( *(_DWORD *)(__readfsdword(0x30u) + 104) & 0x70 )  --------------->NtGlobalFlag字段
    if ( *(_DWORD *)(__readfsdword(0x30u) + 2) & 0xFF ) ------------------>BeingDebugged字段
    

    为了能够成功动调程序,我们需要进行反反调试,绕过反调试代码执行函数的正常逻辑。
    上述的链接3中给出几个比较常见的手段:

    1. 动调时手动修改代码,比如汇编下把jz改成jmp/jnz,我改成了jnz,机器码是74改成75
    2. 使用插件ScyllaHide了(https://github.com/x64dbg/ScyllaHide/)

    绕过反动调后能够得到byte_416050 = [0x2a,0xd7,0x92,0xe9,0x53,0xe2,0xc4,0xcd],具体的绕过过程看上述的链接3
    exp

    import hashlib
    
    box = [0x2a,0xd7,0x92,0xe9,0x53,0xe2,0xc4,0xcd]
    a =[100,98,97,112,112,115,101,99]
    flag=""
    
    for i in range(8):
        flag+=(hex(a[i]^box[i])[2:])
    print ('md5加密前:'+flag)
    
    m = hashlib.md5()
    b = flag.encode(encoding='utf-8')
    m.update(b)
    flag = m.hexdigest()
    
    print ('md5加密后:'+flag)
    

    在这里插入图片描述
    flag{d2be2981b84f2a905669995873d6a36c}

  • 相关阅读:
    2016/10/18 数据库设计三大范式
    2016/10/13 Oracle COALESCE()
    2016/10/13 oracle中的round()
    2016/10/10 数据、数据元素和数据项
    2016/09/29 Maven简介
    2016/09/29 瀑布模型开发和敏捷开发
    python2和python3中的类
    使用JQuery完成页面定时弹出广告
    JQuery入门+js库文件分享
    使用JavaScript完成控制下拉列表左右选择
  • 原文地址:https://www.cnblogs.com/xlrp/p/14273626.html
Copyright © 2011-2022 走看看