码迷,mamicode.com
首页 > 其他好文 > 详细

越界攻击强制修改运算结果

时间:2016-01-16 12:00:27      阅读:208      评论:0      收藏:0      [点我收藏+]

标签:

系统 : Windows xp

程序 : CrackMe2016

程序下载地址 :http://pan.baidu.com/s/1dDOP2Xr

要求 : 找出正确密码

使用工具 : OD & IDA

可在看雪论坛中查找关于此程序的讨论,http://bbs.pediy.com/showthread.php?t=206850

 

打开IDA,翻找出提示匹配成功的字串“Good job”,并向上翻找出关键代码:

004010F0  /> \55            push    ebp
004010F1  |.  8BEC          mov     ebp, esp
004010F3  |.  81EC 44040000 sub     esp, 444
004010F9  |.  53            push    ebx
004010FA  |.  56            push    esi
004010FB  |.  57            push    edi
004010FC  |.  8DBD BCFBFFFF lea     edi, dword ptr [ebp-444]
00401102  |.  B9 11010000   mov     ecx, 111
00401107  |.  B8 CCCCCCCC   mov     eax, CCCCCCCC
0040110C  |.  F3:AB         rep     stos dword ptr es:[edi]
0040110E  |.  C745 FC 00000>mov     dword ptr [ebp-4], 0
00401115  |>  B8 01000000   /mov     eax, 1
0040111A  |.  85C0          |test    eax, eax
0040111C  |.  74 5A         |je      short 00401178
0040111E  |.  68 CC504200   |push    004250CC                        ;  ASCII "Please input password:"
00401123  |.  E8 D8030000   |call    00401500                        ;  _printf
00401128  |.  83C4 04       |add     esp, 4                          ;  平衡堆栈
0040112B  |.  8D8D FCFBFFFF |lea     ecx, dword ptr [ebp-404]
00401131  |.  51            |push    ecx
00401132  |.  68 C8504200   |push    004250C8                        ;  ASCII "%s"
00401137  |.  E8 64030000   |call    004014A0                        ;  _scanf
0040113C  |.  83C4 08       |add     esp, 8
0040113F  |.  8D95 FCFBFFFF |lea     edx, dword ptr [ebp-404]        ;  取password
00401145  |.  52            |push    edx                             ;  password入栈
00401146  |.  E8 BAFEFFFF   |call    00401005
0040114B  |.  83C4 04       |add     esp, 4                          ;  平衡堆栈
0040114E  |.  8945 FC       |mov     dword ptr [ebp-4], eax
00401151  |.  817D FC 53434>|cmp     dword ptr [ebp-4], 474353
00401158  |.  75 0F         |jnz     short 00401169
0040115A  |.  68 B8504200   |push    004250B8                        ;  ASCII 0A,"Good job!",LF
0040115F  |.  E8 9C030000   |call    00401500
00401164  |.  83C4 04       |add     esp, 4
00401167  |.  EB 0F         |jmp     short 00401178
00401169  |>  68 9C504200   |push    0042509C                        ;  ASCII "Incorrect password!",LF,LF
0040116E  |.  E8 8D030000   |call    00401500
00401173  |.  83C4 04       |add     esp, 4
00401176  |.^ EB 9D         \jmp     short 00401115
00401178  |>  68 94504200   push    00425094                         ;  ASCII "pause"
0040117D  |.  E8 0E020000   call    00401390
00401182  |.  83C4 04       add     esp, 4
00401185  |.  5F            pop     edi
00401186  |.  5E            pop     esi
00401187  |.  5B            pop     ebx
00401188  |.  81C4 44040000 add     esp, 444
0040118E  |.  3BEC          cmp     ebp, esp
00401190  |.  E8 BB010000   call    00401350
00401195  |.  8BE5          mov     esp, ebp
00401197  |.  5D            pop     ebp
00401198  \.  C3            retn

F7进入401500子程序:

00401005 $ /E9 16000000 jmp 00401020

 继续跟进:

