Path: blob/master/modules/auxiliary/scanner/discovery/arp_sweep.rb
28052 views
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45class MetasploitModule < Msf::Auxiliary6include Msf::Exploit::Remote::Capture7include Msf::Auxiliary::Report8include Msf::Auxiliary::Scanner910OUI_LIST = Rex::Oui1112def initialize13super(14'Name' => 'ARP Sweep Local Network Discovery',15'Description' => %q{16Enumerate alive hosts in local network using ARP requests.17},18'Author' => 'belch',19'License' => MSF_LICENSE,20'Notes' => {21'Stability' => [CRASH_SAFE],22'SideEffects' => [IOC_IN_LOGS],23'Reliability' => []24}25)2627register_options([28OptString.new('SHOST', [false, 'Source IP Address']),29OptString.new('SMAC', [false, 'Source MAC Address']),30# one re-register TIMEOUT here with a lower value, cause 5 seconds will be enough in most of the case31OptInt.new('TIMEOUT', [true, 'The number of seconds to wait for new data', 5]),32])3334deregister_options('SNAPLEN', 'FILTER', 'PCAPFILE', 'SECRET', 'GATEWAY_PROBE_HOST', 'GATEWAY_PROBE_PORT')35end3637def run_batch_size38datastore['BATCHSIZE'] || 25639end4041def run_batch(hosts)42open_pcap({ 'SNAPLEN' => 68, 'FILTER' => 'arp[6:2] == 0x0002' })4344@netifaces = true45if !netifaces_implemented?46print_error('WARNING : NetworkInterface is not up-to-date, some functionality will not be available')47@netifaces = false48end4950@interface = datastore['INTERFACE'] || Pcap.lookupdev51shost = datastore['SHOST']52shost ||= get_ipv4_addr(@interface) if @netifaces53raise 'SHOST should be defined' unless shost5455smac = datastore['SMAC']56smac ||= get_mac(@interface) if @netifaces57raise 'SMAC should be defined' unless smac5859begin60hosts.each do |dhost|61next unless dhost != shost6263probe = buildprobe(shost, smac, dhost)64inject(probe)6566while (reply = getreply)67next unless reply.is_arp?6869company = OUI_LIST.lookup_oui_company_name(reply.arp_saddr_mac)70print_good("#{reply.arp_saddr_ip} appears to be up (#{company}).")71report_host(host: reply.arp_saddr_ip, mac: reply.arp_saddr_mac)72report_note(host: reply.arp_saddr_ip, type: 'mac_oui', data: { company: company })73end74end7576etime = Time.now.to_f + datastore['TIMEOUT']77while (Time.now.to_f < etime)78while (reply = getreply)79next unless reply.is_arp?8081company = OUI_LIST.lookup_oui_company_name(reply.arp_saddr_mac)82print_good("#{reply.arp_saddr_ip} appears to be up (#{company}).")83report_host(host: reply.arp_saddr_ip, mac: reply.arp_saddr_mac)84report_note(host: reply.arp_saddr_ip, type: 'mac_oui', data: { company: company })85end86Kernel.select(nil, nil, nil, 0.50)87end88ensure89close_pcap90end91end9293def buildprobe(shost, smac, dhost)94p = PacketFu::ARPPacket.new95p.eth_saddr = smac96p.eth_daddr = 'ff:ff:ff:ff:ff:ff'97p.arp_opcode = 198p.arp_saddr_mac = p.eth_saddr99p.arp_daddr_mac = p.eth_daddr100p.arp_saddr_ip = shost101p.arp_daddr_ip = dhost102p.recalc103p104end105106def getreply107pkt_bytes = capture.next108Kernel.select(nil, nil, nil, 0.1)109return unless pkt_bytes110111pkt = PacketFu::Packet.parse(pkt_bytes)112return unless pkt.is_arp?113return unless pkt.arp_opcode == 2114115pkt116end117end118119120