吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 4996|回复: 11
收起左侧

[CTF] 【新手】DDCTF-RE1、2

  [复制链接]
H1ghker 发表于 2019-4-25 12:31
新手刚开始学习逆向,有很多地方说得不对或者不好还希望各位表哥能指正
Windows Reverse1

0x01
首先exeinfo查一下壳,发现是upx壳

0x02
脱壳
这里针对upx壳有很多办法,我就挑一个好懂的和一个好用的说



1、首先是ESP定律脱壳,这里先载入OD,F8单步一次


注意观察右边寄存器esp的变化,选中esp,选择在数据窗口中跟随

可以看到这时左下方窗口中跟踪到数值所对应的地址正对应esp,在这里下硬件断点,选择断点-->硬件访问-->word

F9运行一下
[Asm] 纯文本查看 复制代码
00407C47   .  8D4424 80     lea eax,dword ptr ss:[esp-0x80]
00407C4B   >  6A 00         push 0x0
00407C4D   .  39C4          cmp esp,eax
00407C4F   .^ 75 FA         jnz short reverse1.00407C4B
00407C51   .  83EC 80       sub esp,-0x80
00407C54   .- E9 9E97FFFF   jmp reverse1.004013F7


F4运行到7c51,F8步过一次,达到oep
[Asm] 纯文本查看 复制代码
004013F7    E8 7C040000     call reverse1.00401878
004013FC  ^ E9 9FFDFFFF     jmp reverse1.004011A0
00401401    8BFF            mov edi,edi
00401403    55              push ebp
00401404    8BEC            mov ebp,esp
00401406    81EC 28030000   sub esp,0x328
0040140C    A3 A0314000     mov dword ptr ds:[0x4031A0],eax
00401411    890D 9C314000   mov dword ptr ds:[0x40319C],ecx


2、然后是一步到位法
od载入后ctrl+f搜索出栈指令


可以看到又到了上边的地址
[Asm] 纯文本查看 复制代码
00407C46   .  61            popad
00407C47   .  8D4424 80     lea eax,dword ptr ss:[esp-0x80]
00407C4B   >  6A 00         push 0x0
00407C4D   .  39C4          cmp esp,eax
00407C4F   .^ 75 FA         jnz short reverse1.00407C4B
00407C51   .  83EC 80       sub esp,-0x80
00407C54   .- E9 9E97FFFF   jmp reverse1.004013F7







lordpe提取一下

这时候修复一下iat


0x03
找到地址后import rce获取输入表转储到文件即可,IDA分析一波,直接F5大法

[C] 纯文本查看 复制代码
int __cdecl main(int argc, const char **argv, const char **envp)
{
  int result; // eax@2
  char v4; // [sp+4h] [bp-804h]@1
  char v5; // [sp+5h] [bp-803h]@1
  char v6; // [sp+404h] [bp-404h]@1
  char Dst; // [sp+405h] [bp-403h]@1

  v6 = 0;
  memset(&Dst, 0, 0x3FFu);
  v4 = 0;
  memset(&v5, 0, 0x3FFu);
  printf("please input code:");
  scanf("%s", &v6);
  sub_401000(&v6);
  if ( !strcmp(&v4, "DDCTF{reverseME}") )
  {
    printf("You've got it!!%s\n", &v4);
    result = 0;
  }
  else
  {
    printf("Try again later.\n");
    result = 0;
  }
  return result;
}

分析一下对输入内容的check
[C] 纯文本查看 复制代码
unsigned int __cdecl sub_401000(const char *a1)
{
  _BYTE *v1; // ecx@0
  unsigned int v2; // edi@1
  unsigned int result; // eax@1
  int v4; // ebx@2

  v2 = 0;
  result = strlen(a1);
  if ( result )
  {
    v4 = a1 - v1;
    do
    {
      *v1 = byte_402FF8[v1[v4]];
      ++v2;
      ++v1;
      result = strlen(a1);
    }
    while ( v2 < result );
  }
  return result;
}

