Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/modules/auxiliary/admin/upnp/soap_portmapping.rb
Views: 11784
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45require 'nokogiri'67class MetasploitModule < Msf::Auxiliary8include Msf::Exploit::Remote::HttpClient910def initialize11super(12'Name' => 'UPnP IGD SOAP Port Mapping Utility',13'Description' => %q{14Manage port mappings on UPnP IGD-capable device using the AddPortMapping and15DeletePortMapping SOAP requests16},17'Author' =>18[19'St0rn <fabien[at]anbu-pentest.com>', # initial module20'Jon Hart <jon_hart[at]rapid7.com>' # module cleanup and refactoring21],22'License' => MSF_LICENSE,23'References' => [['URL', 'http://www.upnp-hacks.org/igd.html']],24'DefaultAction' => 'ADD',25'Actions' =>26[27[ 'ADD',28{29'Description' => 'Use the AddPortMapping SOAP command to open and forward a port',30'SOAP_ACTION' => 'AddPortMapping'31}32],33[ 'DELETE',34{35'Description' => 'Use the DeletePortMapping SOAP command to remove a port forwarding',36'SOAP_ACTION' => 'DeletePortMapping'37}38]39],40)4142register_options(43[44OptString.new('TARGETURI', [true, 'UPnP control URL', '/' ]),45OptAddress.new('INTERNAL_CLIENT', [false, 'Internal client hostname/IP']),46OptAddress.new('EXTERNAL_CLIENT', [false, 'External client hostname/IP']),47OptEnum.new('PROTOCOL', [true, 'Transport level protocol to map', 'TCP', %w(TCP UDP)]),48OptInt.new('INTERNAL_PORT', [false, 'Internal port']),49OptInt.new('EXTERNAL_PORT', [true, 'External port']),50OptInt.new('LEASE_DURATION', [false, 'Lease time for mapping, in seconds', 3600])51],52self.class53)54end5556def internal_port57@internal_port ||= datastore['INTERNAL_PORT']58end5960def internal_client61@internal_client ||= datastore['INTERNAL_CLIENT']62end6364def external_port65@external_port ||= datastore['EXTERNAL_PORT']66end6768def external_client69@external_client ||= datastore['EXTERNAL_CLIENT']70end7172def lease_duration73@lease_duration ||= datastore['LEASE_DURATION']74end7576def protocol77@protocol ||= datastore['PROTOCOL']78end7980def soap_action81@soap_action ||= action.opts['SOAP_ACTION']82end8384def build_soap85builder = ::Nokogiri::XML::Builder.new do |xml|86xml['SOAP-ENV'].Envelope('xmlns:SOAP-ENV' => 'http://schemas.xmlsoap.org/soap/envelope', 'SOAP-ENV:encodingStyle' => 'http://schemas.xmlsoap.org/soap/encoding/') do87xml['SOAP-ENV'].Body do88xml['m'].send(soap_action, 'xmlns:m' => 'urn:schemas-upnp-org:service:WANIPConnection:1') do89case action.name90when 'ADD'91xml.NewPortMappingDescription(Rex::Text.rand_text_alpha(8)) { xml.parent.namespace = nil }92xml.NewLeaseDuration(lease_duration) { xml.parent.namespace = nil }93xml.NewInternalClient(internal_client) { xml.parent.namespace = nil }94xml.NewEnabled(1) { xml.parent.namespace = nil }95xml.NewExternalPort(external_port) { xml.parent.namespace = nil }96xml.NewRemoteHost(external_client) { xml.parent.namespace = nil }97xml.NewProtocol(protocol) { xml.parent.namespace = nil }98xml.NewInternalPort(internal_port) { xml.parent.namespace = nil }99when 'DELETE'100xml.NewExternalPort(external_port) { xml.parent.namespace = nil }101xml.NewRemoteHost(external_client) { xml.parent.namespace = nil }102xml.NewProtocol(protocol) { xml.parent.namespace = nil }103end104end105end106end107end108builder.to_xml109end110111def run112res = send_request_cgi(113'uri' => normalize_uri(target_uri.path),114'method' => 'POST',115'content-type' => 'text/xml;charset="utf-8"',116'data' => build_soap,117'headers' => {118'SoapAction' => "urn:schemas-upnp-org:service:WANIPConnection:1##{soap_action}"119}120)121122external_map = "#{external_client ? external_client : 'any'}:#{external_port}/#{protocol}"123internal_map = "#{internal_client ? internal_client : 'any'}:#{internal_port}/#{protocol}"124map = "#{external_map} -> #{internal_map}"125126if res127if res.code == 200128print_good("#{peer} #{map} #{action.name} succeeded")129else130print_error("#{peer} #{map} #{action.name} failed with response code #{res.code}")131vprint_status("#{res.body}")132end133else134print_error("#{peer} no response for #{map} #{action.name}")135end136end137end138139140