RSS
热门关键字:  Linux  图形  项目管理  LAMP  java
当前位置 : 主页>开源安全>列表

WinRAR 7z压缩包处理溢出分析和利用

来源:黑客防线 作者:sherman 时间:2007-10-25 点击:

 { "edx", "JJJJJJJJJJJJJJJJJ7RY" mixedcase_ascii_decoder_body },
 { "ebx", "SYIIIIIIIIIIIIIIII7QZ" mixedcase_ascii_decoder_body },
 { "esp", "TYIIIIIIIIIIIIIIII7QZ" mixedcase_ascii_decoder_body },
 { "ebp", "UYIIIIIIIIIIIIIIII7QZ" mixedcase_ascii_decoder_body },
 { "esi", "VYIIIIIIIIIIIIIIII7QZ" mixedcase_ascii_decoder_body },
 { "edi", "WYIIIIIIIIIIIIIIII7QZ" mixedcase_ascii_decoder_body },
 { "[esp-10]", "LLLLLLLLLLLLLLLLYIIIIIIIIIQZ" mixedcase_ascii_decoder_body },
 { "[esp-C]", "LLLLLLLLLLLLYIIIIIIIIIIIQZ" mixedcase_ascii_decoder_body },
 { "[esp-8]", "LLLLLLLLYIIIIIIIIIIIIIQZ" mixedcase_ascii_decoder_body },
 { "[esp-4]", "LLLL7YIIIIIIIIIIIIII7QZ" mixedcase_ascii_decoder_body },
 { "[esp]", "YIIIIIIIIIIIIIIIIIQZ" mixedcase_ascii_decoder_body },

字串7


 { "[esp+4]", "YYIIIIIIIIIIIIIIII7QZ" mixedcase_ascii_decoder_body },
 { "[esp+8]", "YYYIIIIIIIIIIIIIIIIQZ" mixedcase_ascii_decoder_body },
 { "[esp+C]", "YYYYIIIIIIIIIIIIIII7QZ" mixedcase_ascii_decoder_body },
 { "[esp+10]", "YYYYYIIIIIIIIIIIIIIIQZ" mixedcase_ascii_decoder_body },
 { "[esp+14]", "YYYYYYIIIIIIIIIIIIII7QZ" mixedcase_ascii_decoder_body },
 { "[esp+18]", "YYYYYYYIIIIIIIIIIIIIIQZ" mixedcase_ascii_decoder_body },
 { "[esp+1C]", "YYYYYYYYIIIIIIIIIIIII7QZ" mixedcase_ascii_decoder_body },
 { "seh", mixedcase_w32sehgetpc "IIIIIIIIIIIIIIIII7QZ" // ecx code 字串4

    这是解码头,根据溢出的时候哪个寄存器指向Shellcode进行选用,生成Shellcode主体的函数配套代码alphashellcode里面有。我们这应该选择TYIIIIIIIIIIIIIIII7QZ这个解码头,Shellcode怪长的我就不贴了,以免有骗稿费之嫌。再次测试,成功。

字串7

疑云重重

字串2

    虽然利用是成功了,不过不知道大家有没有发现一些比较奇怪的问题:1.如果是栈溢出,为什么溢出点却在超长字符串的前面,而不是在中间或者后面,不会它的缓冲区只有1个字节吧? 2.为什么打开的时候不触发漏洞只有解压的时候才触发? 3.为什么gyzy说这不是严格意义上的栈溢出?带着这一连串的问题,任何言语的猜测都是苍白的,还是让OD去解开我们的疑团。这里顺便发一下牢骚,OD对多线程的处理真是不咋的,经常会莫名其妙的出现假死的现象,先加载WinRAR.exe让OD跑起来,记得先把跳转地址改掉,以免出现没有断下来的尴尬局面,另外还要记得校正CRC值,不然它会郑重的警告你一下,哈哈,祈祷你的机器没有假死吧。

字串7

    我发现原版的OD好像稳定性好一点,所以我用的是原版的,这个时候EIP已经被覆盖了,我在堆栈窗口里往上下都翻了翻,没有翻到正常的返回地址,奇怪了,不可能所有的返回地址都覆盖吧?太狠了,居然一点线索都不给留下,按照常规堆栈回溯下很容易找到出问题的代码,看来事情越发的扑朔迷离了。 Ctrl+F2重新来,F9让他跑起来,然后bp CreateThread,在这上面下断,因为很明显解压文件的时候需要新开线程,会发现0049CDFC这个地址是新开线程的起始地址,然后一部部往下跟(省略N多步骤,要是都写出来有点感觉自己像是写长篇小说了),跟进到这个地方: 字串4

0045BD63 |. E8 7466FBFF |CALL WinRAR.004123DC
0045BD68 |. 84C0 |TEST AL,AL
0045BD6A |. 74 04 |JE SHORT WinRAR.0045BD70
0045BD6C |. B0 01 |MOV AL,1
0045BD6E |. EB 0F |JMP SHORT WinRAR.0045BD7F
0045BD70 |> 43 |INC EBX
0045BD71 |> 3B9F 04040000 CMP EBX,DWORD PTR DS:[EDI+404]
0045BD77 |.^0F8C 41FFFFFF \JL WinRAR.0045BCBE
0045BD7D |. 33C0 XOR EAX,EAX
0045BD7F |> 5F POP EDI
0045BD80 |. 5E POP ESI
0045BD81 |. 5B POP EBX
0045BD82 |. 8BE5 MOV ESP,EBP
0045BD84 |. 5D POP EBP
0045BD85 \. C2 0800 RETN 8
    返回的时候EIP被覆盖了,RETN 8指令说明在返回地址后面要有8个字节的保留空间,再跟Shellcode,我们在0045BD80下断。

字串9

霍然开朗

字串3

    但这时的ESP却还是01DCF80C,怎么后来就跳到了017D6578了呢,答案就在下面0045B082的 MOV ESP,EBP而EBP恰恰是017D6578,这就解释了刚才的种种疑问,为什么异常发生的时候栈里回溯不到调用信息,为什么溢出点会出现在字符串的前几个字节了。答案就是EBP的值被污染了。重复上面的若干步骤,在01DCF8E8上下写入硬断,里面保存着被覆盖前的的EBP,下面这段代码覆盖了栈里的正确EBP值:

字串6

00494AD8 |. 57 PUSH EDI
00494AD9 |. 8B7D 08 MOV EDI,DWORD PTR SS:[EBP+8]
00494ADC |. 8BC7 MOV EAX,EDI
00494ADE |. 8B75 0C MOV ESI,DWORD PTR SS:[EBP+C]
00494AE1 |. 8B4D 10 MOV ECX,DWORD PTR SS:[EBP+10]
00494AE4 |. 8BD1 MOV EDX,ECX
00494AE6 |. D1E9 SHR ECX,1
00494AE8 |. D1E9 SHR ECX,1
00494AEA |. FC CLD ecx 203
00494AEB |. F3:A5 REP MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ESI]
00494AED |. 8BCA MOV ECX,EDX
00494AEF |. 83E1 03 AND ECX,3 2
00494AF2 |. F3:A4 REP MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI]
00494AF4 |. 5F POP EDI

字串4

    省略N多步骤,最后发现是00412562这里的指令将EBP值污染了,然后返回到0045BD82的时候间接覆盖了ESP。

最新评论共有 0 位网友发表了评论
发表评论
评论内容:不能超过250字,需审核,请自觉遵守互联网相关政策法规。
用户名: 密码:
匿名?
注册