Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rapid7
GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/auxiliary/scanner/discovery/arp_sweep.rb
28052 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
include Msf::Exploit::Remote::Capture
8
include Msf::Auxiliary::Report
9
include Msf::Auxiliary::Scanner
10
11
OUI_LIST = Rex::Oui
12
13
def initialize
14
super(
15
'Name' => 'ARP Sweep Local Network Discovery',
16
'Description' => %q{
17
Enumerate alive hosts in local network using ARP requests.
18
},
19
'Author' => 'belch',
20
'License' => MSF_LICENSE,
21
'Notes' => {
22
'Stability' => [CRASH_SAFE],
23
'SideEffects' => [IOC_IN_LOGS],
24
'Reliability' => []
25
}
26
)
27
28
register_options([
29
OptString.new('SHOST', [false, 'Source IP Address']),
30
OptString.new('SMAC', [false, 'Source MAC Address']),
31
# one re-register TIMEOUT here with a lower value, cause 5 seconds will be enough in most of the case
32
OptInt.new('TIMEOUT', [true, 'The number of seconds to wait for new data', 5]),
33
])
34
35
deregister_options('SNAPLEN', 'FILTER', 'PCAPFILE', 'SECRET', 'GATEWAY_PROBE_HOST', 'GATEWAY_PROBE_PORT')
36
end
37
38
def run_batch_size
39
datastore['BATCHSIZE'] || 256
40
end
41
42
def run_batch(hosts)
43
open_pcap({ 'SNAPLEN' => 68, 'FILTER' => 'arp[6:2] == 0x0002' })
44
45
@netifaces = true
46
if !netifaces_implemented?
47
print_error('WARNING : NetworkInterface is not up-to-date, some functionality will not be available')
48
@netifaces = false
49
end
50
51
@interface = datastore['INTERFACE'] || Pcap.lookupdev
52
shost = datastore['SHOST']
53
shost ||= get_ipv4_addr(@interface) if @netifaces
54
raise 'SHOST should be defined' unless shost
55
56
smac = datastore['SMAC']
57
smac ||= get_mac(@interface) if @netifaces
58
raise 'SMAC should be defined' unless smac
59
60
begin
61
hosts.each do |dhost|
62
next unless dhost != shost
63
64
probe = buildprobe(shost, smac, dhost)
65
inject(probe)
66
67
while (reply = getreply)
68
next unless reply.is_arp?
69
70
company = OUI_LIST.lookup_oui_company_name(reply.arp_saddr_mac)
71
print_good("#{reply.arp_saddr_ip} appears to be up (#{company}).")
72
report_host(host: reply.arp_saddr_ip, mac: reply.arp_saddr_mac)
73
report_note(host: reply.arp_saddr_ip, type: 'mac_oui', data: { company: company })
74
end
75
end
76
77
etime = Time.now.to_f + datastore['TIMEOUT']
78
while (Time.now.to_f < etime)
79
while (reply = getreply)
80
next unless reply.is_arp?
81
82
company = OUI_LIST.lookup_oui_company_name(reply.arp_saddr_mac)
83
print_good("#{reply.arp_saddr_ip} appears to be up (#{company}).")
84
report_host(host: reply.arp_saddr_ip, mac: reply.arp_saddr_mac)
85
report_note(host: reply.arp_saddr_ip, type: 'mac_oui', data: { company: company })
86
end
87
Kernel.select(nil, nil, nil, 0.50)
88
end
89
ensure
90
close_pcap
91
end
92
end
93
94
def buildprobe(shost, smac, dhost)
95
p = PacketFu::ARPPacket.new
96
p.eth_saddr = smac
97
p.eth_daddr = 'ff:ff:ff:ff:ff:ff'
98
p.arp_opcode = 1
99
p.arp_saddr_mac = p.eth_saddr
100
p.arp_daddr_mac = p.eth_daddr
101
p.arp_saddr_ip = shost
102
p.arp_daddr_ip = dhost
103
p.recalc
104
p
105
end
106
107
def getreply
108
pkt_bytes = capture.next
109
Kernel.select(nil, nil, nil, 0.1)
110
return unless pkt_bytes
111
112
pkt = PacketFu::Packet.parse(pkt_bytes)
113
return unless pkt.is_arp?
114
return unless pkt.arp_opcode == 2
115
116
pkt
117
end
118
end
119
120