diff --git a/modules/auxiliary/admin/misc/wol.rb b/modules/auxiliary/admin/misc/wol.rb new file mode 100644 index 0000000000..6f3d0fa62c --- /dev/null +++ b/modules/auxiliary/admin/misc/wol.rb @@ -0,0 +1,126 @@ +## +# This file is part of the Metasploit Framework and may be subject to +# redistribution and commercial restrictions. Please see the Metasploit +# Framework web site for more information on licensing and terms of use. +# http://metasploit.com/framework/ +## + +require 'msf/core' + +class Metasploit3 < Msf::Auxiliary + + include Msf::Exploit::Remote::Udp + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'UDP Wake-On-Lan (WOL)', + 'Description' => %q{ + This module will turn on a remote machine with a network card that + supports wake-on-lan (or MagicPacket). In order to use this, you must + know the machine's MAC address in advance. The current default MAC + address is just an example of how your input should look like. + + The password field is optional. If present, it should be in this hex + format: 001122334455, which is translated to "0x001122334455" in binary. + Note that this should be either 4 or 6 bytes long. + }, + 'Author' => [ 'sinn3r' ], + 'License' => MSF_LICENSE, + )) + + register_options( + [ + OptString.new("MAC", [true, 'Specify a MAC address', '00:90:27:85:cf:01']), + OptString.new("PASSWORD", [false, 'Specify a four or six-byte password']), + OptBool.new("IPV6", [false, 'Use IPv6 broadcast', false]) + ], self.class) + + deregister_options('RHOST', 'RPORT') + end + + # + # Restore the original rhost:rport + # + def cleanup + datastore['RHOST'] = @last_rhost + datastore['RPORT'] = @last_rport + end + + # + # Convert the MAC option to binary format + # + def get_mac_addr + mac = datastore['MAC'] + if mac !~ /^([0-9a-zA-Z]{2}\:){5}[0-9a-zA-Z]{2}$/ + print_error("Invalid MAC address format") + return nil + end + + bin_mac = '' + mac.split(':').each do |group| + bin_mac << [group].pack('H*') + end + + bin_mac + end + + # + # Supply a password to go with the WOL packet (SecureON) + # + def parse_password + return "" if datastore['PASSWORD'].nil? + + dataset = [ datastore['PASSWORD'] ].pack('H*').unpack('C*') + + # According to Wireshark wiki, this must be either 4 or 6 bytes + if dataset.length == 4 or dataset.length == 6 + pass = '' + dataset.each do |group| + pass << group.to_i + end + + return pass + else + print_error("Bad password format or length: #{dataset.inspect}") + end + + nil + end + + def run + # If the MAC is bad, no point to continue + mac = get_mac_addr + return if mac.nil? + + # If there's a password, use it + pass = parse_password + return if pass.nil? + + # Save the original rhost:rport settings so we can restore them + # later once the module is done running + @last_rhost = rhost + @last_rport = rport + + # Config to broadcast + datastore['RHOST'] = datastore['IPV6'] ? "ff:ff:ff:ff:ff:ff" : "255.255.255.255" + datastore['RPORT'] = 9 + + # Craft the WOL packet + wol_pkt = "\xff" * 6 #Sync stream (magic packet) + wol_pkt << mac * 16 #Mac address + wol_pkt << pass if not pass.empty? + + # Send out the packet + print_status("Sending WOL packet...") + connect_udp + udp_sock.put(wol_pkt) + disconnect_udp + end +end + +=begin +http://wiki.wireshark.org/WakeOnLAN + +Test: +udp && eth.addr == ff:ff:ff:ff:ff:ff +=end