metasploit-framework/modules/auxiliary/admin/upnp/soap_portmapping.rb

141 lines
4.7 KiB
Ruby
Raw Normal View History

2015-07-26 18:59:04 +00:00
##
# encoding: utf-8
# This module requires Metasploit: http://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'msf/core'
2015-09-17 02:53:33 +00:00
require 'nokogiri'
2015-08-28 22:09:58 +00:00
2015-07-26 18:59:04 +00:00
class Metasploit3 < Msf::Auxiliary
2015-08-28 21:47:13 +00:00
include Msf::Exploit::Remote::HttpClient
2015-07-26 18:59:04 +00:00
2015-08-28 21:19:28 +00:00
def initialize
super(
2015-08-31 17:42:50 +00:00
'Name' => 'UPnP IGD SOAP Port Mapping Utility',
2015-09-25 18:34:16 +00:00
'Description' => %q{
Manage port mappings on UPnP IGD-capable device using the AddPortMapping and
DeletePortMapping SOAP requests
},
2015-08-31 17:42:50 +00:00
'Author' =>
[
'St0rn <fabien[at]anbu-pentest.com>', # initial module
'Jon Hart <jon_hart[at]rapid7.com>' # module cleanup and refactoring
],
'License' => MSF_LICENSE,
2015-08-31 19:03:17 +00:00
'References' => [['URL', 'http://www.upnp-hacks.org/igd.html']],
2015-08-31 17:42:50 +00:00
'DefaultAction' => 'ADD',
'Actions' =>
[
[ 'ADD',
{
'Description' => 'Use the AddPortMapping SOAP command to open and forward a port',
'SOAP_ACTION' => 'AddPortMapping'
}
],
[ 'DELETE',
{
'Description' => 'Use the DeletePortMapping SOAP command to remove a port forwarding',
'SOAP_ACTION' => 'DeletePortMapping'
}
]
],
2015-08-28 21:19:28 +00:00
)
2015-08-28 21:19:28 +00:00
register_options(
2015-07-26 18:59:04 +00:00
[
2015-08-28 21:49:57 +00:00
OptString.new('TARGETURI', [true, 'UPnP control URL', '/' ]),
OptAddress.new('INTERNAL_CLIENT', [false, 'Internal client hostname/IP']),
2015-09-25 18:41:27 +00:00
OptAddress.new('EXTERNAL_CLIENT', [false, 'External client hostname/IP']),
OptEnum.new('PROTOCOL', [true, 'Transport level protocol to map', 'TCP', %w(TCP UDP)]),
OptInt.new('INTERNAL_PORT', [false, 'Internal port']),
OptInt.new('EXTERNAL_PORT', [true, 'External port']),
2015-09-25 18:34:16 +00:00
OptInt.new('LEASE_DURATION', [false, 'Lease time for mapping, in seconds', 3600])
2015-08-28 21:19:28 +00:00
],
self.class
)
end
2015-07-26 18:59:04 +00:00
def internal_port
@internal_port ||= datastore['INTERNAL_PORT']
end
def internal_client
@internal_client ||= datastore['INTERNAL_CLIENT']
end
def external_port
@external_port ||= datastore['EXTERNAL_PORT']
end
def external_client
@external_client ||= datastore['EXTERNAL_CLIENT']
end
def lease_duration
@lease_duration ||= datastore['LEASE_DURATION']
end
def protocol
@protocol ||= datastore['PROTOCOL']
end
def soap_action
@soap_action ||= action.opts['SOAP_ACTION']
end
2015-09-17 02:53:33 +00:00
def build_soap
builder = ::Nokogiri::XML::Builder.new do |xml|
2015-09-25 18:35:38 +00:00
xml['SOAP-ENV'].Envelope('xmlns:SOAP-ENV' => 'http://schemas.xmlsoap.org/soap/envelope', 'SOAP-ENV:encodingStyle' => 'http://schemas.xmlsoap.org/soap/encoding/') do
2015-09-17 02:53:33 +00:00
xml['SOAP-ENV'].Body do
xml['m'].send(soap_action, 'xmlns:m' => 'urn:schemas-upnp-org:service:WANIPConnection:1') do
case action.name
when 'ADD'
xml.NewPortMappingDescription(Rex::Text.rand_text_alpha(8)) { xml.parent.namespace = nil }
xml.NewLeaseDuration(lease_duration) { xml.parent.namespace = nil }
xml.NewInternalClient(internal_client) { xml.parent.namespace = nil }
xml.NewEnabled(1) { xml.parent.namespace = nil }
xml.NewExternalPort(external_port) { xml.parent.namespace = nil }
xml.NewRemoteHost(external_client) { xml.parent.namespace = nil }
xml.NewProtocol(protocol) { xml.parent.namespace = nil }
xml.NewInternalPort(internal_port) { xml.parent.namespace = nil }
when 'DELETE'
xml.NewExternalPort(external_port) { xml.parent.namespace = nil }
xml.NewRemoteHost(external_client) { xml.parent.namespace = nil }
xml.NewProtocol(protocol) { xml.parent.namespace = nil }
end
end
end
end
end
2015-09-17 02:53:33 +00:00
builder.to_xml
end
2015-08-28 22:49:29 +00:00
2015-09-17 02:53:33 +00:00
def run
2015-08-28 21:47:13 +00:00
res = send_request_cgi(
2015-08-28 21:49:57 +00:00
'uri' => normalize_uri(target_uri.path),
'method' => 'POST',
'content-type' => 'text/xml;charset="utf-8"',
2015-09-17 02:53:33 +00:00
'data' => build_soap,
2015-08-28 21:49:57 +00:00
'headers' => {
'SoapAction' => "urn:schemas-upnp-org:service:WANIPConnection:1##{soap_action}"
2015-08-28 21:47:13 +00:00
}
)
2015-07-26 18:59:04 +00:00
external_map = "#{external_client ? external_client : 'any'}:#{external_port}/#{protocol}"
internal_map = "#{internal_client ? internal_client : 'any'}:#{internal_port}/#{protocol}"
map = "#{external_map} -> #{internal_map}"
2015-08-28 21:47:13 +00:00
if res
if res.code == 200
print_good("#{peer} #{map} #{action.name} succeeded")
2015-08-28 21:47:13 +00:00
else
2015-09-25 18:51:18 +00:00
print_error("#{peer} #{map} #{action.name} failed with response code #{res.code}")
vprint_status("#{res.body}")
2015-08-28 21:47:13 +00:00
end
2015-08-28 21:19:28 +00:00
else
print_error("#{peer} no response for #{map} #{action.name}")
2015-08-28 21:19:28 +00:00
end
end
2015-07-26 18:59:04 +00:00
end