00401020  /> \55            push    ebp
00401021  |.  8BEC          mov     ebp, esp
00401023  |.  81EC C0000000 sub     esp, 0C0
00401029  |.  53            push    ebx
0040102A  |.  56            push    esi
0040102B  |.  57            push    edi
0040102C  |.  8DBD 40FFFFFF lea     edi, dword ptr [ebp-C0]          ;  取一段内存
00401032  |.  B9 30000000   mov     ecx, 30
00401037  |.  B8 CCCCCCCC   mov     eax, CCCCCCCC
0040103C  |.  F3:AB         rep     stos dword ptr es:[edi]          ;  重复拷贝将eax拷贝到【edi】中0x30次,
0040103E  |.  8B45 08       mov     eax, dword ptr [ebp+8]           ;  取password
00401041  |.  50            push    eax                              ;  入栈
00401042  |.  8D4D 80       lea     ecx, dword ptr [ebp-80]          ;  取一段内存
00401045  |.  51            push    ecx                              ;  入栈
00401046  |.  E8 15020000   call    00401260                         ;  拷贝字串
0040104B  |.  83C4 08       add     esp, 8                           ;  平衡堆栈
0040104E  |.  68 6C504200   push    0042506C                         ;  ‘看雪论坛的兄弟姐妹们,元旦快乐!’
00401053  |.  8D55 80       lea     edx, dword ptr [ebp-80]          ;  取password
00401056  |.  52            push    edx
00401057  |.  E8 74010000   call    004011D0                         ;  _strcmp
0040105C  |.  83C4 08       add     esp, 8                           ;  平衡堆栈
0040105F  |.  8945 F8       mov     dword ptr [ebp-8], eax           ;  保存比较结果
00401062  |.  8B45 08       mov     eax, dword ptr [ebp+8]           ;  取password
00401065  |.  50            push    eax                              ;  password入栈
00401066  |.  8D4D A8       lea     ecx, dword ptr [ebp-58]          ;  取一段内存
00401069  |.  51            push    ecx                              ;  入栈
0040106A  |.  E8 F1010000   call    00401260                         ;  拷贝字串
0040106F  |.  83C4 08       add     esp, 8                           ;  平衡堆栈
00401072  |.  68 44504200   push    00425044                         ;  ‘有可能被你发现密码了,加油加油’
00401077  |.  8D55 A8       lea     edx, dword ptr [ebp-58]          ;  取password
0040107A  |.  52            push    edx                              ;  password入栈
0040107B  |.  E8 50010000   call    004011D0                         ;  _strcmp
00401080  |.  83C4 08       add     esp, 8                           ;  平衡堆栈
00401083  |.  8945 F8       mov     dword ptr [ebp-8], eax           ;  保存比较结果
00401086  |.  8B45 08       mov     eax, dword ptr [ebp+8]           ;  取password
00401089  |.  50            push    eax                              ;  password入栈
0040108A  |.  8D4D D0       lea     ecx, dword ptr [ebp-30]          ;  取一段内存
0040108D  |.  51            push    ecx                              ;  入栈
0040108E  |.  E8 CD010000   call    00401260                         ;  拷贝字串
00401093  |.  83C4 08       add     esp, 8                           ;  平衡堆栈
00401096  |.  68 1C504200   push    0042501C                         ;  ‘关键是如何输入,中文我也没办法!’
0040109B  |.  8D55 D0       lea     edx, dword ptr [ebp-30]          ;  取password
0040109E  |.  52            push    edx                              ;  password入栈
0040109F  |.  E8 2C010000   call    004011D0                         ;  _strcmp
004010A4  |.  83C4 08       add     esp, 8                           ;  平衡堆栈
004010A7  |.  8945 FC       mov     dword ptr [ebp-4], eax           ;  保存比较结果
004010AA  |.  8B45 F8       mov     eax, dword ptr [ebp-8]
004010AD  |.  5F            pop     edi
004010AE  |.  5E            pop     esi
004010AF  |.  5B            pop     ebx
004010B0  |.  81C4 C0000000 add     esp, 0C0
004010B6  |.  3BEC          cmp     ebp, esp
004010B8  |.  E8 93020000   call    00401350                         ;  __chkesp 只检测ebp的当前值(函数入口点的栈顶地址)和函数释放栈上空间以后的esp是否一致
004010BD  |.  8BE5          mov     esp, ebp
004010BF  |.  5D            pop     ebp
004010C0  \.  C3            retn

