Thursday 15 October 2015

Advanced WiFi Attacks Using Commodity Hardware

The WiFi protocol assumes all clients behaves fairly. This means a station will give others a chance to transmit packets, before it starts transmitting itself. It's known that with a software defined radio such as a USRP, a user can implement the WiFi protocol themselves and not follow these rules.

 A desktop computer, antenna, two USRPs on top of each other, and a signal analyzer.

An attacker can also use this equipment to create a constant jammer, which continuously transmits noise, and makes the channel completely unusable. In principle an attacker could also turn on a badly shielded microwave to jam the channel :-) However, that doesn't give the attacker control over which frequency is jammed, bandwidth of the emitted noise, nor the emitted noise pattern.

It's even possible to implement a more sophisticated selective jammer. Such a jammer is capable of only jamming specific packets (e.g. only packets sent by a certain device). While it's already known this is possible using expensive hardware such as USRPs, we found that even cheap WiFi dongles can be used to implement all these attacks. It's especially surprising that a selective jammer can be implemented on a cheap WiFi dongle, since it must be fast enough to detect and subsequently jam a packet.

Our attacks were first published at ACSAC 2014 and subsequently demonstrated at BruCON 2015. Additionally our code is available on github! You can also view my presentation at BruCON online.

Selfish Behavior

When a station wants to transmit a packet, but the channel is already in use by another device, it first waits until this transmission is done. Then it waits a random period (called the backoff period), and if no one else starts transmitting during this period, the station may send the packet. We found that it's easy to disable the random backoff period on commodity devices, meaning it will instantly transmit packets. More interestingly, we found that even the original driver and firmware for our device incorrectly calculated the backoff period, giving itself an unfair advantage over other stations! It turns out that many devices do this to gain an unfair advantage:
Over six Wi-Fi cards, neither one performs as expected. In some cases, implementation issues seem to affect the proper card operation. In other cases, manufacturers rely on backoff parameters different from the standard specification, this perhaps being done on purpose to provide an unfair advantage. [Minimized conclusion from this paper]
This raises the question what would happen if there are two stations that both behave selfishly by disabling the backoff period. In other words, what happens if two selfish stations instantly transmit all packets they have queued? You may think that the packets of both selfish stations will collide, and as a result both are lost in the collision. It turns out this is not the case! Due to the capture effect, the packet having the highest signal quality and lowest bitrate will get decoded properly. You can compare this to receiving two radio stations on the same frequency, where generally one station will "win the collision" (see this demo video). This means selfish stations will abuse the capture effect, and reduce their bitrate, in order to win the collision (and have their packet decoded correctly by the receiver). Surprisingly, we now get that selfish clients wanting to maximize their throughput, will reduce their bitrate!

One of our WiFi dongles attached to a Raspberry Pi

There is a research prototype called DOMINO which can detect and punish this type of selfish behavior. Unfortunately we discovered a critical flaw in this system. The problem is that this system bases some of its decisions on unauthenticated packets. As an attacker we can abuse this by forging packets which appear to be sent by a different station. Hence we can make DOMINO believe this client is acting selfishly, meaning it will be punished and thrown off the network. Moral of the story: only base your decisions on authenticated or hard-to-forge data.

Constant Jammer

Our WiFi dongles can also be used to implement a constant jammer. The idea is straightforward: make the radio instantly transmit packets (even if someone else is transmitting), and then send an infinite amount of packets without interruption. The second part is tedious, since we can't queue many packets due to the limited amount of memory available in the WiFi dongle. However, we can simulate an infinite amount of packets. The packets queued for transmission are stored in a linked list. By turning this queue into a circular list we can simulate an infinite amount of packets.

What's interesting here is that in principle the jammer is constantly transmitting valid WiFi packets. However, because they are sent so fast after one another, other WiFi devices are unable to detect these packets. In other words, other WiFi devices operating in monitor mode only see noise, and will not detect/show and show any WiFi traffic.

Selective Jammer

Arguably the most impressive result is that our cheap dongle can be used to implement a selective (also called reactive) jammer. Such a jammer decodes the header of a packet still in the air, and based on information in the header, decides whether to jam the remaining content or not. This is not an easy feat to accomplish. The selective jammer must be fast enough to decode the header, make the decision to jam the packet, put the antenna in transmit mode, and finally jam the packet. All this needs to be done in just a few microseconds (an average WiFi packet takes ~200 microseconds to transmit)!

Jamming the end of the packet is easy, simply inject a packet like we did for the continuous jammer. But there is no support or API to be notified when a packet is in the progress of being received. How do we get around this? The important realization is that there are two chips inside our WiFi device. The first one is the radio which processes the incoming physical signal, and uses Direct Memory Access (DMA) to write the packet to memory. The second chip is the main CPU which is responsible for communicating with the host over USB and controlling the radio chip. Hence we can use the main CPU to constantly monitor the memory where the packet will be saved. Once we detect that the radio chip is writing bytes to this memory location, we know a frame is being received:

When the memory is modified, we know a frame is being received.

With this clever trick we can detect when a frame is being received. Our jammer then reads the MAC address(es) in the header, and compares it to the MAC address of the station we are targeting. If they match, the remaining content of the packet is jammed. This will cause the CRC (called the ICV in WiFi) of the packet to be wrong, meaning the packet will be dropped by the receiver.

The code of the reactive jammer is public, feel free to play around with it (against a test network).

Channel-Based Man-in-the-Middle Attack

As an example, we show how these low-layer attacks can be used to reliably manipulate encrypted traffic. Note that our goal is not to decrypt traffic. Instead, we want to be able to reliably drop, modify, and inject packets. This ability is typically required in order to launch actual (cryptographic) attacks against an higher-layer protocol. Previously when targeting wireless traffic, it was not clear how to do this: there were no known methods to obtain a (reliable) man-in-the-middle position between a client and access point if encryption is used.

In order to intercept (not decrypt) all traffic of an encrypted wireless network, we cannot simply create a rogue Access Point (AP) with a different MAC address. When a client connects to the access point, not only are the credentials verified (e.g. shared password), but also the MAC addresses of the client and access point. Hence the client and AP will detect that an attacker was forwarding packets under different MAC addresses. Setting up a rouge AP with the same mac address as the real AP is futile: the client will simply directly communicate with the real AP (unless they are out of range of each other).

Our solution is to clone the access point on a different channel, but with the same MAC address as the real access point. We forward all frames to the real AP. In other words, we forward packets between both channels. Using the constant jammer we force clients to switch to the channel where our rogue AP is located. Since we did not modify the MAC address of the AP, and also didn't modify the MAC address of the client, the client will successfully connect to the (rogue) AP. We now have a (channel-based) man-in-the-middle position, allowing reliable manipulation of encrypted traffic.

Demonstration of the Channel-Based MiTM attack against WPA-TKIP

The channel-based man-in-the-middle attack can be used to break WPA-TKIP (people commonly, but incorrectly, refer to TKIP as WPA, and AES-CCMP as WPA2). The TKIP protocol was supposed to be a temporarily replacement of WEP, designed to run on old hardware. Unfortunately, for backwards compatibility, many networks still support both TKIP and the newer AES-CCMP. If both these protocols are supported, the older TKIP protocol is used to encrypt all broadcast packets. Without going into detail, the channel-based man-in-the-middle allows us to apply existing TKIP attacks to broadcast packets. Hence you should configure your network so only (AES-)CCMP is enabled!