可以发现这货啥都没干,那我们也不必看下去,可以直接OD载入,nop掉判断,输入DDCTF{reverseME}
[Asm] 纯文本查看 复制代码
004010FB    90              nop
004010FC    90              nop
004010FD    8D4C24 04       lea ecx,dword ptr ss:[esp+0x4]
00401101    51              push ecx
00401102    68 20214000     push dumped_.00402120                    ; You've got it!!%s\n
00401107    FFD6            call esi
00401109    83C4 08         add esp,0x8
0040110C    33C0            xor eax,eax
0040110E    5E              pop esi                                  ; kernel32.7C817077
0040110F    8B8C24 00080000 mov ecx,dword ptr ss:[esp+0x800]
00401116    33CC            xor ecx,esp
00401118    E8 29000000     call dumped_.00401146
0040111D    81C4 04080000   add esp,0x804
00401123    C3              retn


check通过

Windows Reverse2
0x01
继续exeinfo查壳,发现是aspack,接着手脱即可

脱壳步骤和上边的re1基本一致,使用esp定律脱掉即可,这里不多赘述
0x02
载入ida分析,F5大法

[C] 纯文本查看 复制代码
int __cdecl main(int argc, const char **argv, const char **envp)
{
  char Dest; // [sp+8h] [bp-C04h]@4
  char v5; // [sp+9h] [bp-C03h]@4
  char v6; // [sp+408h] [bp-804h]@1
  char Dst; // [sp+409h] [bp-803h]@1
  char v8; // [sp+808h] [bp-404h]@1
  char v9; // [sp+809h] [bp-403h]@1

  v6 = 0;
  memset(&Dst, 0, 0x3FFu);
  v8 = 0;
  memset(&v9, 0, 0x3FFu);
  printf("input code:");
  scanf("%s", &v6);
  if ( !(unsigned __int8)sub_4011F0() )
  {
    printf("invalid input\n");
    exit(0);
  }
  sub_401240(&v8);
  Dest = 0;
  memset(&v5, 0, 0x3FFu);
  sprintf(&Dest, "DDCTF{%s}", &v8);
  if ( !strcmp(&Dest, "DDCTF{reverse+}") )
    printf("You've got it !!! %s\n", &Dest);
  else
    printf("Something wrong. Try again...\n");
  return 0;
}

首先看一下sub_4011F0函数
[C] 纯文本查看 复制代码
char __usercall sub_4011F0@<al>(const char *a1@<esi>)
{
  signed int v1; // eax@1
  signed int v2; // edx@1
  int v3; // ecx@3
  char v4; // al@4

  v1 = strlen(a1);
  v2 = v1;
  if ( v1 && v1 % 2 != 1 )
  {
    v3 = 0;
    if ( v1 <= 0 )
      return 1;
    while ( 1 )
    {
      v4 = a1[v3];
      if ( (v4 < 48 || v4 > 57) && (v4 < 65 || v4 > 70) )
        break;
      if ( ++v3 >= v2 )
        return 1;
    }
  }
  return 0;
}

可以看出输入16进制字符串可以通过验证,然后是sub_401240函数
[C] 纯文本查看 复制代码
int __usercall sub_401240@<eax>(const char *a1@<esi>, int a2)
{
  signed int v2; // edi@1
  unsigned int v3; // edx@1
  char v4; // bl@2
  char v5; // al@3
  char v6; // al@7
  unsigned int v7; // ecx@11
  char v9; // [sp+Bh] [bp-405h]@0
  char v10; // [sp+Ch] [bp-404h]@1
  char Dst; // [sp+Dh] [bp-403h]@1

  v2 = strlen(a1);
  v10 = 0;
  memset(&Dst, 0, 0x3FFu);
  v3 = 0;
  if ( v2 > 0 )
  {
    v4 = v9;
    do
    {
      v5 = a1[v3];
      if ( (unsigned __int8)(a1[v3] - 48) > 9u )
      {
        if ( (unsigned __int8)(v5 - 65) <= 5u )
          v9 = v5 - 55;
      }
      else
      {
        v9 = a1[v3] - 48;
      }
      v6 = a1[v3 + 1];
      if ( (unsigned __int8)(a1[v3 + 1] - 48) > 9u )
      {
        if ( (unsigned __int8)(v6 - 65) <= 5u )
          v4 = v6 - 55;
      }
      else
      {
        v4 = a1[v3 + 1] - 48;
      }
      v7 = v3 >> 1;
      v3 += 2;
      *(&v10 + v7) = v4 | 16 * v9;
    }
    while ( (signed int)v3 < v2 );
  }
  return sub_401000(v2 / 2, (void *)a2);
}

