【CTF REVERSE】ctf02-查找字符串

1、前言

公司大拿给写的一个CTF逆向程序,提升我们组内人员的水平。

基于对话框MFC框架开发,使用EDIT控制特性隐藏Flag,可借助spy4win之类窗体工具找出Flag。
程序加UPX壳,已对壳信息混淆处理,PEiD无法识别出壳信息。
DLL 依赖情况如图所示。

2、思路

程序用IDA查看的时候,因为有壳混淆后是没法跟下去的。这道题比较简单,破解还是常规思路。。。

  • 1)手动脱UPX壳
  • 2)IDA查找字符串,获取信息
  • 3)跟踪调用的函数

3、过程

1、脱壳

UPX是一款常用的压缩壳,单步跟踪法或者是ESP定律都能很快的脱掉它。

单步跟踪到如下反汇编指令处:


00406A10 pushad
00406A11 mov esi,ctf02.00406000
00406A16 lea edi,dword ptr ds:[esi-0x5000]
00406A1C push edi
00406A1D or ebp,-0x1
00406A20 jmp short ctf02.00406A32

F8单步向下运行,遇到向上的跳转就F4到下一条指令去,不让自己迷失在各种解密操作指令中。

00406A32 mov ebx,dword ptr ds:[esi]
00406A34 sub esi,-0x4
00406A37 adc ebx,ebx
00406A39 jb short ctf02.00406A28   ;  向上跳转,跳转实现向上运行
00406A3B mov eax,0x1               ;   F4运行到此处,遇到红色跳转就下一条
00406A40 add ebx,ebx
00406A42 jnz short ctf02.00406A4B
00406A44 mov ebx,dword ptr ds:[esi]
00406A46 sub esi,-0x4
00406A49 adc ebx,ebx
00406A4B adc eax,eax
00406A4D add ebx,ebx
00406A4F jnb short ctf02.00406A40
00406A51 jnz short ctf02.00406A5C
00406A53 mov ebx,dword ptr ds:[esi]
00406A55 sub esi,-0x4
00406A58 adc ebx,ebx
00406A5A jnb short ctf02.00406A40
00406A5C xor ecx,ecx
00406A5E sub eax,0x3
00406A61 jb short ctf02.00406A70
00406A63 shl eax,0x8
00406A66 mov al,byte ptr ds:[esi]
00406A68 inc esi                   ;  ctf02.0040600B
00406A69 xor eax,-0x1
00406A6C je short ctf02.00406AE2
00406A6E mov ebp,eax
00406A70 add ebx,ebx

接下来会遇见两个向上的跳转,一个小跳转,一个大跳转。
我们在NOP指令的下一行代码F4运行到那一条,接下来的操作就比较重复化,遇到跳转就F4到下一条。

然后遇到popad指令的时候说明我们距离OEP就不远了!

