Path: blob/master/modules/auxiliary/bnat/bnat_scan.rb
19535 views
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45class MetasploitModule < Msf::Auxiliary6include Msf::Auxiliary::Scanner7include Msf::Exploit::Capture89def initialize10super(11'Name' => 'BNAT Scanner',12'Description' => %q{13This module is a scanner which can detect Broken NAT (network address translation)14implementations, which could result in an inability to reach ports on remote15machines. Typically, these ports will appear in nmap scans as 'filtered'/'closed'.16},17'Author' => [18'bannedit',19'Jonathan Claudius <jclaudius[at]trustwave.com>',20],21'License' => MSF_LICENSE,22'References' => [23['URL', 'https://github.com/claudijd/bnat'],24['URL', 'http://www.slideshare.net/claudijd/dc-skytalk-bnat-hijacking-repairing-broken-communication-channels']25]26)2728register_options(29[30OptString.new('PORTS', [true, 'Ports to scan (e.g. 22-25,80,110-900)', '21,22,23,80,443']),31OptString.new('INTERFACE', [true, 'The name of the interface', 'eth0']),32OptInt.new('TIMEOUT', [true, 'The reply read timeout in milliseconds', 500])33]34)3536deregister_options('FILTER', 'PCAPFILE', 'SNAPLEN')37end3839def probe_reply(pcap, to)40reply = nil41begin42Timeout.timeout(to) do43pcap.each do |r|44pkt = PacketFu::Packet.parse(r)45next unless pkt.is_tcp?4647reply = pkt48break49end50end51rescue Timeout::Error => e52vprint_error(e.message)53end54return reply55end5657def generate_probe(ip)58ftypes = %w[windows linux freebsd]59@flavor = ftypes.sample60config = PacketFu::Utils.whoami?(iface: datastore['INTERFACE'])61p = PacketFu::TCPPacket.new(config: config)62p.ip_daddr = ip63p.tcp_flags.syn = 164return p65end6667def run_host(ip)68ports = Rex::Socket.portspec_crack(datastore['PORTS'])6970if ports.empty?71raise Msf::OptionValidateError, ['PORTS']72end7374open_pcap7576to = (datastore['TIMEOUT'] || 500).to_f / 1000.07778p = generate_probe(ip)79pcap = capture8081ports.each_with_index do |port, _i|82p.tcp_dst = port83p.tcp_src = rand(1024..65534)84p.tcp_seq = rand(1024..65534)85p.recalc8687ackbpf = "tcp [8:4] == 0x#{(p.tcp_seq + 1).to_s(16)}"88pcap.setfilter("tcp and tcp[13] == 18 and not host #{ip} and src port #{p.tcp_dst} and dst port #{p.tcp_src} and #{ackbpf}")89break unless capture_sendto(p, ip)9091reply = probe_reply(pcap, to)92next if reply.nil?9394print_status("[BNAT RESPONSE] Requested IP: #{ip} Responding IP: #{reply.ip_saddr} Port: #{reply.tcp_src}")95end9697close_pcap98end99end100101102