CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/auxiliary/scanner/discovery/arp_sweep.rb
Views: 1904
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
)
22
23
register_options([
24
OptString.new('SHOST', [false, "Source IP Address"]),
25
OptString.new('SMAC', [false, "Source MAC Address"]),
26
# one re-register TIMEOUT here with a lower value, cause 5 seconds will be enough in most of the case
27
OptInt.new('TIMEOUT', [true, 'The number of seconds to wait for new data', 5]),
28
])
29
30
deregister_options('SNAPLEN', 'FILTER', 'PCAPFILE', 'SECRET', 'GATEWAY_PROBE_HOST', 'GATEWAY_PROBE_PORT')
31
end
32
33
def run_batch_size
34
datastore['BATCHSIZE'] || 256
35
end
36
37
def run_batch(hosts)
38
open_pcap({'SNAPLEN' => 68, 'FILTER' => "arp[6:2] == 0x0002"})
39
40
@netifaces = true
41
if not netifaces_implemented?
42
print_error("WARNING : NetworkInterface is not up-to-date, some functionality will not be available")
43
@netifaces = false
44
end
45
46
@interface = datastore['INTERFACE'] || Pcap.lookupdev
47
shost = datastore['SHOST']
48
shost ||= get_ipv4_addr(@interface) if @netifaces
49
raise 'SHOST should be defined' unless shost
50
51
smac = datastore['SMAC']
52
smac ||= get_mac(@interface) if @netifaces
53
raise 'SMAC should be defined' unless smac
54
55
begin
56
57
hosts.each do |dhost|
58
if dhost != shost
59
probe = buildprobe(shost, smac, dhost)
60
inject(probe)
61
62
while(reply = getreply())
63
next unless reply.is_arp?
64
company = OUI_LIST::lookup_oui_company_name(reply.arp_saddr_mac)
65
print_good("#{reply.arp_saddr_ip} appears to be up (#{company}).")
66
report_host(:host => reply.arp_saddr_ip, :mac=>reply.arp_saddr_mac)
67
report_note(:host => reply.arp_saddr_ip, :type => "mac_oui", :data => company)
68
end
69
70
end
71
end
72
73
etime = Time.now.to_f + datastore['TIMEOUT']
74
while (Time.now.to_f < etime)
75
while(reply = getreply())
76
next unless reply.is_arp?
77
company = OUI_LIST::lookup_oui_company_name(reply.arp_saddr_mac)
78
print_good("#{reply.arp_saddr_ip} appears to be up (#{company}).")
79
report_host(:host => reply.arp_saddr_ip, :mac=>reply.arp_saddr_mac)
80
report_note(:host => reply.arp_saddr_ip, :type => "mac_oui", :data => company)
81
end
82
Kernel.select(nil, nil, nil, 0.50)
83
end
84
85
ensure
86
close_pcap()
87
end
88
end
89
90
def buildprobe(shost, smac, dhost)
91
p = PacketFu::ARPPacket.new
92
p.eth_saddr = smac
93
p.eth_daddr = "ff:ff:ff:ff:ff:ff"
94
p.arp_opcode = 1
95
p.arp_saddr_mac = p.eth_saddr
96
p.arp_daddr_mac = p.eth_daddr
97
p.arp_saddr_ip = shost
98
p.arp_daddr_ip = dhost
99
p.recalc
100
p
101
end
102
103
def getreply
104
pkt_bytes = capture.next
105
Kernel.select(nil,nil,nil,0.1)
106
return unless pkt_bytes
107
pkt = PacketFu::Packet.parse(pkt_bytes)
108
return unless pkt.is_arp?
109
return unless pkt.arp_opcode == 2
110
pkt
111
end
112
end
113
114