00406ABD mov al,byte ptr ds:[edx]
00406ABF inc edx                              ;  
00406AC0 mov byte ptr ds:[edi],al 
00406AC2 inc edi                              ;  
00406AC3 dec ecx
00406AC4 jnz short ctf02.00406ABD             ;  小跳转
00406AC6 jmp ctf02.00406A2E                   ;  大跳转
00406ACB nop
00406ACC mov eax,dword ptr ds:[edx]           ;  F4运行到此处
00406ACE add edx,0x4
00406AD1 mov dword ptr ds:[edi],eax
00406AD3 add edi,0x4
00406AD6 sub ecx,0x4
00406AD9 ja short ctf02.00406ACC              ;  又是一个跳转的地方
00406ADB add edi,ecx                          ;  F4运行到此处
00406ADD jmp ctf02.00406A2E                   ;  大跳转,F4运行到下一条语句
00406AE2 pop esi                              ;  
00406AE3 mov edi,esi                          ;  F4运行到此处
00406AE5 mov ecx,0x3B
00406AEA mov al,byte ptr ds:[edi]
00406AEC inc edi                              ;  
00406AED sub al,0xE8
00406AEF cmp al,0x1
00406AF1 ja short ctf02.00406AEA              ;  小跳转
00406AF3 cmp byte ptr ds:[edi],0x1            ;  F4运行到此处
00406AF6 jnz short ctf02.00406AEA
00406AF8 mov eax,dword ptr ds:[edi]           ;  F4运行到此处
00406AFA mov bl,byte ptr ds:[edi+0x4]
00406AFD shr ax,0x8
00406B01 rol eax,0x10
00406B04 xchg ah,al
00406B06 sub eax,edi                          ;  
00406B08 sub bl,0xE8
00406B0B add eax,esi                          ;  
00406B0D mov dword ptr ds:[edi],eax
00406B0F add edi,0x5
00406B12 mov al,bl
00406B14 loopd short ctf02.00406AEF           ;  循环操作
00406B16 lea edi,dword ptr ds:[esi+0x4000]    ;  F4运行到此处
00406B1C mov eax,dword ptr ds:[edi]
00406B1E or eax,eax
00406B20 je short ctf02.00406B67
00406B22 mov ebx,dword ptr ds:[edi+0x4]
00406B25>lea eax,dword ptr ds:[eax+esi+0x68BC]
00406B2C add ebx,esi                          ;  
00406B2E push eax
00406B2F add edi,0x8
00406B32 call dword ptr ds:[esi+0x6920]       ;  
00406B38 xchg eax,ebp                         ;  
00406B39 mov al,byte ptr ds:[edi]
00406B3B inc edi                              ;  
00406B3C or al,al
00406B3E je short ctf02.00406B1C
00406B40 mov ecx,edi                          ;  
00406B42 jns short ctf02.00406B4B
00406B44 movzx eax,word ptr ds:[edi]
00406B47 inc edi                              ;  
00406B48 push eax
00406B49 inc edi                              ;  
00406B4A db B9
00406B4B push edi                             ;  
00406B4C dec eax
00406B4D repne scas byte ptr es:[edi]
00406B4F push ebp                             ;  
00406B50 call dword ptr ds:[esi+0x6924]       ;  
00406B56 or eax,eax
00406B58 je short ctf02.00406B61
00406B5A mov dword ptr ds:[ebx],eax
00406B5C add ebx,0x4
00406B5F jmp short ctf02.00406B39             ;  无条件跳转
00406B61 call dword ptr ds:[esi+0x6934]       ;  
00406B67 mov ebp,dword ptr ds:[esi+0x6928]    ;  F4运行到此处
00406B6D lea edi,dword ptr ds:[esi-0x1000]
00406B73 mov ebx,0x1000
00406B78 push eax
00406B79 push esp
00406B7A push 0x4
00406B7C push ebx
00406B7D push edi                             ;  
00406B7E call ebp                             ;  
00406B80 lea eax,dword ptr ds:[edi+0x207]
00406B86 and byte ptr ds:[eax],0x7F
00406B89 and byte ptr ds:[eax+0x28],0x7F
00406B8D pop eax
00406B8E push eax
00406B8F push esp
00406B90 push eax
00406B91 push ebx
00406B92 push edi                             ;  
00406B93 call ebp                             ;  
00406B95 pop eax
00406B96 popad                                ;  到这里的时候说明快到OEP了
00406B97 lea eax,dword ptr ss:[esp-0x80]
00406B9B push 0x0
00406B9D cmp esp,eax
00406B9F jnz short ctf02.00406B9B
00406BA1 sub esp,-0x80
00406BA4 jmp ctf02.00401750                   ;  跳转到OEP

到了00406BA4 这里的时候,我用OD插件-Ollydump脱壳。

2、IDA查看

脱了壳后的程序,用IDA看就没有障碍了。

IDA打开后-View - Open Subviews - Srings

然后X键,查看哪个函数在引用它,F5查看C源码就确认出Flag了。

signed int __thiscall sub_4012B0(CDialog *this)
{
  CDialog *v1; // esi@1
  HMENU v2; // eax@1
  struct CMenu *v3; // edi@1
  LPCSTR lpNewItem; // [sp+8h] [bp-10h]@2
  int v6; // [sp+14h] [bp-4h]@2

  v1 = this;
  CDialog::OnInitDialog(this);
  v2 = GetSystemMenu(*((HWND *)v1 + 8), 0);
  v3 = CMenu::FromHandle(v2);
  if ( v3 )
  {
    CString::CString(&lpNewItem);
    v6 = 0;
    CString::LoadStringA((CString *)&lpNewItem, 0x65u);
    if ( *((_DWORD *)lpNewItem - 2) )
    {
      AppendMenuA(*((HMENU *)v3 + 1), 0x800u, 0, 0);
      AppendMenuA(*((HMENU *)v3 + 1), 0, 0x10u, lpNewItem);
    }
    v6 = -1;
    CString::~CString((CString *)&lpNewItem);
  }
  SendMessageA(*((HWND *)v1 + 8), 0x80u, 1u, *((_DWORD *)v1 + 40));
  SendMessageA(*((HWND *)v1 + 8), 0x80u, 0, *((_DWORD *)v1 + 40)); //发送消息到窗口
  CWnd::SetWindowTextA((CDialog *)((char *)v1 + 96), "6C9F69EF-C170-4e43-A007-9AA3526823DB");  //设置文本
  SendMessageA(*((HWND *)v1 + 32), 0xCCu, 0x2Eu, 0);
  return 1;
}

4、附件下载地址

https://github.com/zprogram/zprogram.github.io/blob/master/Blog_attachment/CTF/CTF_REVERSE_ctf02_查找字符串.zip

5、参考

手脱UPX壳的几种方法
http://blog.csdn.net/xiaoyuai1234/article/details/51463501

原文地址:https://www.cnblogs.com/17bdw/p/7684560.html