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

  • 相关阅读:
    TCGA下载神器--TCGAbiolinks
    perl模块终极解决方案--转载
    Web前端优化
    关于CDN
    手写RateLimiter
    互联网高并发之限流
    互联网高并发之Hystrix实现服务隔离和降级
    关于Hystrix
    Apollo原理
    SpringBoot2.0之整合Apollo
  • 原文地址:https://www.cnblogs.com/17bdw/p/7684560.html
Copyright © 2011-2022 走看看