好吧其实是有点长的,但是这里可以使些小技俩,结合程序本身进行推测,首先是第一段验证,只允许输入16进制字符串,那就随便输入个AF进去

可以看到输出结果很像base64编码,试着解码一下

那么就很简单了,我们开始构造payload
0x03
对最终需要进行对比的内容逆向分析,显然要经过base64解码,然后再转为16进制

用python构造一下
[Python] 纯文本查看 复制代码
>>> import base64
>>> import binascii
>>> a = 'reverse+'
>>> print(binascii.b2a_hex(base64.b64decode(a)).upper())
b'ADEBDEAEC7BE'

验证通过

reverse2_final.zip

7.54 KB, 下载次数: 16, 下载积分: 吾爱币 -1 CB

re2

reverse1_final.zip

3.99 KB, 下载次数: 8, 下载积分: 吾爱币 -1 CB

re1

免费评分

参与人数 2威望 +1 吾爱币 +8 热心值 +2 收起 理由
梦呓233 + 1 + 1 谢谢@Thanks!
Hmily + 1 + 7 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

Li1y 发表于 2019-4-25 18:38
冰露㊣神 发表于 2019-4-25 17:22
对啊,这种打印有什么用,他算法都没管,直接爆破出这个。那很多题都不用做了啊,想nop就nop,想jmp就jmp ...

做题求速度啊
把跳过GOT IT的跳转NOP,然后输入DDCTF{reverseME}就能看到flag,楼主思路很清晰,我看过其他分析算法的WP,但是还是觉得这个取巧的最好,比赛当然要这样,但是平时能逆算法还是逆算法吧
 楼主| H1ghker 发表于 2019-4-25 18:17
冰露㊣神 发表于 2019-4-25 15:51
ddctf第一题你没是在逗我吧,把判断nop掉,还判断啥?真正的flag是一堆乱码一样的,自己百度个wp看下吧

建议表哥你再去审一下这个cm哦,这里nop掉是没有问题的,我只是没有自己写脚本去逆字符集解密,而是利用这个cm会将其输出的特点去直接得到flag的
冰露㊣神 发表于 2019-4-25 15:51
ddctf第一题你没是在逗我吧,把判断nop掉,还判断啥?真正的flag是一堆乱码一样的,自己百度个wp看下吧
瑟瑟发抖小菜虾 发表于 2019-4-25 16:55
冰露㊣神 发表于 2019-4-25 15:51
ddctf第一题你没是在逗我吧,把判断nop掉,还判断啥?真正的flag是一堆乱码一样的,自己百度个wp看下吧

他这个只是把判断 nop掉 然后直接让flag 打印出来。。。。。。 你可以看看上面他nop掉后的程序截图。。。
gyzzzzz 发表于 2019-4-25 17:20
第一个题他的check函数我没记错就是固定字符替换
冰露㊣神 发表于 2019-4-25 17:22
瑟瑟发抖小菜虾 发表于 2019-4-25 16:55
他这个只是把判断 nop掉 然后直接让flag 打印出来。。。。。。 你可以看看上面他nop掉后的程序截图。。。

对啊,这种打印有什么用,他算法都没管,直接爆破出这个。那很多题都不用做了啊,想nop就nop,想jmp就jmp,这不是乱来嘛
cat95f 发表于 2019-4-25 18:50
看不懂,还是谢谢楼主分享
冰露㊣神 发表于 2019-4-25 19:14
H1ghker 发表于 2019-4-25 18:17
建议表哥你再去审一下这个cm哦,这里nop掉是没有问题的,我只是没有自己写脚本去逆字符集解密,而是利用 ...

不好意思,我傻逼了,你那图check的图看不到,刚我试了下,确实可以,tql
GJH588 发表于 2019-4-25 19:56
虽然看不懂,但还是支持一下
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-25 04:46

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表