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/scanner/natpmp/natpmp_portscan.rb
Views: 11784
##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 External Port Scanner',14'Description' => 'Scan NAT devices for their external listening ports using NAT-PMP',15'Author' => 'Jon Hart <jhart[at]spoofed.org>',16'License' => MSF_LICENSE17)1819register_options(20[21OptString.new('PORTS', [true, "Ports to scan (e.g. 22-25,80,110-900)", "1-1000"])22])23end2425def run_host(host)26begin27udp_sock = Rex::Socket::Udp.create({28'LocalHost' => datastore['CHOST'] || nil,29'Context' => {'Msf' => framework, 'MsfExploit' => self} }30)31add_socket(udp_sock)32peer = "#{host}:#{datastore['RPORT']}"33vprint_status("#{peer} Scanning #{protocol} ports #{datastore['PORTS']} using NATPMP")3435external_address = get_external_address(udp_sock, host, datastore['RPORT'])36if (external_address)37print_good("#{peer} responded with external address of #{external_address}")38else39vprint_status("#{peer} didn't respond with an external address")40return41end4243# clear all mappings44map_port(udp_sock, host, datastore['RPORT'], 0, 0, Rex::Proto::NATPMP.const_get(protocol), 0)4546Rex::Socket.portspec_crack(datastore['PORTS']).each do |port|47map_req = map_port_request(port, port, Rex::Proto::NATPMP.const_get(datastore['PROTOCOL']), 1)48udp_sock.sendto(map_req, host, datastore['RPORT'], 0)49while (r = udp_sock.recvfrom(16, 1.0) and r[1])50break if handle_reply(host, external_address, r)51end52end5354rescue ::Interrupt55raise $!56rescue ::Rex::HostUnreachable, ::Rex::ConnectionTimeout, ::Rex::ConnectionRefused57nil58rescue ::Exception => e59print_error("Unknown error: #{e.class} #{e.backtrace}")60end61end6263def handle_reply(host, external_addr, pkt)64return if not pkt[1]6566if(pkt[1] =~ /^::ffff:/)67pkt[1] = pkt[1].sub(/^::ffff:/, '')68end69host = pkt[1]70protocol = datastore['PROTOCOL'].to_s.downcase7172(ver, op, result, epoch, int, ext, lifetime) = parse_map_port_response(pkt[0])73peer = "#{host}:#{datastore['RPORT']}"74if (result == 0)75# we always ask to map an external port to the same port on us. If76# we get a successful response back but the port we requested be forwarded77# is different, that means that someone else already has it open78if (int != ext)79state = Msf::ServiceState::Open80print_good("#{peer} #{external_addr} - #{int}/#{protocol} #{state} because of successful mapping with unmatched ports")81if inside_workspace_boundary?(external_addr)82report_service(83:host => external_addr,84:port => int,85:proto => protocol,86:state => state87)88end89else90state = Msf::ServiceState::Closed91vprint_error("#{peer} #{external_addr} - #{int}/#{protocol} #{state} because of successful mapping with matched ports")92end93else94state = Msf::ServiceState::Closed95vprint_error("#{peer} #{external_addr} - #{int}/#{protocol} #{state} because of code #{result} response")96end9798report_service(99:host => host,100:port => pkt[2],101:name => 'natpmp',102:proto => 'udp',103:state => Msf::ServiceState::Open104)105true106end107end108109110