程序最终根据eax的值进行判断,eax的值来源于[ebp-8]。对[ebp-8]下内存写入断点,发现最后在给eax赋值之前最后一次写入[ebp-8]的值是在

00401083 |. 8945 F8 mov dword ptr [ebp-8], eax ; 保存比较结果

 比较结果是什么呢?我们跟入_strcmp:

004011D0  /$  8B5424 04     mov     edx, dword ptr [esp+4]           ;  取password
004011D4  |.  8B4C24 08     mov     ecx, dword ptr [esp+8]
004011D8  |.  F7C2 03000000 test    edx, 3
004011DE  |.  75 3C         jnz     short 0040121C
004011E0  |>  8B02          /mov     eax, dword ptr [edx]            ;  将字串当做dword数值赋给eax
004011E2  |.  3A01          |cmp     al, byte ptr [ecx]              ;  与‘关键是如何输入,中文我也没办法!’逐个比较
004011E4  |.  75 2E         |jnz     short 00401214
004011E6  |.  0AC0          |or      al, al                          ;  字符为空?
004011E8  |.  74 26         |je      short 00401210
004011EA  |.  3A61 01       |cmp     ah, byte ptr [ecx+1]            ;  取高位继续比较
004011ED  |.  75 25         |jnz     short 00401214
004011EF  |.  0AE4          |or      ah, ah                          ;  字符为空?
004011F1  |.  74 1D         |je      short 00401210
004011F3  |.  C1E8 10       |shr     eax, 10                         ;  逻辑右移16位
004011F6  |.  3A41 02       |cmp     al, byte ptr [ecx+2]            ;  取低位继续比较
004011F9  |.  75 19         |jnz     short 00401214
004011FB  |.  0AC0          |or      al, al                          ;  字符为空?
004011FD  |.  74 11         |je      short 00401210
004011FF  |.  3A61 03       |cmp     ah, byte ptr [ecx+3]            ;  取高位继续比较
00401202  |.  75 10         |jnz     short 00401214
00401204  |.  83C1 04       |add     ecx, 4
00401207  |.  83C2 04       |add     edx, 4
0040120A  |.  0AE4          |or      ah, ah                          ;  字符为空?
0040120C  |.^ 75 D2         \jnz     short 004011E0
0040120E  |.  8BFF          mov     edi, edi
00401210  |>  33C0          xor     eax, eax
00401212  |.  C3            retn
00401213  |   90            nop
00401214  |>  1BC0          sbb     eax, eax
00401216  |.  D1E0          shl     eax, 1
00401218  |.  40            inc     eax
00401219  |.  C3            retn

结果只可能是两个:0和FFFFFFFF。这意味着我们不能通过普通的手段来进行破解,只能修改程序结构(爆破)或是修改内存(越界攻击)。这里,我们查看[ebp-8]前后的内存区域:

技术分享

执行到40108A时,[ebp-30]的内存地址是:12FAF4,相对于存放结果的位置[ebp-4]如上图所示。接下来的流程要将输入的password拷贝至[ebp-30],而程序对于password并没有做任何格式限制,这意味着理论上我们可以输入无限大的字串,直到将[ebp-4]的值覆盖掉。这里,我们随便输入40个字符就可以到达[ebp-4]的区域,对比流程,发现[ebp-4]的值应该为:53|43|47|00

最后一个字节作为字串结尾,前三个字节转化为ASCII码。最终可以通过验证的字串格式应为:任意40个占一字节的字符+"SCG"。

验证我们的猜想:

技术分享

越界攻击强制修改运算结果

标签:

原文地址:http://www.cnblogs.com/ZRBYYXDM/p/5135080.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!