CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/auxiliary/admin/misc/wol.rb
Views: 11784
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::Udp
8
9
def initialize(info = {})
10
super(update_info(info,
11
'Name' => 'UDP Wake-On-Lan (WOL)',
12
'Description' => %q{
13
This module will turn on a remote machine with a network card that
14
supports wake-on-lan (or MagicPacket). In order to use this, you must
15
know the machine's MAC address in advance. The current default MAC
16
address is just an example of how your input should look like.
17
18
The password field is optional. If present, it should be in this hex
19
format: 001122334455, which is translated to "0x001122334455" in binary.
20
Note that this should be either 4 or 6 bytes long.
21
},
22
'License' => MSF_LICENSE,
23
'Author' => [ 'sinn3r' ]
24
))
25
26
deregister_udp_options
27
28
register_options(
29
[
30
OptString.new("MAC", [true, 'Specify a MAC address', '00:90:27:85:cf:01']),
31
OptString.new("PASSWORD", [false, 'Specify a four or six-byte password']),
32
OptBool.new("IPV6", [false, 'Use IPv6 broadcast', false])
33
])
34
end
35
36
#
37
# Convert the MAC option to binary format
38
#
39
def get_mac_addr
40
mac = datastore['MAC']
41
if mac !~ /^([0-9a-zA-Z]{2}\:){5}[0-9a-zA-Z]{2}$/
42
print_error("Invalid MAC address format")
43
return nil
44
end
45
46
bin_mac = ''
47
mac.split(':').each do |group|
48
bin_mac << [group].pack('H*')
49
end
50
51
bin_mac
52
end
53
54
#
55
# Supply a password to go with the WOL packet (SecureON)
56
#
57
def parse_password
58
return "" if datastore['PASSWORD'].nil?
59
60
dataset = [ datastore['PASSWORD'] ].pack('H*').unpack('C*')
61
62
# According to Wireshark wiki, this must be either 4 or 6 bytes
63
if dataset.length == 4 or dataset.length == 6
64
pass = ''
65
dataset.each do |group|
66
pass << group.to_i
67
end
68
69
return pass
70
else
71
print_error("Bad password format or length: #{dataset.inspect}")
72
end
73
74
nil
75
end
76
77
def wol_rhost
78
datastore['IPV6'] ? "ff:ff:ff:ff:ff:ff" : "255.255.255.255"
79
end
80
81
def wol_rport
82
9
83
end
84
85
def run
86
# If the MAC is bad, no point to continue
87
mac = get_mac_addr
88
return if mac.nil?
89
90
# If there's a password, use it
91
pass = parse_password
92
return if pass.nil?
93
94
# Craft the WOL packet
95
wol_pkt = "\xff" * 6 #Sync stream (magic packet)
96
wol_pkt << mac * 16 #Mac address
97
wol_pkt << pass if not pass.empty?
98
99
# Send out the packet
100
print_status("Sending WOL packet...")
101
connect_udp( true, {
102
'RHOST' => wol_rhost,
103
'RPORT' => wol_rport
104
})
105
udp_sock.put(wol_pkt)
106
disconnect_udp
107
end
108
end
109
110
=begin
111
http://wiki.wireshark.org/WakeOnLAN
112
113
Test:
114
udp && eth.addr == ff:ff:ff:ff:ff:ff
115
=end
116
117