CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/auxiliary/bnat/bnat_scan.rb
Views: 11779
1
##
2
# This module requires Metasploit: https://metasploit.com/download
3
# Current source: https://github.com/rapid7/metasploit-framework
4
##
5
6
class MetasploitModule < Msf::Auxiliary
7
include Msf::Auxiliary::Scanner
8
include Msf::Exploit::Capture
9
10
def initialize
11
super(
12
'Name' => 'BNAT Scanner',
13
'Description' => %q{
14
This module is a scanner which can detect Broken NAT (network address translation)
15
implementations, which could result in an inability to reach ports on remote
16
machines. Typically, these ports will appear in nmap scans as 'filtered'/'closed'.
17
},
18
'Author' =>
19
[
20
'bannedit',
21
'Jonathan Claudius <jclaudius[at]trustwave.com>',
22
],
23
'License' => MSF_LICENSE,
24
'References' =>
25
[
26
[ 'URL', 'https://github.com/claudijd/bnat'],
27
[ 'URL', 'http://www.slideshare.net/claudijd/dc-skytalk-bnat-hijacking-repairing-broken-communication-channels']
28
]
29
)
30
31
register_options(
32
[
33
OptString.new('PORTS', [true, "Ports to scan (e.g. 22-25,80,110-900)", "21,22,23,80,443"]),
34
OptString.new('INTERFACE', [true, "The name of the interface", "eth0"]),
35
OptInt.new('TIMEOUT', [true, "The reply read timeout in milliseconds", 500])
36
])
37
38
deregister_options('FILTER','PCAPFILE','SNAPLEN')
39
40
end
41
42
def probe_reply(pcap, to)
43
reply = nil
44
begin
45
Timeout.timeout(to) do
46
pcap.each do |r|
47
pkt = PacketFu::Packet.parse(r)
48
next unless pkt.is_tcp?
49
reply = pkt
50
break
51
end
52
end
53
rescue Timeout::Error
54
end
55
return reply
56
end
57
58
def generate_probe(ip)
59
ftypes = %w{windows, linux, freebsd}
60
@flavor = ftypes[rand(ftypes.length)]
61
config = PacketFu::Utils.whoami?(:iface => datastore['INTERFACE'])
62
p = PacketFu::TCPPacket.new(:config => config)
63
p.ip_daddr = ip
64
p.tcp_flags.syn = 1
65
return p
66
end
67
68
def run_host(ip)
69
open_pcap
70
71
to = (datastore['TIMEOUT'] || 500).to_f / 1000.0
72
73
p = generate_probe(ip)
74
pcap = self.capture
75
76
ports = Rex::Socket.portspec_crack(datastore['PORTS'])
77
78
if ports.empty?
79
raise Msf::OptionValidateError.new(['PORTS'])
80
end
81
82
ports.each_with_index do |port,i|
83
p.tcp_dst = port
84
p.tcp_src = rand(64511)+1024
85
p.tcp_seq = rand(64511)+1024
86
p.recalc
87
88
ackbpf = "tcp [8:4] == 0x#{(p.tcp_seq + 1).to_s(16)}"
89
pcap.setfilter("tcp and tcp[13] == 18 and not host #{ip} and src port #{p.tcp_dst} and dst port #{p.tcp_src} and #{ackbpf}")
90
break unless capture_sendto(p, ip)
91
reply = probe_reply(pcap, to)
92
next if reply.nil?
93
94
print_status("[BNAT RESPONSE] Requested IP: #{ip} Responding IP: #{reply.ip_saddr} Port: #{reply.tcp_src}")
95
end
96
97
close_pcap
98
end
99
end
100
101