From fba81fc539f1b93ca02d197aedda86684817a3dd Mon Sep 17 00:00:00 2001 From: Fabien Date: Sun, 26 Jul 2015 20:59:04 +0200 Subject: [PATCH 01/24] Create soap_addportmapping.rb --- modules/auxiliary/upnp/soap_addportmapping.rb | 69 +++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 modules/auxiliary/upnp/soap_addportmapping.rb diff --git a/modules/auxiliary/upnp/soap_addportmapping.rb b/modules/auxiliary/upnp/soap_addportmapping.rb new file mode 100644 index 0000000000..80dddbe613 --- /dev/null +++ b/modules/auxiliary/upnp/soap_addportmapping.rb @@ -0,0 +1,69 @@ +## +# encoding: utf-8 +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' +class Metasploit3 < Msf::Auxiliary + include Msf::Exploit::Remote::Tcp + + def initialize + super( + 'Name' => 'UPnP AddPortMapping', + 'Version' => '$Revision: 1 $', + 'Description' => 'UPnP AddPortMapping SOAP request', + 'Author' => 'St0rn ', + 'License' => MSF_LICENSE + ) + register_options( + [ + OptString.new('CTRL_URL', [ true, 'UPnP Control URL']), + OptString.new('INTERNAL_CLIENT', [ true, 'New Internal Client']), + OptInt.new('INTERNAL_PORT', [ true, 'New Internal Port']), + OptInt.new('EXTERNAL_PORT', [ true, 'New External Port']) + ], self.class) + end + + def run() + ctrlurl = #{datastore['CTRL_URL']} + soapaction = "urn:schemas-upnp-org:service:WANIPConnection:1#AddPortMapping" + + content = "" + content << "" + content << "" + content << "" + content << "New Port Mapping" + content << "3600" + content << "#{datastore['INTERNAL_CLIENT']}" + content << "1" + content << "#{datastore['EXTERNAL_PORT']}" + content << "" + content << "TCP" + content << "#{datastore['INTERNAL_PORT']}" + content << "" + content << "" + content << "" + + contentlen = content.length + + header = "POST http://#{rhost}:#{rport}/#{ctrlurl} HTTP/1.0\r\n" + header << "Content-Type: text/xml;charset=\"utf-8\"\r\n" + header << "SOAPAction: #{soapaction}\n\r" + header << "User-Agent: SOAP AddPortMapping Metasploit Module\r\n" + header << "Host: #{rhost}:#{rport}\r\n" + header << "Content-Length: #{contentlen}\r\n" + header << "\r\n" + header << content + + print_status("Sending SOAP Request") + connect() + sock.puts(header) + resp=sock.recv(1024) + if resp.include? "200 OK" + print_good("PAT added successfully") + else + print_error("Fail") + end + end +end From 8dbd51ae3877dfc8f90a0b157c556c5a7f0af144 Mon Sep 17 00:00:00 2001 From: Fabien Date: Sun, 26 Jul 2015 20:59:43 +0200 Subject: [PATCH 02/24] Update soap_addportmapping.rb --- modules/auxiliary/upnp/soap_addportmapping.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/auxiliary/upnp/soap_addportmapping.rb b/modules/auxiliary/upnp/soap_addportmapping.rb index 80dddbe613..be15d31aaf 100644 --- a/modules/auxiliary/upnp/soap_addportmapping.rb +++ b/modules/auxiliary/upnp/soap_addportmapping.rb @@ -6,7 +6,7 @@ require 'msf/core' class Metasploit3 < Msf::Auxiliary - include Msf::Exploit::Remote::Tcp + include Msf::Exploit::Remote::Tcp def initialize super( From 1210183930774a65c0a5ab4cdb34061df8959a69 Mon Sep 17 00:00:00 2001 From: Fabien Date: Sun, 26 Jul 2015 21:41:47 +0200 Subject: [PATCH 03/24] Update soap_addportmapping.rb --- modules/auxiliary/upnp/soap_addportmapping.rb | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/modules/auxiliary/upnp/soap_addportmapping.rb b/modules/auxiliary/upnp/soap_addportmapping.rb index be15d31aaf..3dbac76346 100644 --- a/modules/auxiliary/upnp/soap_addportmapping.rb +++ b/modules/auxiliary/upnp/soap_addportmapping.rb @@ -32,16 +32,16 @@ class Metasploit3 < Msf::Auxiliary content = "" content << "" content << "" - content << "" - content << "New Port Mapping" - content << "3600" - content << "#{datastore['INTERNAL_CLIENT']}" - content << "1" - content << "#{datastore['EXTERNAL_PORT']}" - content << "" - content << "TCP" - content << "#{datastore['INTERNAL_PORT']}" - content << "" + content << "" + content << "New Port Mapping" + content << "3600" + content << "#{datastore['INTERNAL_CLIENT']}" + content << "1" + content << "#{datastore['EXTERNAL_PORT']}" + content << "" + content << "TCP" + content << "#{datastore['INTERNAL_PORT']}" + content << "" content << "" content << "" From 3fd18e484415e71d55f33b15c75a36202fa75a21 Mon Sep 17 00:00:00 2001 From: Fabien Date: Sun, 26 Jul 2015 21:57:49 +0200 Subject: [PATCH 04/24] Update soap_addportmapping.rb --- modules/auxiliary/upnp/soap_addportmapping.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/auxiliary/upnp/soap_addportmapping.rb b/modules/auxiliary/upnp/soap_addportmapping.rb index 3dbac76346..958a5b9d16 100644 --- a/modules/auxiliary/upnp/soap_addportmapping.rb +++ b/modules/auxiliary/upnp/soap_addportmapping.rb @@ -26,7 +26,7 @@ class Metasploit3 < Msf::Auxiliary end def run() - ctrlurl = #{datastore['CTRL_URL']} + ctrlurl = datastore['CTRL_URL'] soapaction = "urn:schemas-upnp-org:service:WANIPConnection:1#AddPortMapping" content = "" From 45c2422981148b2bbc81bef0319274247353714f Mon Sep 17 00:00:00 2001 From: Jon Hart Date: Fri, 28 Aug 2015 14:19:28 -0700 Subject: [PATCH 05/24] First pass at style cleanup --- modules/auxiliary/upnp/soap_addportmapping.rb | 99 ++++++++++--------- 1 file changed, 50 insertions(+), 49 deletions(-) diff --git a/modules/auxiliary/upnp/soap_addportmapping.rb b/modules/auxiliary/upnp/soap_addportmapping.rb index 958a5b9d16..807a19ac85 100644 --- a/modules/auxiliary/upnp/soap_addportmapping.rb +++ b/modules/auxiliary/upnp/soap_addportmapping.rb @@ -6,64 +6,65 @@ require 'msf/core' class Metasploit3 < Msf::Auxiliary - include Msf::Exploit::Remote::Tcp + include Msf::Exploit::Remote::Tcp - def initialize - super( - 'Name' => 'UPnP AddPortMapping', - 'Version' => '$Revision: 1 $', - 'Description' => 'UPnP AddPortMapping SOAP request', - 'Author' => 'St0rn ', - 'License' => MSF_LICENSE - ) - register_options( + def initialize + super( + 'Name' => 'UPnP AddPortMapping', + 'Description' => 'UPnP AddPortMapping SOAP request', + 'Author' => 'St0rn ', + 'License' => MSF_LICENSE + ) + register_options( [ OptString.new('CTRL_URL', [ true, 'UPnP Control URL']), OptString.new('INTERNAL_CLIENT', [ true, 'New Internal Client']), OptInt.new('INTERNAL_PORT', [ true, 'New Internal Port']), OptInt.new('EXTERNAL_PORT', [ true, 'New External Port']) - ], self.class) - end + ], + self.class + ) + end - def run() - ctrlurl = datastore['CTRL_URL'] - soapaction = "urn:schemas-upnp-org:service:WANIPConnection:1#AddPortMapping" + def run + ctrlurl = datastore['CTRL_URL'] + soapaction = "urn:schemas-upnp-org:service:WANIPConnection:1#AddPortMapping" - content = "" - content << "" - content << "" - content << "" - content << "New Port Mapping" - content << "3600" - content << "#{datastore['INTERNAL_CLIENT']}" - content << "1" - content << "#{datastore['EXTERNAL_PORT']}" - content << "" - content << "TCP" - content << "#{datastore['INTERNAL_PORT']}" - content << "" - content << "" - content << "" + content = "" + content << "" + content << "" + content << "" + content << "New Port Mapping" + content << "3600" + content << "#{datastore['INTERNAL_CLIENT']}" + content << "1" + content << "#{datastore['EXTERNAL_PORT']}" + content << "" + content << "TCP" + content << "#{datastore['INTERNAL_PORT']}" + content << "" + content << "" + content << "" - contentlen = content.length + contentlen = content.length - header = "POST http://#{rhost}:#{rport}/#{ctrlurl} HTTP/1.0\r\n" - header << "Content-Type: text/xml;charset=\"utf-8\"\r\n" - header << "SOAPAction: #{soapaction}\n\r" - header << "User-Agent: SOAP AddPortMapping Metasploit Module\r\n" - header << "Host: #{rhost}:#{rport}\r\n" - header << "Content-Length: #{contentlen}\r\n" - header << "\r\n" - header << content + header = "POST http://#{rhost}:#{rport}/#{ctrlurl} HTTP/1.0\r\n" + header << "Content-Type: text/xml;charset=\"utf-8\"\r\n" + header << "SOAPAction: #{soapaction}\n\r" + header << "User-Agent: SOAP AddPortMapping Metasploit Module\r\n" + header << "Host: #{rhost}:#{rport}\r\n" + header << "Content-Length: #{contentlen}\r\n" + header << "\r\n" + header << content - print_status("Sending SOAP Request") - connect() - sock.puts(header) - resp=sock.recv(1024) - if resp.include? "200 OK" - print_good("PAT added successfully") - else - print_error("Fail") - end - end + print_status("Sending SOAP Request") + connect + sock.puts(header) + resp = sock.recv(1024) + if resp.include? "200 OK" + print_good("PAT added successfully") + else + print_error("Fail") + end + end end From a0aaf93f27c78d543cc44621afa47a359ae9f316 Mon Sep 17 00:00:00 2001 From: Jon Hart Date: Fri, 28 Aug 2015 14:20:33 -0700 Subject: [PATCH 06/24] Relocate module to more correct location --- modules/auxiliary/{ => admin}/upnp/soap_addportmapping.rb | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename modules/auxiliary/{ => admin}/upnp/soap_addportmapping.rb (100%) diff --git a/modules/auxiliary/upnp/soap_addportmapping.rb b/modules/auxiliary/admin/upnp/soap_addportmapping.rb similarity index 100% rename from modules/auxiliary/upnp/soap_addportmapping.rb rename to modules/auxiliary/admin/upnp/soap_addportmapping.rb From ba95a7d2acc9d57b540c388a8d74ede07e90cfe9 Mon Sep 17 00:00:00 2001 From: Jon Hart Date: Fri, 28 Aug 2015 14:47:13 -0700 Subject: [PATCH 07/24] Convert to using HttpClient --- .../admin/upnp/soap_addportmapping.rb | 49 +++++++++---------- 1 file changed, 23 insertions(+), 26 deletions(-) diff --git a/modules/auxiliary/admin/upnp/soap_addportmapping.rb b/modules/auxiliary/admin/upnp/soap_addportmapping.rb index 807a19ac85..89b9dc8703 100644 --- a/modules/auxiliary/admin/upnp/soap_addportmapping.rb +++ b/modules/auxiliary/admin/upnp/soap_addportmapping.rb @@ -6,7 +6,7 @@ require 'msf/core' class Metasploit3 < Msf::Auxiliary - include Msf::Exploit::Remote::Tcp + include Msf::Exploit::Remote::HttpClient def initialize super( @@ -17,18 +17,15 @@ class Metasploit3 < Msf::Auxiliary ) register_options( [ - OptString.new('CTRL_URL', [ true, 'UPnP Control URL']), - OptString.new('INTERNAL_CLIENT', [ true, 'New Internal Client']), - OptInt.new('INTERNAL_PORT', [ true, 'New Internal Port']), - OptInt.new('EXTERNAL_PORT', [ true, 'New External Port']) + OptString.new('TARGETURI',[true, 'UPnP control URL', '/' ]), + OptString.new('INTERNAL_CLIENT', [true, 'New Internal Client']), + OptInt.new('INTERNAL_PORT', [true, 'New Internal Port']), + OptInt.new('EXTERNAL_PORT', [true, 'New External Port']) ], self.class ) end - def run - ctrlurl = datastore['CTRL_URL'] - soapaction = "urn:schemas-upnp-org:service:WANIPConnection:1#AddPortMapping" content = "" content << "" @@ -45,26 +42,26 @@ class Metasploit3 < Msf::Auxiliary content << "" content << "" content << "" + res = send_request_cgi( + { + 'uri' => normalize_uri(target_uri.path), + 'method' => 'POST', + 'content-type' => 'text/xml;charset="utf-8"', + 'headers' => { + 'SoapAction' => 'urn:schemas-upnp-org:service:WANIPConnection:1#AddPortMapping' + }, + 'data' => content + } + ) - contentlen = content.length - - header = "POST http://#{rhost}:#{rport}/#{ctrlurl} HTTP/1.0\r\n" - header << "Content-Type: text/xml;charset=\"utf-8\"\r\n" - header << "SOAPAction: #{soapaction}\n\r" - header << "User-Agent: SOAP AddPortMapping Metasploit Module\r\n" - header << "Host: #{rhost}:#{rport}\r\n" - header << "Content-Length: #{contentlen}\r\n" - header << "\r\n" - header << content - - print_status("Sending SOAP Request") - connect - sock.puts(header) - resp = sock.recv(1024) - if resp.include? "200 OK" - print_good("PAT added successfully") + if res + if res.code == 200 + print_good("#{peer} successfully mapped") + else + print_error("#{peer} failed to map #{res}") + end else - print_error("Fail") + print_error("#{peer} no response") end end end From 45fde928fc08276392253e537a0dcd7c373248b3 Mon Sep 17 00:00:00 2001 From: Jon Hart Date: Fri, 28 Aug 2015 14:49:57 -0700 Subject: [PATCH 08/24] More minor style cleanup --- .../admin/upnp/soap_addportmapping.rb | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/modules/auxiliary/admin/upnp/soap_addportmapping.rb b/modules/auxiliary/admin/upnp/soap_addportmapping.rb index 89b9dc8703..88747386b5 100644 --- a/modules/auxiliary/admin/upnp/soap_addportmapping.rb +++ b/modules/auxiliary/admin/upnp/soap_addportmapping.rb @@ -17,7 +17,7 @@ class Metasploit3 < Msf::Auxiliary ) register_options( [ - OptString.new('TARGETURI',[true, 'UPnP control URL', '/' ]), + OptString.new('TARGETURI', [true, 'UPnP control URL', '/' ]), OptString.new('INTERNAL_CLIENT', [true, 'New Internal Client']), OptInt.new('INTERNAL_PORT', [true, 'New Internal Port']), OptInt.new('EXTERNAL_PORT', [true, 'New External Port']) @@ -25,8 +25,8 @@ class Metasploit3 < Msf::Auxiliary self.class ) end - def run + def run content = "" content << "" content << "" @@ -43,14 +43,12 @@ class Metasploit3 < Msf::Auxiliary content << "" content << "" res = send_request_cgi( - { - 'uri' => normalize_uri(target_uri.path), - 'method' => 'POST', - 'content-type' => 'text/xml;charset="utf-8"', - 'headers' => { - 'SoapAction' => 'urn:schemas-upnp-org:service:WANIPConnection:1#AddPortMapping' - }, - 'data' => content + 'uri' => normalize_uri(target_uri.path), + 'method' => 'POST', + 'content-type' => 'text/xml;charset="utf-8"', + 'data' => content, + 'headers' => { + 'SoapAction' => 'urn:schemas-upnp-org:service:WANIPConnection:1#AddPortMapping' } ) From 840be716831896ae34df8d17d06a32711e73c52d Mon Sep 17 00:00:00 2001 From: Jon Hart Date: Fri, 28 Aug 2015 14:53:41 -0700 Subject: [PATCH 09/24] Add support for specifying protocol UDP is fun too. Are there others? --- modules/auxiliary/admin/upnp/soap_addportmapping.rb | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/modules/auxiliary/admin/upnp/soap_addportmapping.rb b/modules/auxiliary/admin/upnp/soap_addportmapping.rb index 88747386b5..2270ae77b0 100644 --- a/modules/auxiliary/admin/upnp/soap_addportmapping.rb +++ b/modules/auxiliary/admin/upnp/soap_addportmapping.rb @@ -19,6 +19,7 @@ class Metasploit3 < Msf::Auxiliary [ OptString.new('TARGETURI', [true, 'UPnP control URL', '/' ]), OptString.new('INTERNAL_CLIENT', [true, 'New Internal Client']), + OptEnum.new('PROTOCOL', [true, 'Transport level protocol to map', 'TCP', %w(TCP UDP)]), OptInt.new('INTERNAL_PORT', [true, 'New Internal Port']), OptInt.new('EXTERNAL_PORT', [true, 'New External Port']) ], @@ -26,6 +27,10 @@ class Metasploit3 < Msf::Auxiliary ) end + def setup + @protocol = datastore['PROTOCOL'] + end + def run content = "" content << "" @@ -37,7 +42,7 @@ class Metasploit3 < Msf::Auxiliary content << "1" content << "#{datastore['EXTERNAL_PORT']}" content << "" - content << "TCP" + content << "#{@protocol}" content << "#{datastore['INTERNAL_PORT']}" content << "" content << "" From d57041136fe6d272d68be78ed84c71458c8cfc52 Mon Sep 17 00:00:00 2001 From: Jon Hart Date: Fri, 28 Aug 2015 15:09:58 -0700 Subject: [PATCH 10/24] Use random port mapping description --- modules/auxiliary/admin/upnp/soap_addportmapping.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/auxiliary/admin/upnp/soap_addportmapping.rb b/modules/auxiliary/admin/upnp/soap_addportmapping.rb index 2270ae77b0..0e79573807 100644 --- a/modules/auxiliary/admin/upnp/soap_addportmapping.rb +++ b/modules/auxiliary/admin/upnp/soap_addportmapping.rb @@ -5,6 +5,7 @@ ## require 'msf/core' + class Metasploit3 < Msf::Auxiliary include Msf::Exploit::Remote::HttpClient @@ -36,7 +37,7 @@ class Metasploit3 < Msf::Auxiliary content << "" content << "" content << "" - content << "New Port Mapping" + content << "#{Rex::Text.rand_text_alpha(8)}" content << "3600" content << "#{datastore['INTERNAL_CLIENT']}" content << "1" From 13dd8222ecf190309d004980507c275e649eeb3c Mon Sep 17 00:00:00 2001 From: Jon Hart Date: Fri, 28 Aug 2015 15:22:19 -0700 Subject: [PATCH 11/24] Expose lease duration as an option --- modules/auxiliary/admin/upnp/soap_addportmapping.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/auxiliary/admin/upnp/soap_addportmapping.rb b/modules/auxiliary/admin/upnp/soap_addportmapping.rb index 0e79573807..0ec0205ec6 100644 --- a/modules/auxiliary/admin/upnp/soap_addportmapping.rb +++ b/modules/auxiliary/admin/upnp/soap_addportmapping.rb @@ -22,14 +22,14 @@ class Metasploit3 < Msf::Auxiliary OptString.new('INTERNAL_CLIENT', [true, 'New Internal Client']), OptEnum.new('PROTOCOL', [true, 'Transport level protocol to map', 'TCP', %w(TCP UDP)]), OptInt.new('INTERNAL_PORT', [true, 'New Internal Port']), - OptInt.new('EXTERNAL_PORT', [true, 'New External Port']) + OptInt.new('EXTERNAL_PORT', [true, 'New External Port']), + OptInt.new('LEASE_DURATION', [true, 'Lease time for mapping, in seconds', 3600]) ], self.class ) end def setup - @protocol = datastore['PROTOCOL'] end def run @@ -38,12 +38,12 @@ class Metasploit3 < Msf::Auxiliary content << "" content << "" content << "#{Rex::Text.rand_text_alpha(8)}" - content << "3600" + content << "#{datastore['LEASE_DURATION']}" content << "#{datastore['INTERNAL_CLIENT']}" content << "1" content << "#{datastore['EXTERNAL_PORT']}" content << "" - content << "#{@protocol}" + content << "#{datastore['PROTOCOL']}" content << "#{datastore['INTERNAL_PORT']}" content << "" content << "" From 35555f5f24a7a50462eab1dd950293d071686369 Mon Sep 17 00:00:00 2001 From: Jon Hart Date: Fri, 28 Aug 2015 15:36:49 -0700 Subject: [PATCH 12/24] Make most everything configurable and provide useful output --- .../admin/upnp/soap_addportmapping.rb | 46 ++++++++++++++----- 1 file changed, 35 insertions(+), 11 deletions(-) diff --git a/modules/auxiliary/admin/upnp/soap_addportmapping.rb b/modules/auxiliary/admin/upnp/soap_addportmapping.rb index 0ec0205ec6..d8bfebc4ef 100644 --- a/modules/auxiliary/admin/upnp/soap_addportmapping.rb +++ b/modules/auxiliary/admin/upnp/soap_addportmapping.rb @@ -19,7 +19,8 @@ class Metasploit3 < Msf::Auxiliary register_options( [ OptString.new('TARGETURI', [true, 'UPnP control URL', '/' ]), - OptString.new('INTERNAL_CLIENT', [true, 'New Internal Client']), + OptString.new('INTERNAL_IP', [false, 'New Internal Client']), + OptString.new('EXTERNAL_IP', [false, 'New Internal Client']), OptEnum.new('PROTOCOL', [true, 'Transport level protocol to map', 'TCP', %w(TCP UDP)]), OptInt.new('INTERNAL_PORT', [true, 'New Internal Port']), OptInt.new('EXTERNAL_PORT', [true, 'New External Port']), @@ -29,7 +30,28 @@ class Metasploit3 < Msf::Auxiliary ) end - def setup + def internal_port + @internal_port ||= datastore['INTERNAL_PORT'] + end + + def internal_ip + @internal_ip ||= datastore['INTERNAL_IP'] + end + + def external_port + @external_port ||= datastore['EXTERNAL_PORT'] + end + + def external_ip + @external_ip ||= datastore['EXTERNAL_IP'] + end + + def lease_duration + @lease_duration ||= datastore['LEASE_DURATION'] + end + + def protocol + @protocol ||= datastore['PROTOCOL'] end def run @@ -38,13 +60,13 @@ class Metasploit3 < Msf::Auxiliary content << "" content << "" content << "#{Rex::Text.rand_text_alpha(8)}" - content << "#{datastore['LEASE_DURATION']}" - content << "#{datastore['INTERNAL_CLIENT']}" + content << "#{lease_duration}" + content << "#{internal_ip}" content << "1" - content << "#{datastore['EXTERNAL_PORT']}" - content << "" - content << "#{datastore['PROTOCOL']}" - content << "#{datastore['INTERNAL_PORT']}" + content << "#{external_port}" + content << "#{external_ip}" + content << "#{protocol}" + content << "#{internal_port}" content << "" content << "" content << "" @@ -59,13 +81,15 @@ class Metasploit3 < Msf::Auxiliary ) if res + map_target = Rex::Socket.source_address(rhost) + map = "#{rhost}:#{external_port}/#{protocol} -> #{internal_ip}:#{internal_port}/#{protocol}" if res.code == 200 - print_good("#{peer} successfully mapped") + print_good("#{peer} successfully mapped #{map}") else - print_error("#{peer} failed to map #{res}") + print_error("#{peer} failed to map #{map}: #{res}") end else - print_error("#{peer} no response") + print_error("#{peer} no response for mapping #{map}") end end end From 66616eeb958f52b37f656c2a0366f802c962727d Mon Sep 17 00:00:00 2001 From: Jon Hart Date: Fri, 28 Aug 2015 15:38:23 -0700 Subject: [PATCH 13/24] Remove unused --- modules/auxiliary/admin/upnp/soap_addportmapping.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/auxiliary/admin/upnp/soap_addportmapping.rb b/modules/auxiliary/admin/upnp/soap_addportmapping.rb index d8bfebc4ef..681c978987 100644 --- a/modules/auxiliary/admin/upnp/soap_addportmapping.rb +++ b/modules/auxiliary/admin/upnp/soap_addportmapping.rb @@ -81,7 +81,6 @@ class Metasploit3 < Msf::Auxiliary ) if res - map_target = Rex::Socket.source_address(rhost) map = "#{rhost}:#{external_port}/#{protocol} -> #{internal_ip}:#{internal_port}/#{protocol}" if res.code == 200 print_good("#{peer} successfully mapped #{map}") From e6e05814d062fc50f905b8e3b1a1912997d01238 Mon Sep 17 00:00:00 2001 From: Jon Hart Date: Fri, 28 Aug 2015 15:43:04 -0700 Subject: [PATCH 14/24] Use an OptAddress instead, revert back to client name --- .../admin/upnp/soap_addportmapping.rb | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/modules/auxiliary/admin/upnp/soap_addportmapping.rb b/modules/auxiliary/admin/upnp/soap_addportmapping.rb index 681c978987..d8ac917a2f 100644 --- a/modules/auxiliary/admin/upnp/soap_addportmapping.rb +++ b/modules/auxiliary/admin/upnp/soap_addportmapping.rb @@ -19,11 +19,11 @@ class Metasploit3 < Msf::Auxiliary register_options( [ OptString.new('TARGETURI', [true, 'UPnP control URL', '/' ]), - OptString.new('INTERNAL_IP', [false, 'New Internal Client']), - OptString.new('EXTERNAL_IP', [false, 'New Internal Client']), + OptAddress.new('INTERNAL_CLIENT', [false, 'Internal client hostname/IP']), + 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', [true, 'New Internal Port']), - OptInt.new('EXTERNAL_PORT', [true, 'New External Port']), + OptInt.new('INTERNAL_PORT', [true, 'Internal port']), + OptInt.new('EXTERNAL_PORT', [true, 'External port']), OptInt.new('LEASE_DURATION', [true, 'Lease time for mapping, in seconds', 3600]) ], self.class @@ -34,16 +34,16 @@ class Metasploit3 < Msf::Auxiliary @internal_port ||= datastore['INTERNAL_PORT'] end - def internal_ip - @internal_ip ||= datastore['INTERNAL_IP'] + def internal_client + @internal_client ||= datastore['INTERNAL_CLIENT'] end def external_port @external_port ||= datastore['EXTERNAL_PORT'] end - def external_ip - @external_ip ||= datastore['EXTERNAL_IP'] + def external_client + @external_client ||= datastore['EXTERNAL_CLIENT'] end def lease_duration @@ -61,10 +61,10 @@ class Metasploit3 < Msf::Auxiliary content << "" content << "#{Rex::Text.rand_text_alpha(8)}" content << "#{lease_duration}" - content << "#{internal_ip}" + content << "#{internal_client}" content << "1" content << "#{external_port}" - content << "#{external_ip}" + content << "#{external_client}" content << "#{protocol}" content << "#{internal_port}" content << "" @@ -81,7 +81,7 @@ class Metasploit3 < Msf::Auxiliary ) if res - map = "#{rhost}:#{external_port}/#{protocol} -> #{internal_ip}:#{internal_port}/#{protocol}" + map = "#{rhost}:#{external_port}/#{protocol} -> #{internal_client}:#{internal_port}/#{protocol}" if res.code == 200 print_good("#{peer} successfully mapped #{map}") else From 436910b25f14323c26a2423aeb8d63c96b76a145 Mon Sep 17 00:00:00 2001 From: Jon Hart Date: Fri, 28 Aug 2015 15:49:29 -0700 Subject: [PATCH 15/24] Clean up map description --- modules/auxiliary/admin/upnp/soap_addportmapping.rb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/modules/auxiliary/admin/upnp/soap_addportmapping.rb b/modules/auxiliary/admin/upnp/soap_addportmapping.rb index d8ac917a2f..43024774fa 100644 --- a/modules/auxiliary/admin/upnp/soap_addportmapping.rb +++ b/modules/auxiliary/admin/upnp/soap_addportmapping.rb @@ -70,6 +70,7 @@ class Metasploit3 < Msf::Auxiliary content << "" content << "" content << "" + res = send_request_cgi( 'uri' => normalize_uri(target_uri.path), 'method' => 'POST', @@ -81,7 +82,9 @@ class Metasploit3 < Msf::Auxiliary ) if res - map = "#{rhost}:#{external_port}/#{protocol} -> #{internal_client}:#{internal_port}/#{protocol}" + 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}" if res.code == 200 print_good("#{peer} successfully mapped #{map}") else From 86651346910dcc7029a40be4d46a7fc7cc26c52c Mon Sep 17 00:00:00 2001 From: Jon Hart Date: Mon, 31 Aug 2015 10:22:36 -0700 Subject: [PATCH 16/24] Add add/delete action. update logging. rename module again --- ..._addportmapping.rb => soap_portmapping.rb} | 65 ++++++++++++++----- 1 file changed, 47 insertions(+), 18 deletions(-) rename modules/auxiliary/admin/upnp/{soap_addportmapping.rb => soap_portmapping.rb} (51%) diff --git a/modules/auxiliary/admin/upnp/soap_addportmapping.rb b/modules/auxiliary/admin/upnp/soap_portmapping.rb similarity index 51% rename from modules/auxiliary/admin/upnp/soap_addportmapping.rb rename to modules/auxiliary/admin/upnp/soap_portmapping.rb index 43024774fa..634c7a95ea 100644 --- a/modules/auxiliary/admin/upnp/soap_addportmapping.rb +++ b/modules/auxiliary/admin/upnp/soap_portmapping.rb @@ -14,8 +14,25 @@ class Metasploit3 < Msf::Auxiliary 'Name' => 'UPnP AddPortMapping', 'Description' => 'UPnP AddPortMapping SOAP request', 'Author' => 'St0rn ', - 'License' => MSF_LICENSE + 'License' => MSF_LICENSE, + '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' + } + ] + ], + 'DefaultAction' => 'ADD' ) + register_options( [ OptString.new('TARGETURI', [true, 'UPnP control URL', '/' ]), @@ -54,20 +71,31 @@ class Metasploit3 < Msf::Auxiliary @protocol ||= datastore['PROTOCOL'] end + def soap_action + @soap_action ||= action.opts['SOAP_ACTION'] + end + def run content = "" content << "" content << "" - content << "" - content << "#{Rex::Text.rand_text_alpha(8)}" - content << "#{lease_duration}" - content << "#{internal_client}" - content << "1" - content << "#{external_port}" - content << "#{external_client}" - content << "#{protocol}" - content << "#{internal_port}" - content << "" + content << "" + case action.name + when 'ADD' + content << "#{Rex::Text.rand_text_alpha(8)}" + content << "#{lease_duration}" + content << "#{internal_client}" + content << "1" + content << "#{external_port}" + content << "#{external_client}" + content << "#{protocol}" + content << "#{internal_port}" + when 'DELETE' + content << "#{external_port}" + content << "#{external_client}" + content << "#{protocol}" + end + content << "" content << "" content << "" @@ -77,21 +105,22 @@ class Metasploit3 < Msf::Auxiliary 'content-type' => 'text/xml;charset="utf-8"', 'data' => content, 'headers' => { - 'SoapAction' => 'urn:schemas-upnp-org:service:WANIPConnection:1#AddPortMapping' + 'SoapAction' => "urn:schemas-upnp-org:service:WANIPConnection:1##{soap_action}" } ) + 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}" + if res - 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}" if res.code == 200 - print_good("#{peer} successfully mapped #{map}") + print_good("#{peer} #{map} #{action.name} succeeded") else - print_error("#{peer} failed to map #{map}: #{res}") + print_error("#{peer} #{map} #{action.name} failed: #{res}") end else - print_error("#{peer} no response for mapping #{map}") + print_error("#{peer} no response for #{map} #{action.name}") end end end From 44813370d54c5a73c5c6a8ad8a79d85773f5b446 Mon Sep 17 00:00:00 2001 From: Jon Hart Date: Mon, 31 Aug 2015 10:42:50 -0700 Subject: [PATCH 17/24] Better name, description and author --- modules/auxiliary/admin/upnp/soap_portmapping.rb | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/modules/auxiliary/admin/upnp/soap_portmapping.rb b/modules/auxiliary/admin/upnp/soap_portmapping.rb index 634c7a95ea..d9177f9ca0 100644 --- a/modules/auxiliary/admin/upnp/soap_portmapping.rb +++ b/modules/auxiliary/admin/upnp/soap_portmapping.rb @@ -11,10 +11,15 @@ class Metasploit3 < Msf::Auxiliary def initialize super( - 'Name' => 'UPnP AddPortMapping', - 'Description' => 'UPnP AddPortMapping SOAP request', - 'Author' => 'St0rn ', + 'Name' => 'UPnP IGD SOAP Port Mapping Utility', + 'Description' => 'Manage port mappings on UPnP IGD-capable device using the AddPortMapping and DeletePortMapping SOAP requests', + 'Author' => + [ + 'St0rn ', # initial module + 'Jon Hart ' # module cleanup and refactoring + ], 'License' => MSF_LICENSE, + 'DefaultAction' => 'ADD', 'Actions' => [ [ 'ADD', @@ -30,7 +35,6 @@ class Metasploit3 < Msf::Auxiliary } ] ], - 'DefaultAction' => 'ADD' ) register_options( From c14cae14253da70374358b8d115d34dd53bb8e05 Mon Sep 17 00:00:00 2001 From: Jon Hart Date: Mon, 31 Aug 2015 11:30:18 -0700 Subject: [PATCH 18/24] Make INTERNAL_PORT optional, allowing DELETE to work --- modules/auxiliary/admin/upnp/soap_portmapping.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/auxiliary/admin/upnp/soap_portmapping.rb b/modules/auxiliary/admin/upnp/soap_portmapping.rb index d9177f9ca0..e9fc66c080 100644 --- a/modules/auxiliary/admin/upnp/soap_portmapping.rb +++ b/modules/auxiliary/admin/upnp/soap_portmapping.rb @@ -43,7 +43,7 @@ class Metasploit3 < Msf::Auxiliary OptAddress.new('INTERNAL_CLIENT', [false, 'Internal client hostname/IP']), 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', [true, 'Internal port']), + OptInt.new('INTERNAL_PORT', [false, 'Internal port']), OptInt.new('EXTERNAL_PORT', [true, 'External port']), OptInt.new('LEASE_DURATION', [true, 'Lease time for mapping, in seconds', 3600]) ], From 9a2696aed4b36a6a4b0ec8c1062377f8373224d4 Mon Sep 17 00:00:00 2001 From: Jon Hart Date: Mon, 31 Aug 2015 12:03:17 -0700 Subject: [PATCH 19/24] Add Reference --- modules/auxiliary/admin/upnp/soap_portmapping.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/auxiliary/admin/upnp/soap_portmapping.rb b/modules/auxiliary/admin/upnp/soap_portmapping.rb index e9fc66c080..001934246f 100644 --- a/modules/auxiliary/admin/upnp/soap_portmapping.rb +++ b/modules/auxiliary/admin/upnp/soap_portmapping.rb @@ -19,6 +19,7 @@ class Metasploit3 < Msf::Auxiliary 'Jon Hart ' # module cleanup and refactoring ], 'License' => MSF_LICENSE, + 'References' => [['URL', 'http://www.upnp-hacks.org/igd.html']], 'DefaultAction' => 'ADD', 'Actions' => [ From 0113cbd353b6fdd7a8c28f919cf14490a8abfa47 Mon Sep 17 00:00:00 2001 From: Jon Hart Date: Wed, 16 Sep 2015 19:53:33 -0700 Subject: [PATCH 20/24] Nokogiri::XML::Builder instead --- .../auxiliary/admin/upnp/soap_portmapping.rb | 51 ++++++++++--------- 1 file changed, 28 insertions(+), 23 deletions(-) diff --git a/modules/auxiliary/admin/upnp/soap_portmapping.rb b/modules/auxiliary/admin/upnp/soap_portmapping.rb index 001934246f..c6c628c592 100644 --- a/modules/auxiliary/admin/upnp/soap_portmapping.rb +++ b/modules/auxiliary/admin/upnp/soap_portmapping.rb @@ -5,6 +5,7 @@ ## require 'msf/core' +require 'nokogiri' class Metasploit3 < Msf::Auxiliary include Msf::Exploit::Remote::HttpClient @@ -80,35 +81,39 @@ class Metasploit3 < Msf::Auxiliary @soap_action ||= action.opts['SOAP_ACTION'] end - def run - content = "" - content << "" - content << "" - content << "" - case action.name - when 'ADD' - content << "#{Rex::Text.rand_text_alpha(8)}" - content << "#{lease_duration}" - content << "#{internal_client}" - content << "1" - content << "#{external_port}" - content << "#{external_client}" - content << "#{protocol}" - content << "#{internal_port}" - when 'DELETE' - content << "#{external_port}" - content << "#{external_client}" - content << "#{protocol}" + def build_soap + builder = ::Nokogiri::XML::Builder.new do |xml| + xml['SOAP-ENV'].Envelope("xmlns:SOAP-ENV" => 'http://schemas.xmlsoap.org/soap/envelope', 'SOAP-ENV:encodingStyle' => 'http://schemas.xmlsoap.org/soap/encoding/') do + 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 - content << "" - content << "" - content << "" + builder.to_xml + end + def run res = send_request_cgi( 'uri' => normalize_uri(target_uri.path), 'method' => 'POST', 'content-type' => 'text/xml;charset="utf-8"', - 'data' => content, + 'data' => build_soap, 'headers' => { 'SoapAction' => "urn:schemas-upnp-org:service:WANIPConnection:1##{soap_action}" } From a5698ebce00c30b22c4ea8a4a31246ec74d86107 Mon Sep 17 00:00:00 2001 From: jvazquez-r7 Date: Fri, 25 Sep 2015 13:34:16 -0500 Subject: [PATCH 21/24] Fix metadata --- modules/auxiliary/admin/upnp/soap_portmapping.rb | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/modules/auxiliary/admin/upnp/soap_portmapping.rb b/modules/auxiliary/admin/upnp/soap_portmapping.rb index c6c628c592..1c2f2113e4 100644 --- a/modules/auxiliary/admin/upnp/soap_portmapping.rb +++ b/modules/auxiliary/admin/upnp/soap_portmapping.rb @@ -13,7 +13,10 @@ class Metasploit3 < Msf::Auxiliary def initialize super( 'Name' => 'UPnP IGD SOAP Port Mapping Utility', - 'Description' => 'Manage port mappings on UPnP IGD-capable device using the AddPortMapping and DeletePortMapping SOAP requests', + 'Description' => %q{ + Manage port mappings on UPnP IGD-capable device using the AddPortMapping and + DeletePortMapping SOAP requests + }, 'Author' => [ 'St0rn ', # initial module @@ -43,11 +46,11 @@ class Metasploit3 < Msf::Auxiliary [ OptString.new('TARGETURI', [true, 'UPnP control URL', '/' ]), OptAddress.new('INTERNAL_CLIENT', [false, 'Internal client hostname/IP']), - OptAddress.new('EXTERNAL_CLIENT', [false, 'External client hostname/IP']), + OptAddress.new('EXTERNAL_CLIENT', [true, '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']), - OptInt.new('LEASE_DURATION', [true, 'Lease time for mapping, in seconds', 3600]) + OptInt.new('LEASE_DURATION', [false, 'Lease time for mapping, in seconds', 3600]) ], self.class ) From e4e9609bc2de6c4f7bc1614d49e17f8598fd75bf Mon Sep 17 00:00:00 2001 From: jvazquez-r7 Date: Fri, 25 Sep 2015 13:35:38 -0500 Subject: [PATCH 22/24] Use single quotes --- modules/auxiliary/admin/upnp/soap_portmapping.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/auxiliary/admin/upnp/soap_portmapping.rb b/modules/auxiliary/admin/upnp/soap_portmapping.rb index 1c2f2113e4..9ce29428a7 100644 --- a/modules/auxiliary/admin/upnp/soap_portmapping.rb +++ b/modules/auxiliary/admin/upnp/soap_portmapping.rb @@ -86,7 +86,7 @@ class Metasploit3 < Msf::Auxiliary def build_soap builder = ::Nokogiri::XML::Builder.new do |xml| - xml['SOAP-ENV'].Envelope("xmlns:SOAP-ENV" => 'http://schemas.xmlsoap.org/soap/envelope', 'SOAP-ENV:encodingStyle' => 'http://schemas.xmlsoap.org/soap/encoding/') do + xml['SOAP-ENV'].Envelope('xmlns:SOAP-ENV' => 'http://schemas.xmlsoap.org/soap/envelope', 'SOAP-ENV:encodingStyle' => 'http://schemas.xmlsoap.org/soap/encoding/') do xml['SOAP-ENV'].Body do xml['m'].send(soap_action, 'xmlns:m' => 'urn:schemas-upnp-org:service:WANIPConnection:1') do case action.name From 80c9cd4e6fe7ca153c75a28e03b1687bf0ea3a00 Mon Sep 17 00:00:00 2001 From: jvazquez-r7 Date: Fri, 25 Sep 2015 13:41:27 -0500 Subject: [PATCH 23/24] Restore required option --- modules/auxiliary/admin/upnp/soap_portmapping.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/auxiliary/admin/upnp/soap_portmapping.rb b/modules/auxiliary/admin/upnp/soap_portmapping.rb index 9ce29428a7..38b958c2ab 100644 --- a/modules/auxiliary/admin/upnp/soap_portmapping.rb +++ b/modules/auxiliary/admin/upnp/soap_portmapping.rb @@ -46,7 +46,7 @@ class Metasploit3 < Msf::Auxiliary [ OptString.new('TARGETURI', [true, 'UPnP control URL', '/' ]), OptAddress.new('INTERNAL_CLIENT', [false, 'Internal client hostname/IP']), - OptAddress.new('EXTERNAL_CLIENT', [true, 'External client hostname/IP']), + 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']), From f6f3efea758b17cf04617501f196d9be417d786b Mon Sep 17 00:00:00 2001 From: jvazquez-r7 Date: Fri, 25 Sep 2015 13:51:18 -0500 Subject: [PATCH 24/24] print the body as verbose --- modules/auxiliary/admin/upnp/soap_portmapping.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/auxiliary/admin/upnp/soap_portmapping.rb b/modules/auxiliary/admin/upnp/soap_portmapping.rb index 38b958c2ab..4ddc743e52 100644 --- a/modules/auxiliary/admin/upnp/soap_portmapping.rb +++ b/modules/auxiliary/admin/upnp/soap_portmapping.rb @@ -130,7 +130,8 @@ class Metasploit3 < Msf::Auxiliary if res.code == 200 print_good("#{peer} #{map} #{action.name} succeeded") else - print_error("#{peer} #{map} #{action.name} failed: #{res}") + print_error("#{peer} #{map} #{action.name} failed with response code #{res.code}") + vprint_status("#{res.body}") end else print_error("#{peer} no response for #{map} #{action.name}")