Low-Cost ZigBee Selective Jamming
I just reviewed a paper that claimed that reactive jamming of ZigBee would only be possible with sophisticated devices that cost over $3000. There was, however, already a paper in 2011, which implemented a reactive ZigBee jammer by modifying the FPGA of a USRP2 SDR [1]. Furthermore, it was shown that low-cost CC2420-based nodes can be turned into a reactive jammer [2]. Since I recently bought a $40 ATUSB ZigBee USB dongle from Sysmocom, I wanted to give it a try with this device.
(The whole idea is very similar to my blog post about jamming WiFi ACKs with WLAN cards, which was based on Mathy Vanhoef’s work, who modified the Atheros ath9k_htc
firmware [3].)
Step 1: Setup
The ATUSB is completely Open Source (drivers, firmware, and schematics) and has native Linux support.
We, therefore, only need the user space tools.
On Ubuntu they come with wpan-tools
package.
Using these tool, we can put the ATUSB in monitor mode with something like:
sudo iwpan dev wpan0 del
sudo iwpan phy phy0 interface add monitor0 type monitor
sudo ifconfig monitor0 up
sudo iwpan phy phy0 set channel 0 24
With this, we can, for example, listen to the monitor0
interface with Wireshark and sniff ZigBee traffic.
(I also deleted the normal wpan interface to make sure that the Linux ZigBee stack does not interfere. I was not sure whether this would cause problems when modifying the firmware for jamming.)
Step 2: Preliminaries
The ATUSB uses an Atmega32U2 microcontroller with an AT86RF231 ZigBee transceiver.
An interesting feature of the AT86RF231 is that it supports high-accuracy receive time stamping by issuing an RX_START
interrupt when the device syncs on a frame.
This can be done through a dedicated pin, which is unfortunately not connected on the ATUSB.
Yet, the interrupt can also be received through the usual interrupt mechanism between RF chip and microcontroller.
It works as follows:
- The microcontroller enables the interrupts that it is interested in through the interrupt mask.
- To signal the interrupt, the transceiver toggles the IRQ pin.
- Once the microcontroller notices the interrupt, it reads the interrupt register through SPI (which also clears the register).
This way the single interrupt line can be used to signal multiple events like frame start, finished TX, and ACK received.
The goal is now to detect the RX_START
interrupt and force the AT86RF231 to transmit something ASAP.
The main questions are: (1) can this be done fast enough and (2) can we force the AT86RF231 to transmit even though the channel is busy.
The latter should be possible, since ZigBee (or actually IEEE 802.15.4) can use two operational modes. The usual CSMA/CA base channel access (where the frame is sent only if the channel is free) and a contention free channel access (where the device has fixed slots allocated). To support the second mode, it should be possible to send frames without CCA.
Step 3: Modify the Firmware
The firmware of the ATUSB is available on GitHub. To compile it, one needs the AVR toolchain:
sudo apt install avr-libc gcc-avr binutils-avr
Furthermore, flashing the firmware requires an older version (v0.7) of dfu-util
.
The one in the Ubuntu repositories is too recent, so it has to be compiled from source.
It is available here.
After installing dfu-util and the toolchain, the firmware can be compiled and flashed with
cd atusb/fw
make
make dfu
Step 4: Jamming
As it turns out, jamming is rather straight forward to implement.
We can just extend the interrupt service routine (ISR) and check whether we are notified about the start of the reception process.
If this is the case, we use the FORCE_PLL_ON
command to enter the PLL_ON
state, from which we can trigger a transmission.
The only thing I did before actually triggering the transmission was to define the size of the interfering frame. The transceiver has an internal buffer for a maximum sized frame. Since we don’t care about the payload, we just set the size and the transceiver will send whatever is in the buffer.
Finally, transmission is triggered with slp_tr()
, which sets (and then clears) an IO pin that is directly connected to the transceiver.
Afterwards, we switch back to receive mode.
ISR(INT0_vect)
{
irq = reg_read(REG_IRQ_STATUS);
if(irq == IRQ_RX_START) {
reg_write(REG_TRX_STATE, TRX_CMD_FORCE_PLL_ON);
spi_begin();
spi_send(AT86RF230_BUF_WRITE);
spi_send(17); // length of jam frame
spi_end();
slp_tr();
change_state(TRX_CMD_RX_ON);
return;
}
[...]
}
I didn’t have another ZigBee device at hand, so I used my GNU Radio IEEE 802.15.4 transceiver to send ZigBee frames with a HackRF. To check if jamming works, I used a Pluto SDR to monitor the channel.
I recorded a video that first shows the ZigBee frames, which are sent nearly back-to-back.
Then, after some time, the monitor0
interface (i.e., the ATUSB dongle) is enabled and the frames get jammed.
To better show the timing, I sent rather short jamming pulses.
However, the length can be changed with the above spi_send()
call as annotated in the listing.
It seems to work rather reliably and can deal with high frame rates.
With 260us, the reaction time of the jammer is rather fast. The delay comprises 160us for preamble and start of frame delimiter and another 100us for switching to TX. This low reaction time means that already the third byte of the payload can get jammed. Even ACKs use five byte payload (including a two byte CRC) and can, therefore, be jammed.
Selective Jamming
The AT86RF231 has another very interesting feature.
Apart from the RX_START
interrupt, it can be configured to also issue an address match interrupt (AMI).
The actual intention is to notify the receiver only about frames targeted to this particular device.
When an address is configured, this interrupt is raised immediately after the MAC header is received.
Subscribing to this interrupt, we can even jam one selected device.
I prepared a small proof-of-concept where my PlutoSDR sends frames alternately to two ZigBee nodes. To indicate reception of a frame, the nodes toggle an LED. In the beginning, I jam both devices (reactive jamming). Then I load an alternate firmware, which jams only the right node (selective jamming).
References
-
Matthias Wilhelm, Ivan Martinovic, Jens B. Schmitt and Vincent Lenders, “Short Paper: Reactive Jamming in Wireless Networks – How Realistic is the Threat?,” Proceedings of 4th ACM Conference on Wireless Network Security (WiSec 2011), Hamburg, Germany, June 2011, pp. 47–52. [DOI, BibTeX, PDF and Details…]
-
Anthony D Wood, John A Stankovic and Gang Zhou, “DEEJAM: Defeating Energy-Efficient Jamming in IEEE 802.15.4-based Wireless Networks,” Proceedings of 4th Annual IEEE Communications Society Conference on Sensor, Mesh and Ad Hoc Communications and Networks (SECON 2007), San Diego, CA, 2007, pp. 60–69. [BibTeX, PDF and Details…]
-
Mathy Vanhoef and Frank Piessens, “Advanced Wi-Fi Attacks Using Commodity Hardware,” Proceedings of 30th Annual Computer Security Applications Conference (ACSAC 2014), New Orleans, LA, December 2014, pp. 256-265. [DOI, BibTeX, PDF and Details…]