2012-01-24 16:16:56 +00:00
|
|
|
require 'msf/core'
|
|
|
|
require 'rex/proto/natpmp'
|
|
|
|
|
|
|
|
class Metasploit3 < Msf::Auxiliary
|
|
|
|
|
|
|
|
include Msf::Auxiliary::Report
|
|
|
|
include Msf::Auxiliary::Scanner
|
|
|
|
|
|
|
|
def initialize
|
|
|
|
super(
|
2012-02-08 18:23:46 +00:00
|
|
|
'Name' => 'NAT-PMP External Address Scanner',
|
2012-01-24 16:16:56 +00:00
|
|
|
'Description' => 'Scan NAT devices for their external address using NAT-PMP',
|
2012-01-25 19:02:39 +00:00
|
|
|
'Author' => 'Jon Hart <jhart[at]spoofed.org>',
|
2012-01-24 16:16:56 +00:00
|
|
|
'License' => MSF_LICENSE
|
|
|
|
)
|
|
|
|
|
|
|
|
register_options(
|
|
|
|
[
|
|
|
|
Opt::RPORT(Rex::Proto::NATPMP::DefaultPort),
|
|
|
|
Opt::CHOST
|
|
|
|
],
|
|
|
|
self.class
|
|
|
|
)
|
|
|
|
end
|
|
|
|
|
|
|
|
def run_host(host)
|
|
|
|
begin
|
2012-02-08 18:23:46 +00:00
|
|
|
udp_sock = Rex::Socket::Udp.create({
|
|
|
|
'LocalHost' => datastore['CHOST'] || nil,
|
|
|
|
'Context' => {'Msf' => framework, 'MsfExploit' => self}
|
2012-01-24 16:16:56 +00:00
|
|
|
})
|
|
|
|
add_socket(udp_sock)
|
|
|
|
print_status "#{host}:#{datastore['RPORT']} - NATPMP - Probing for external address" if (datastore['VERBOSE'])
|
|
|
|
|
|
|
|
udp_sock.sendto(Rex::Proto::NATPMP.external_address_request, host, datastore['RPORT'].to_i, 0)
|
2012-02-08 18:23:46 +00:00
|
|
|
while (r = udp_sock.recvfrom(12, 1.0) and r[1])
|
2012-01-24 16:16:56 +00:00
|
|
|
handle_reply(host, r)
|
|
|
|
end
|
|
|
|
rescue ::Interrupt
|
|
|
|
raise $!
|
|
|
|
rescue ::Rex::HostUnreachable, ::Rex::ConnectionTimeout, ::Rex::ConnectionRefused
|
|
|
|
nil
|
|
|
|
rescue ::Exception => e
|
2012-02-08 18:23:46 +00:00
|
|
|
print_error("#{host}:#{datastore['RPORT']} Unknown error: #{e.class} #{e}")
|
2012-01-24 16:16:56 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def handle_reply(host, pkt)
|
|
|
|
return if not pkt[1]
|
|
|
|
|
|
|
|
if(pkt[1] =~ /^::ffff:/)
|
|
|
|
pkt[1] = pkt[1].sub(/^::ffff:/, '')
|
|
|
|
end
|
|
|
|
|
|
|
|
(ver, op, result, epoch, external_address) = Rex::Proto::NATPMP.parse_external_address_response(pkt[0])
|
|
|
|
|
|
|
|
if (result == 0)
|
|
|
|
print_status("#{host} -- external address #{external_address}")
|
|
|
|
end
|
|
|
|
|
|
|
|
# report the host we scanned as alive
|
|
|
|
report_host(
|
|
|
|
:host => host,
|
|
|
|
:state => Msf::HostState::Alive
|
|
|
|
)
|
|
|
|
|
|
|
|
# also report its external address as alive
|
2012-02-08 18:23:46 +00:00
|
|
|
if inside_workspace_boundary(external_address)
|
|
|
|
report_host(
|
|
|
|
:host => external_address,
|
|
|
|
:state => Msf::HostState::Alive
|
|
|
|
)
|
|
|
|
end
|
2012-01-24 16:16:56 +00:00
|
|
|
|
|
|
|
# report NAT-PMP as being open
|
|
|
|
report_service(
|
|
|
|
:host => host,
|
|
|
|
:port => pkt[2],
|
|
|
|
:proto => 'udp',
|
2012-02-08 18:23:46 +00:00
|
|
|
:name => 'natpmp',
|
|
|
|
:state => Msf::ServiceState::Open
|
2012-01-24 16:16:56 +00:00
|
|
|
)
|
|
|
|
end
|
|
|
|
end
|