TL;DR: Yes, You Can Learn Aviation Protocol Security Without Touching an SDR or the RF Spectrum
Public ADS-B and ACARS feeds let you build a complete decode-and-replay lab legally and safely—no radio hardware, no transmissions, no gray areas. You download real aircraft telemetry, dissect it in Wireshark, decode it with Scapy, and replay it against local tooling. This guide shows you exactly how to decode ADS-B traffic with Wireshark and Scapy using nothing but your laptop and an internet connection.
Aviation’s two most widely used surveillance and reporting protocols—ADS-B and ACARS—broadcast operational data in the clear. No encryption. No authentication. No integrity checks. For a security practitioner, that combination is familiar territory: it’s the same trust model as an unauthenticated IoT telemetry protocol, except the “devices” are aircraft moving at 500 knots. This lab walks you through building a complete analysis environment from public data feeds, dissecting both protocols at the byte level, and understanding—conceptually and in a bounded local lab—why researchers have demonstrated ghost aircraft and spoofed identities against them.
Why ADS-B and ACARS Matter to Security Practitioners
ADS-B (Automatic Dependent Surveillance–Broadcast) is the FAA-mandated surveillance technology replacing radar: aircraft periodically broadcast their position, velocity, altitude, and identity over 1090 MHz (or 978 MHz UAT in the US). ACARS (Aircraft Communications Addressing and Reporting System) is the older data-link protocol carrying operational messages—weather requests, gate assignments, engine reports—over VHF, HF, and satellite.
Neither protocol authenticates its sender. The design decision traces back to the 1990s: universal interoperability and cheap avionics were prioritized over security. The result is a broadcast medium where any receiver can decode every message, and—because there are no cryptographic checks—the protocols are vulnerable to jamming, message injection, and impersonation.
Why should you care? Three reasons:
- Blue-team transferability. Detecting ADS-B spoofing is a plausibility-and-anomaly problem—impossible speeds, duplicate ICAO addresses, position jumps—structurally identical to telemetry fraud detection in fleet and IoT monitoring.
- CTF and research relevance. Aviation protocol challenges appear regularly in CTFs and academic work (the OpenSky Network’s research papers are a solid starting point).
- Threat modeling practice. The attack surface—passive tracking of aircraft, injection of phantom contacts, identity spoofing—is a clean, real-world example of what happens when a safety-critical protocol ships without authentication. CISA’s guidance on GPS and PNT vulnerabilities makes the same point about adjacent navigation systems (see CISA’s communications security resources).
Lab Setup: Pulling Live Data from Public Feeds
You don’t need an RTL-SDR dongle, an antenna, or a capture from the RF spectrum. Multiple community projects expose raw ADS-B messages over the internet:
- adsb.lol and adsb.fi — open community feeds offering RAW Beast-format streams ( Beast: <esc> “2” … <esc> “3” <6 bytes> ) you can read with a simple TCP client in Python.
- The OpenSky Network (opensky-network.org) — a research association offering a REST API returning decoded state vectors: ICAO24 addresses, positions, velocities, callsigns. Ideal for ground-truthing your own decoders.
- ACARS feeds and archives — sites like airframes.org and community ACARS decoders expose decoded message databases; ACARSView, acarsdeco2 documentation, and sample dumps floating around GitHub give you real frame structures to work with.
- Pre-made sample captures — searching GitHub for “ModeS sample bin” or “dump1090 samples” yields recorded message dumps you can load directly.
For a reproducible lab, pull a few thousand Beast frames from a community feed with a short Python socket script and save them to a file. That file becomes your immutable “capture”—the equivalent of a pcap, but for Mode S extended squitter messages. Every exercise below works against that static file.
Understanding the ADS-B Message Format
ADS-B messages ride inside Mode S extended squitter (DF17 and DF18 downlink format) frames. A single DF17 message is 112 bits: 5 bits DF, then the ICAO 24-bit address, then a 56-bit payload (ME field) plus parity. The ME field’s first bits are the Type Code (TC), which tells you what the message carries:
- TC 1–4: Identification—8-character callsign, 6 bits per character using the ICAO charset (“ABCDE…12345…”).
- TC 9–18: Airborne position, encoded with Compact Position Reporting (CPR)—the position is split across two message types (odd and even frames) and requires pairing both to recover global coordinates. Altitude uses Gray coding in 25-foot increments.
- TC 19: Velocity—ground speed, track, vertical rate.
- TC 5–8: Surface position (on the ground).
- TC 31: Aircraft operational status (version, capability flags).
The DF field is the first key to dissecting: DF17 (17) is ADS-B from transponder-equipped aircraft; DF18 is for non-transponder vehicles; DF4/5/20/21 are Mode S surveillance replies. If the first byte’s top five bits are 10001, you’re looking at an ADS-B frame. The ICAO 24-bit address in bytes 1–3 is the globally unique aircraft identifier—memorize that offset; you’ll use it constantly.
Understanding ACARS Message Structure
ACARS frames are different beasts entirely. A VHF ACARS message is an ASCII-oriented frame sandwiched between SOH (0x01) and delimiter bytes, with fields:
- Mode character and address (aircraft registration, e.g., “N12345” or “D-AIXP”)
- ACK/NAK flag and label (two characters indicating message type: “H1” for weather requests, “Q0” for ACARS management, “5Z” for position reports)
- Block ID (message sequence number) and message number
- Flight ID (e.g., “DLH447”)
- Message text — often plaintext or lightly obfuscated application payloads, frequently including latitude/longitude, fuel state, ETAs, and sometimes maintenance data
What ACARS exposes in practice is striking: flight routings, weather pull requests, gate assignments, and engine trend reports—all readable by anyone with a receiver or a feed subscription. Decoded archives online make this trivially demonstrable, which is precisely why it belongs in your threat-model education.
Dissecting Packets in Wireshark
Wireshark has no native ADS-B dissector that decodes CPR coordinates, but it’s still your best inspection surface—especially for ACARS and for Mode S raw bytes. Two workflows:
Workflow 1 — ACARS as UDP payloads. Many ACARS decoders output messages as UDP packets in the Planeplotter or “acarsdec JSON” format. Import a capture of those into Wireshark and filter on udp.port == 5555. Add a custom column for Data.data and you can eyeball the SOH-prefixed frames, labels, and flight IDs directly in the packet list. “Follow UDP Stream” reconstructs a full message session.
Workflow 2 — Mode S raw bytes. Wrap your Beast or AVRT (AVR-format) frames into a file Wireshark can open. A practical trick: encode each 112-bit Mode S frame as a UDP packet’s payload in a synthetic pcap using text2pcap or Scapy’s wrpcap(). Then apply display filters like:
data.data[0:1] & 0xf8 == 0x88— matches DF17 frames (top five bits = 10001)data.data[1:4]— isolate the ICAO address bytes for sorting by aircraft
Configure columns for the first four data bytes (DF+ICAO) and the ME type code, and Wireshark becomes a fast triage tool for sorting your capture by aircraft and message type before you hand the frames to Scapy for real decoding.
Building ADS-B Frames with Scapy
Scapy is the natural Python tool for parsing and re-crafting Mode S frames. There’s no built-in Mode S dissector, but raw bit manipulation in Python is only a few dozen lines:
from scapy.all import raw, IP, UDP, wrpcap, rdpcap
def bits(frame, start, n):
b = int.from_bytes(frame, 'big')
return (b >> (len(frame)*8 - start - n)) & ((1 << n) - 1)
def decode_df17(frame): # frame: 14 bytes (7) with CRC 24 + 4 status? use 112-bit
df = bits(frame, 0, 5)
icao = frame[1:4].hex().upper()
if df != 17:
return None
me = int.from_bytes(frame[4:11], 'big')
tc = me >> 51
kind = {range(1,5):'callsign', range(9,19):'position',
range(19,20):'velocity', range(5,9):'surface'}.get(
next((r for r in [{*range(1,5)},{*range(9,19)},{*range(19,20)},{*range(5,9)}] if tc in r), []), 'other')
return {'df':df, 'icao':icao, 'tc':tc, 'type':kind}
For CPR decoding, implement the global odd/even algorithm (well documented in the Mode-S/ADS-B decoding references and OpenSky’s documentation): take one even and one odd airborne-position message for the same ICAO address, compute the latitude zone index, resolve longitude ambiguity, and normalize the latitude into zones −4…+4.
You can also build a pcap of synthetic Mode S frames for your replay exercises:
pkts = [IP()/UDP(sport=30002, dport=30002)/raw(bytes.fromhex(f))
for f in frame_hex_list]
wrpcap('adsb_lab.pcap', pkts)
Expected output when you run the decoder over a real capture looks like:
DF17 ICAO:4CA87A TC:19 velocity gs=447kt trk=283 vr=-64
DF17 ICAO:4CA87A TC:11 position (even) lat_enc=87520 lon_enc=55740
DF17 ICAO:A3C7F2 TC:4 callsign UAL2213
Replaying Captured Traffic in the Lab
Replay is where the lab teaches its most important lesson: downstream tools will accept whatever you feed them, because there’s no authentication to reject it. Two safe replay targets:
- Local feed consumers. Tools like
dump1090,readsb, andtar1090accept raw input over TCP ports (typically 30002/30005 for AVR and Beast). Pipe your recorded frames into readsb’s input port on localhost and watch the aircraft map render a previously captured flight—instant replay of history. - Loopback in Python. Replay frames through a Scapy-driven UDP socket to a local decoder or your own display code, looping with a capture-accurate timing offset.
Everything stays on loopback. You are demonstrating a property of the protocol’s consumers—their inability to distinguish recorded from live messages—not transmitting anything. Keep it that way (see the ethics section).
Demonstrating the Risks: Tracking and Spoofing Scenarios
With the replay mechanics established, the threat model writes itself:
- Passive tracking. Anyone within reception range (or with a feed subscription) can track aircraft movements—executive jets, military transports, sensitive cargo—without any detection, because reception is invisible to the sender.
- Ghost aircraft injection. Craft a DF17 position message with an ICAO address not assigned to any aircraft, feed it to a receiver or aggregator, and a phantom contact appears on the map. Researchers have demonstrated exactly this against tracking aggregators, producing aircraft that never existed—including deliberately implausible ones (the 2020-era demonstrations of spoofed flights tracing cartoon shapes on public trackers).
- Identity spoofing. Craft messages using a real aircraft’s ICAO address and callsign at fabricated positions. Downstream systems now show two aircraft sharing one identity, or one aircraft at a false location—a jamming-and-deception combination that has also been observed in conflict zones as GPS spoofing compounds the confusion.
The root cause in every case is the same: ADS-B has no sender authentication. A message’s only “identity” is the ICAO address it claims, and anyone can claim anything.
Blue-Team Takeaways and Defenses
You cannot fix the protocol tomorrow, but you can detect abuse. Practical anomaly detection ideas for anyone operating ADS-B aggregation or monitoring infrastructure:
- Plausibility checks. Reject ground speeds above ~1,000 knots, negative altitudes, position jumps exceeding max achievable displacement between message timestamps, and altitude/vertical-rate inconsistencies.
- Duplicate ICAO detection. Alert when one ICAO address appears at two locations simultaneously, or when the same address reports inconsistent aircraft type codes or callsigns.
- Route and flight-plan correlation. Cross-reference ADS-B positions against filed flight plans, scheduled routes, and MLAT-derived ground truth.
- Multilateration (MLAT). Independent timing-based position verification across multiple receivers can expose a spoofer who can’t control receiver geometry.
- Signal-layer analysis. Researchers have proposed physical-layer fingerprinting (RF signatures of individual transponders) and cryptographic authentication schemes (e.g., TESLA-based broadcast authentication in OpenSky’s research) as long-term mitigations.
The pattern generalizes: when a telemetry protocol lacks authentication, defense shifts entirely to the consumer—cross-validation, plausibility, and multi-source corroboration. That’s the same architecture principle behind Zero Trust, applied to the sky.
Ethics, Legality, and Lab Boundaries
Draw the line clearly and never cross it. Receiving and decoding ADS-B and ACARS is legal in most jurisdictions—thousands of hobbyists feed community networks with receivers. Transmitting on 1090 MHz or ACARS VHF frequencies is illegal in the US, EU, and essentially everywhere: it requires no license to interfere with safety-of-life aviation spectrum, and doing so violates radio regulations (FCC rules in the US, ETSI/ITU allocations elsewhere) and potentially criminal statutes. This lab uses recorded public data and loopback replay exclusively. If your replay packets can leave localhost, your lab is misconfigured.
Frequently Asked Questions
Is it legal to capture and decode ADS-B traffic?
Receiving is generally legal in most jurisdictions; transmitting on aviation frequencies is not. Keep the lab receive-only or feed-based. In the US, FAA regulations govern broadcasts, and FCC rules govern the spectrum—but listening is not transmitting, and community feed projects exist precisely because passive reception is broadly accepted.
Do I need an SDR dongle to follow this lab?
No. This lab uses publicly available feed data and recorded message dumps instead of RF captures. Community feeds like adsb.lol and the OpenSky Network API provide everything, and a short Python script saves the raw frames to disk for offline analysis.
Why aren’t ADS-B and ACARS encrypted?
Legacy broadcast design prioritizes universal interoperability and low-cost avionics. Encryption would also break the broadcast model—every receiver, including other aircraft, must read every message. Authentication retrofits are still under research; broadcast authentication schemes have been proposed but not mandated.
Can someone spoof an aircraft on flight trackers?
Yes—researchers have demonstrated injected “ghost” aircraft on aggregation platforms. This lab demonstrates replay against local tooling only, never over the air. The demonstration requires nothing exotic because the protocol carries no authentication, which is exactly the point.
What Wireshark version and dissectors work for ADS-B?
Any recent Wireshark works. Mode S frames are typically imported as raw bytes and dissected via custom display filters or companion tools like dump1090/readsb, since Wireshark’s core value here is triage and stream reconstruction rather than full ADS-B decoding.
Related reading
- Build a PCAP Triage Lab with Zeek and T-Shark: Spot C2 Beacons in Real Traffic
- Write YARA Rules That Catch Ransomware Families: A Detection Lab with yara-python
