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/natpmp/natpmp_map.rb
Views: 11783
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45class MetasploitModule < Msf::Auxiliary6include Msf::Auxiliary::Report7include Msf::Auxiliary::Scanner8include Msf::Auxiliary::NATPMP9include Rex::Proto::NATPMP1011def initialize12super(13'Name' => 'NAT-PMP Port Mapper',14'Description' => 'Map (forward) TCP and UDP ports on NAT devices using NAT-PMP',15'Author' => 'Jon Hart <jhart[at]spoofed.org>',16'License' => MSF_LICENSE17)1819register_options(20[21OptString.new('EXTERNAL_PORTS', [true, 'The external ports to forward from (0 to let the target choose)', 0]),22OptString.new('INTERNAL_PORTS', [true, 'The internal ports to forward to', '22,135-139,80,443,445'])23],24self.class25)26end2728def build_ports(ports_string)29# We don't use Rex::Socket.portspec_crack because we need to allow 0 and preserve order30ports = []31ports_string.split(/[ ,]/).map { |s| s.strip }.compact.each do |port_part|32if /^(?<port>\d+)$/ =~ port_part33ports << port.to_i34elsif /^(?<low>\d+)\s*-\s*(?<high>\d+)$/ =~ port_part35ports |= (low..high).to_a.map(&:to_i)36else37fail ArgumentError, "Invalid port specification #{port_part}"38end39end40ports41end4243def setup44super45@external_ports = build_ports(datastore['EXTERNAL_PORTS'])46@internal_ports = build_ports(datastore['INTERNAL_PORTS'])4748if @external_ports.size > @internal_ports.size49fail ArgumentError, "Too many external ports specified (#{@external_ports.size}); " +50"must be one port (0) or #{@internal_ports.size} ports"51end5253if @external_ports.size < @internal_ports.size54if @external_ports != [0]55fail ArgumentError, "Incorrect number of external ports specified (#{@external_ports.size}); " +56"must be one port (0) or #{@internal_ports.size} ports"57else58@external_ports = [0] * @internal_ports.size59end60end61end6263def run_host(host)64begin6566udp_sock = Rex::Socket::Udp.create({67'LocalHost' => datastore['CHOST'] || nil,68'Context' => {'Msf' => framework, 'MsfExploit' => self}69})70add_socket(udp_sock)7172external_address = get_external_address(udp_sock, host, datastore['RPORT']) || host7374@external_ports.each_index do |i|75external_port = @external_ports[i]76internal_port = @internal_ports[i]7778actual_ext_port = map_port(udp_sock, host, datastore['RPORT'], internal_port, external_port, Rex::Proto::NATPMP.const_get(protocol), lifetime)79map_target = Rex::Socket.source_address(host)80requested_forwarding = "#{external_address}:#{external_port}/#{protocol}" +81" -> " +82"#{map_target}:#{internal_port}/#{protocol}"83if actual_ext_port84map_target = datastore['CHOST'] ? datastore['CHOST'] : Rex::Socket.source_address(host)85actual_forwarding = "#{external_address}:#{actual_ext_port}/#{protocol}" +86" -> " +87"#{map_target}:#{internal_port}/#{protocol}"88if external_port == 089print_good("#{actual_forwarding} forwarded")90else91if (external_port != 0 && external_port != actual_ext_port)92print_good("#{requested_forwarding} could not be forwarded, but #{actual_forwarding} could")93else94print_good("#{requested_forwarding} forwarded")95end96end97else98print_error("#{requested_forwarding} could not be forwarded")99end100101report_service(102:host => host,103:port => datastore['RPORT'],104:proto => 'udp',105:name => 'natpmp',106:state => Msf::ServiceState::Open107)108end109rescue ::Interrupt110raise $!111rescue ::Rex::HostUnreachable, ::Rex::ConnectionTimeout, ::Rex::ConnectionRefused112nil113rescue ::Exception => e114print_error("Unknown error: #{e.class} #{e.backtrace}")115end116end117end118119120