|Informative Information for the Uninformed|
One of the fastest ways to find new flaws is through the use of a fuzzer. In general terms, a fuzzer is a program that forces an application to process highly variant data that is typically malformed in the hopes that one of the attempts will yield a crash. Fuzzing a wireless device driver depends on the device being in a state where specific frames are processed and a tool that can send frames likely to cause a crash. In the first part of this chapter, the authors described the default state of a wireless client and what types of management frames are processed in this state.
The two types of frames that this paper will focus on are Beacons and
Probe Responses. These frames have the following structure:
The Information Elements field is a list of variable-length structures consisting of a one byte type field, a one byte length field, and up to 255 bytes of data. Variable-length fields are usually good targets for fuzzing since they require special processing when the packet is parsed. To attack a driver that uses Passive Mode to discover wireless networks, it's necessary to flood the target with mangled Beacons. To attack a driver that uses Active Mode, it's necessary to flood the target with mangled Probe Responses while forcing it to scan for networks. The following Ruby code generates a Beacon frame with randomized Information Element data. The Frame Checksum field is automatically added by the driver and does not need to be included.
# # Generate a beacon frame with random information elements # # Maximum frame size (max is really 2312) mtu = 1500 # Number of information elements ies = rand(1024) # Randomized SSID ssid = Rex::Text.rand_text_alpha(rand(31)+1) # Randomized BSSID bssid = Rex::Text.rand_text(6) # Randomized source src = Rex::Text.rand_text(6) # Randomized sequence seq = [rand(255)].pack('n') # Capabiltiies cap = Rex::Text.rand_text(2) # Timestamp tstamp = Rex::Text.rand_text(8) frame = "\x80" + # type/subtype (mgmt/beacon) "\x00" + # flags "\x00\x00" + # duration "\xff\xff\xff\xff\xff\xff" + # dst (broadcast) src + # src bssid + # bssid seq + # seq tstamp + # timestamp value "\x64\x00" + # beacon interval cap # capabilities # First IE: SSID "\x00" + ssid.length.chr + ssid + # Second IE: Supported Rates "\x01" + "\x08" + "\x82\x84\x8b\x96\x0c\x18\x30\x48" + # Third IE: Current Channel "\x03" + "\x01" + channel.chr # Generate random Information Elements and append them 1.upto(ies) do |i| max = mtu - frame.length break if max < 2 t = rand(256) l = (max - 2 == 0) ? 0 : (max > 255) ? rand(255) : rand(max - 1) d = Rex::Text.rand_text(l) frame += t.chr + l.chr + d end
While this is just one example of a simple 802.11 fuzzer for a particular frame, much more complicated, state-aware fuzzers could be implemented that make it possible to fuzz other packet handling areas of wireless device drivers.