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


    系统 : 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"。

    验证我们的猜想:

    我们一路奋战,不是为了改变世界,而是不让世界改变我们 ——《熔炉》
  • 相关阅读:
    小组件
    rabbitMQ操作
    爬虫
    爬虫相关
    HTTP相关
    Python基本数据类型
    机器学习技法 之 支持向量回归(SVR)
    机器学习基石 之 线性回归(Linear Regression)
    机器学习技法 之 径向基函数网络(RBF Network)
    各个常用的排序算法的适用场景详细分析
  • 原文地址:https://www.cnblogs.com/ZRBYYXDM/p/5135080.html
Copyright © 2020-2023  润新知