---
title: "LoRa security testing notes"
date: "2022-03-25"
path: "/213-lora-security-testing-notes.html"
section: "/ramblings"
description: "A checklist for assessing a LoRaWAN device and network: the questions to ask first, what a passive receiver sees, and where joins, keys and frame counters usually go wrong."
---

These are the notes I keep for looking at a LoRaWAN deployment: sensors, a gateway or two and a network server. Most of the problems are not in the radio. They're in how keys were provisioned, which activation mode was chosen, and what the network server was told to ignore to make a flaky device work.

## Questions before touching anything

- Is it definitely LoRaWAN? LoRa is only the modulation. Plenty of products run their own protocol over LoRa with no encryption at all, and that changes the whole assessment.
- Which region? In Europe it's the 868 MHz plan (EU868): three default channels at 868.1, 868.3 and 868.5 MHz, usually with five more between 867.1 and 867.9 MHz.
- What devices, from which manufacturers, and on what firmware?
- Which LoRaWAN version? 1.0.x and 1.1 differ a lot in their key hierarchy and replay protection, so get this from the device and the network server rather than assuming.
- OTAA (over-the-air activation, with a join) or ABP (activation by personalisation, with session keys burnt in)?
- Who runs the network server and join server: the owner, a public network, or the device vendor's cloud?

## A passive receiver

The easiest way to see what's in the air is to be a gateway. A LoRa concentrator such as Semtech's SX1302 reference design listens on eight channels at once, and Semtech's `sx1302_hal` repository includes the tools to drive it over USB:

```bash
./chip_id -u -d /dev/ttyACM0
./spectral_scan -u -d /dev/ttyACM0
./lora_pkt_fwd -u -d /dev/ttyACM0 -c global_conf.json
```

`chip_id` proves the board is talking and prints its EUI. `spectral_scan` sweeps the band and shows the noise floor per channel, which is worth doing first: a busy or noisy channel explains a lot of "unreliable device" complaints. `lora_pkt_fwd` is the packet forwarder. Point its `server_address` in `global_conf.json` at `localhost`, port 1700, and every uplink it hears is printed as JSON (the `rxpk` format is covered in [decoding LoRaWAN sensor payloads](/214-decoding-lorawan-sensor-payloads.html)). It doesn't need to belong to the network; a gateway just hears everything in range.

From that alone, without any keys, you can see for every frame:

- the message type (join request, confirmed or unconfirmed data),
- the device address (DevAddr), the frame counter, the port and the payload length,
- in join requests, the device's DevEUI and JoinEUI (AppEUI in 1.0) in clear,
- signal strength and SNR, which give a rough idea of distance.

The application payload is encrypted with AES, but the headers aren't. Frame timing and length on their own often give away what a sensor is doing: a door sensor sends when the door opens.

## Keys

LoRaWAN 1.0.x has one root key per device, the AppKey. The join derives two session keys from it: the NwkSKey (message integrity, held by the network server) and the AppSKey (payload encryption, which should only be known to the application). LoRaWAN 1.1 adds a separate NwkKey and splits the network session key into three, so a network operator can no longer forge application traffic.

What to check:

- Is every device's AppKey unique? A batch of devices sharing one key means one extracted key compromises all of them.
- Where are the keys on the device? Many sensors have a UART or debug header, and some accept AT commands that print the keys. Firmware dumped from flash may have them in plain text.
- How were keys delivered to the owner? A spreadsheet emailed by the vendor is common.
- Does the network server or vendor cloud hold the AppSKey? If so, the "end-to-end" encryption ends at their platform.

## Activation mode and frame counters

Each uplink carries a frame counter (FCnt), and the network server should drop any frame whose counter isn't higher than the last one it accepted. That's the replay protection.

ABP devices are where this breaks. With ABP the session keys never change, so when a device reboots and its counter goes back to zero the network server rejects everything until the counter climbs past the old value. The common "fix" is to turn off frame counter validation for that device. Once that's done:

- Any captured uplink can be replayed and will be accepted.
- Because the payload cipher is a keystream derived from the key, the device address and the counter, two frames with the same counter under the same key share a keystream. XOR the two ciphertexts and you get the XOR of the two plaintexts, which for small fixed-format sensor payloads is often enough to recover readings without any key. This is the practical "frame decryption on 1.0" problem.

OTAA devices get fresh session keys at every join, which avoids counter reuse. Check instead:

- that the device rejoins sensibly and doesn't loop through joins (each join is airtime and a chance for something to go wrong),
- that the network server rejects reused DevNonces (in 1.0.x DevNonce is random and servers keep a history; from 1.0.4 and 1.1 it's a counter),
- what the device does when it can't hear its join-accept: some retry at full rate forever, which an attacker can trigger just by drowning out the gateway's downlinks.

## Denial of service

LoRa is robust but not hard to disrupt. A transmitter on the same channel and spreading factor at the right moment kills individual frames, and devices that wait for confirmed downlinks can be made to retransmit until they flatten their batteries. The questions are about consequence: does the system notice a sensor going quiet, and does it fail safe?

## Gateway backhaul

Semtech's UDP packet forwarder protocol between gateway and network server has no authentication or encryption. Anyone on that network path can inject uplinks or read the traffic. Check what the gateways use, and prefer LoRa Basics Station or a vendor equivalent over TLS, or at least put the UDP traffic in a VPN.

## Transmitting

Anything that transmits (spoofing, replay, jamming tests) needs to stay inside the law. The 868 MHz sub-bands have duty cycle limits of 1% or less, and deliberately interfering with other users is illegal. Do active tests cabled through attenuators or in a shielded box, against devices you own or have written permission to test.

## References

- [LoRa Alliance: LoRaWAN security FAQ](https://lora-alliance.org/wp-content/uploads/2020/11/la_faq_security_0220_v1.2_0.pdf)
- [LoRa Alliance: LoRaWAN security white paper](https://lora-alliance.org/sites/default/files/2019-05/lorawan_security_whitepaper.pdf)
- [Trend Micro: Low powered but high risk, evaluating possible attacks on LoRaWAN devices](https://www.trendmicro.com/en_us/research/21/a/Low-Powered-but-High-Risk-Evaluating-Possible-Attacks-on-LoRaWAN-Devices.html)
- [Semtech sx1302_hal and packet forwarder](https://github.com/Lora-net/sx1302_hal)
