BUUCTF Reverse/crackMe

在这里插入图片描述

在这里插入图片描述

主要就是在sub_91830这个函数里面

在这里插入图片描述

上面部分是对密码进行一个变换,就是将字符转换为对应的十进制数字,然后存储到v16中

 while ( v7 < strlen(password) )
  {
    if ( isdigit(password[v7]) )                // 数字,0-9
    {
      v9 = password[v7] - 48;
    }
    else if ( isxdigit(password[v7]) )          // 检测是否是16进制字符,即A-F
    {
      if ( *((_DWORD *)NtCurrentPeb()->ProcessHeap + 3) != 2 )
        password[v7] = 34;
      v9 = (password[v7] | 0x20) - 87;
    }
    else
    {
      v9 = ((password[v7] | 0x20) - 97) % 6 + 10;// 字母
    }
    __rdtsc();
    __rdtsc();
    v10 = v9 + 16 * v10;
    if ( !((int)(v7 + 1) % 2) )                 // 奇数
    {
      v16[v4++ - 1] = v10;
      a1 = v4;
      v10 = 0;
    }
    ++v7;
  }                                         

下面就是对v16进行变换,其中byte_A6050的值是通过username来得到的,可以动调出来,经过一系列变换后最终变换的结果存储到v17

while ( v6 < 8 )
  {
    v11 += byte_A6050[++v12];
    v13 = byte_A6050[v12];
    v8 = byte_A6050[v11];
    byte_A6050[v11] = v13;
    byte_A6050[v12] = v8;
    if ( (NtCurrentPeb()->NtGlobalFlag & 0x70) != 0 )
      v13 = v11 + v12;
    v17[v6] = byte_A6050[(unsigned __int8)(v8 + v13)] ^ v16[v5 - 1];// v16是password变换后的
    if ( !(unsigned __int8)*(_DWORD *)&NtCurrentPeb()->BeingDebugged )
    {
      v11 = -83;
      v12 = 43;
    }
    sub_91710((int)v17, (const char *)username, v6++);
    v5 = v6;
    if ( v6 >= (unsigned int)(&v16[strlen(&v15)] - v16) )// v6 >= 4
      v5 = 0;
  }
  v14 = 0;
  sub_91470(a1, v17, &v14);                     // 检测flag是否正确
  return v14 == 0xAB94;
}

byte_A6050的值

在这里插入图片描述

这里可以得到v17的值 dbappsec 或者 dbappfec

unsigned int *__usercall sub_91470@<eax>(int a1@<ebx>, _BYTE *a2, unsigned int *a3)
{
  char v5; // al
  unsigned int *result; // eax

  if ( *a2 != 'd' )
    *a3 ^= 3u;
  else
    *a3 |= 4u;
  if ( a2[1] != 'b' )
  {
    *a3 &= 0x61u;
    _EAX = *a3;
  }
  else
  {
    _EAX = (unsigned int)a3;
    *a3 |= 0x14u;
  }
  __asm { aam }
  if ( a2[2] != 'a' )
    *a3 &= 0xAu;
  else
    *a3 |= 0x84u;
  if ( a2[3] != 'p' )
    *a3 >>= 7;
  else
    *a3 |= 0x114u;
  if ( a2[4] != 'p' )
    *a3 *= 2;
  else
    *a3 |= 0x380u;
  if ( *((_DWORD *)NtCurrentPeb()->ProcessHeap + 3) != 2 )
  {
    if ( a2[5] != 'f' )
      *a3 |= 0x21u;
    else
      *a3 |= 0x2DCu;
  }
  if ( a2[5] != 's' )
  {
    v5 = (char)a3;
    *a3 ^= 0x1ADu;
  }
  else
  {
    *a3 |= 0xA04u;
    v5 = (char)a3;
  }
  _AL = v5 - (~(a1 >> 5) - 1);
  __asm { daa }
  if ( a2[6] != 'e' )
    *a3 |= 0x4Au;
  else
    *a3 |= 0x2310u;
  if ( a2[7] != 'c' )
  {
    *a3 &= 0x3A3u;
    return (unsigned int *)*a3;
  }
  else
  {
    result = a3;
    *a3 |= 0x8A10u;
  }
  return result;
}

在异或的地方下断点,记录byte_7D6050[eax] 的值,即cl的值

在这里插入图片描述

这里if语句里面都是检测动态调试的,可以看这个反调试 - PEB(BeingDebugged ,NtGlobalFlag)

 if ( (NtCurrentPeb()->NtGlobalFlag & 0x70) != 0 )
      v13 = v11 + v12;
    v17[v6] = byte_A6050[(unsigned __int8)(v8 + v13)] ^ v16[v5 - 1];// v16是password变换后的
    if ( !(unsigned __int8)*(_DWORD *)&NtCurrentPeb()->BeingDebugged )
    {
      v11 = -83;
      v12 = 43;
    }

用ida动调的时候都是会直接跳过的,就不用修改了,直接执行就好


if ( (NtCurrentPeb()->NtGlobalFlag & 0x70) != 0 )
      v13 = v11 + v12;

在这里插入图片描述

 if ( !(unsigned __int8)*(_DWORD *)&NtCurrentPeb()->BeingDebugged )
    {
      v11 = -83;
      v12 = 43;
    }

在这里插入图片描述

直接挨个记录cl的值就好,得到的值为:{0x2A,0xD7,0x92,0xE9,0x53,0xE2,0xC4,0xCD}
写个脚本解密

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>
int main()
{
  int a[] = {0x2A,0xD7,0x92,0xE9,0x53,0xE2,0xC4,0xCD};
  char b1[] = "dbappsec";
  for(int i = 0 ; i < 8 ; i++)
  {
      printf("%x",a[i] ^ b1[i]);
  }
  return 0;


}

“dbappsec” 解密结果为: 4eb5f3992391a1ae md5加密结果 d2be2981b84f2a905669995873d6a36c,试一下刚好是最终flag,

最终flag:flag{d2be2981b84f2a905669995873d6a36c}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ofo300

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值