<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Oli</title>
    <description>The latest articles on DEV Community by Oli (@oliopti).</description>
    <link>https://dev.to/oliopti</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3995480%2F89af3d51-e361-4ccd-937a-8cec49373e4b.png</url>
      <title>DEV Community: Oli</title>
      <link>https://dev.to/oliopti</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/oliopti"/>
    <language>en</language>
    <item>
      <title>Spotting GPS spoofing on a drone — and flying on when the signal is gone</title>
      <dc:creator>Oli</dc:creator>
      <pubDate>Sun, 21 Jun 2026 16:42:14 +0000</pubDate>
      <link>https://dev.to/oliopti/spotting-gps-spoofing-on-a-drone-and-flying-on-when-the-signal-is-gone-1cl8</link>
      <guid>https://dev.to/oliopti/spotting-gps-spoofing-on-a-drone-and-flying-on-when-the-signal-is-gone-1cl8</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Follow-up to my MAVLink post. Same caveat: I'm a beginner doing this as a hobby. The results below come from two small experiments in ArduPilot SITL on a simple setup, so please don't read too much into the exact numbers.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  The weak link: a GPS that believes everything
&lt;/h2&gt;

&lt;p&gt;We secure the comms, encrypt the telemetry… and often forget the drone has another vital sense that's just as exposed: &lt;strong&gt;GPS&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The issue is structural. Civilian GPS isn't &lt;strong&gt;authenticated&lt;/strong&gt; — the receiver has no cryptographic way to check that the signals really come from satellites. So two attacks target it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Spoofing&lt;/strong&gt;: broadcasting fake navigation signals, stronger than the real ones, so the drone thinks it's somewhere it isn't.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Denial (jamming)&lt;/strong&gt;: drowning the GPS band to blind the drone entirely.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This isn't hypothetical: ships have reported impossible positions at sea, airliners have hit spoofing near conflict zones, and anti-drone "bubbles" exist around sensitive sites. The gear to spoof GPS reportedly costs only a few hundred euros now.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Two problems, two answers:&lt;/strong&gt; detect the attack, and survive even when you don't.&lt;/p&gt;

&lt;h2&gt;
  
  
  Part 1 — Catching the liar
&lt;/h2&gt;

&lt;p&gt;You can't verify the GPS signal itself (no authentication). But you can check its &lt;strong&gt;consistency&lt;/strong&gt; with everything else the drone senses.&lt;/p&gt;

&lt;p&gt;A modern drone doesn't rely on GPS alone: it runs an &lt;strong&gt;Extended Kalman Filter (EKF)&lt;/strong&gt; that fuses the accelerometer, gyro, barometer, etc., and continuously &lt;strong&gt;predicts&lt;/strong&gt; where it should be. If the GPS position matches the prediction, fine. If it suddenly diverges… that's suspicious.&lt;/p&gt;

&lt;p&gt;To quantify "diverge," I used the &lt;strong&gt;Mahalanobis distance&lt;/strong&gt;. Instead of a raw distance in metres, it measures how many standard deviations the GPS reading is from the prediction, &lt;strong&gt;weighted by the filter's uncertainty&lt;/strong&gt; (its covariance). That's the appealing part: tolerate normal GPS noise, but flag a statistically abnormal jump. A simple threshold can trigger the alarm.&lt;/p&gt;

&lt;p&gt;And for the clever attacker who &lt;strong&gt;slowly drifts&lt;/strong&gt; the position to stay under the radar? I added a &lt;strong&gt;CUSUM&lt;/strong&gt; test (cumulative sum), which catches a small systematic drift building up over time that an instantaneous threshold would miss.&lt;/p&gt;

&lt;h3&gt;
  
  
  What I saw in my test
&lt;/h3&gt;

&lt;p&gt;In SITL, drone hovering, I injected fake GPS coordinates. The result was quite visual: the Mahalanobis distance stayed flat while things were normal, then &lt;strong&gt;spiked&lt;/strong&gt; right at the moment of injection. A &lt;code&gt;SPOOF DETECTED&lt;/code&gt; alert fired and the failsafe took over. In my (limited) runs I didn't see false positives — but my setup was simple and the scenario clean, so I wouldn't generalise from that.&lt;/p&gt;

&lt;p&gt;The nice part is it runs &lt;strong&gt;without extra hardware&lt;/strong&gt;: it reuses the EKF already in the autopilot. No multi-antenna receiver, no atomic clock — just statistics on data you already have. (Real anti-spoofing systems are far more sophisticated; this is very much a learner's version of the idea.)&lt;/p&gt;

&lt;h2&gt;
  
  
  Part 2 — Surviving with no GPS
&lt;/h2&gt;

&lt;p&gt;Detection is nice. But what if you &lt;strong&gt;miss&lt;/strong&gt; it, or it's pure jamming — no signal at all? The drone still has to stay in control.&lt;/p&gt;

&lt;p&gt;First building block, already in the autopilot: &lt;strong&gt;dead reckoning&lt;/strong&gt;. From the IMU alone, ArduPilot keeps flying for a few seconds after GPS loss, then heads home. The snag: dead reckoning &lt;strong&gt;drifts&lt;/strong&gt; — without an external reference, position error piles up fast.&lt;/p&gt;

&lt;p&gt;Second block, to bound that drift: &lt;strong&gt;optical flow&lt;/strong&gt;. A small (~€25) sensor that looks at the ground and measures actual movement, a bit like an optical mouse. Fused into the EKF, it gives a motion reference that needs no satellite.&lt;/p&gt;

&lt;h3&gt;
  
  
  What I measured
&lt;/h3&gt;

&lt;p&gt;I compared three scenarios in SITL, drone flying, then GPS cut:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Scenario&lt;/th&gt;
&lt;th&gt;Max drift&lt;/th&gt;
&lt;th&gt;Mode after cut&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;A — Normal GPS (baseline)&lt;/td&gt;
&lt;td&gt;0.02 m&lt;/td&gt;
&lt;td&gt;normal flight&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;B — GPS lost, no defense&lt;/td&gt;
&lt;td&gt;0.67 m&lt;/td&gt;
&lt;td&gt;emergency landing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;C — GPS lost + optical flow&lt;/td&gt;
&lt;td&gt;0.15 m&lt;/td&gt;
&lt;td&gt;emergency landing&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;An honest reading: without GPS, the drone triggers an &lt;strong&gt;emergency landing&lt;/strong&gt; in both cases — optical flow does &lt;strong&gt;not&lt;/strong&gt; give "free" GPS-denied flight. What it does, and it's already a lot, is cut the drift by roughly &lt;strong&gt;4x&lt;/strong&gt; (0.67 m → 0.15 m) during that descent, so the drone lands where it is rather than ~70 cm away in the wind. And again — tiny experiment, simulation only, don't over-trust the figure.&lt;/p&gt;

&lt;p&gt;The way I'd put it: dead reckoning drifts, but it's better than nothing — enough for the drone to at least head home. I'd rather state that plainly than oversell an "autonomous no-GPS flight" my data doesn't show.&lt;/p&gt;

&lt;p&gt;On the ArduPilot side, the gist is three parameters: enable optical flow (&lt;code&gt;FLOW_TYPE&lt;/code&gt;), a rangefinder for altitude (&lt;code&gt;RNGFND1_TYPE&lt;/code&gt;), and the dead-reckoning failsafe (&lt;code&gt;FS_DR_ENABLE&lt;/code&gt;), with GPS staying the EKF's primary source while it's healthy.&lt;/p&gt;

&lt;h2&gt;
  
  
  Same flaw, two strategies
&lt;/h2&gt;

&lt;p&gt;Stepping back, GPS spoofing and MAVLink command injection seem to share &lt;strong&gt;the same root cause&lt;/strong&gt;: an input the system accepts without being able to authenticate it.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When you &lt;strong&gt;control the channel&lt;/strong&gt; (telemetry), you go for &lt;strong&gt;prevention&lt;/strong&gt;: signing + encryption.&lt;/li&gt;
&lt;li&gt;When you &lt;strong&gt;don't&lt;/strong&gt; (GPS, which you can't control), you go for &lt;strong&gt;detection + resilience&lt;/strong&gt;: spot the inconsistency, and stay in control even if detection fails.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That, as I understand it, is defense in depth on a drone: planning for your own defenses to fail.&lt;/p&gt;

&lt;h2&gt;
  
  
  Takeaways (beginner edition)
&lt;/h2&gt;

&lt;p&gt;GPS isn't a source of truth, it's just one more sensor — and one you can't authenticate. So &lt;strong&gt;cross-check it&lt;/strong&gt; against your internal estimate, and &lt;strong&gt;plan for the worst&lt;/strong&gt;, i.e. flying without it.&lt;/p&gt;

&lt;p&gt;Good news: most of these protections (EKF, dead-reckoning failsafe, optical-flow support) are already in ArduPilot. The work is &lt;strong&gt;enabling, tuning and testing&lt;/strong&gt; them — not reinventing the wheel. I'm still very much in the testing-and-learning phase, so corrections are welcome.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Happy to share more detail in the comments.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>cybersecurity</category>
      <category>drones</category>
      <category>gps</category>
      <category>ardupilot</category>
    </item>
    <item>
      <title>MAVLink: the protocol behind millions of drones (and why it isn't secure by default)</title>
      <dc:creator>Oli</dc:creator>
      <pubDate>Sun, 21 Jun 2026 16:40:46 +0000</pubDate>
      <link>https://dev.to/oliopti/mavlink-the-protocol-behind-millions-of-drones-and-why-it-isnt-secure-by-default-3n8m</link>
      <guid>https://dev.to/oliopti/mavlink-the-protocol-behind-millions-of-drones-and-why-it-isnt-secure-by-default-3n8m</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Quick disclaimer: I'm still learning this stuff. This comes out of a small personal project where I'm trying to secure the link between a hobby drone and its ground station. Everything below was tested in simulation (ArduPilot SITL) and a little on real hardware, on a very modest setup — so please take my own results with a grain of salt.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Context: a protocol everywhere, secured nowhere
&lt;/h2&gt;

&lt;p&gt;If you build an open-source drone today, chances are it speaks &lt;strong&gt;MAVLink&lt;/strong&gt; — the communication protocol between the drone and its ground control station (GCS), used by ArduPilot and PX4, running on millions of devices.&lt;/p&gt;

&lt;p&gt;The catch: MAVLink was designed for one thing — &lt;strong&gt;performance&lt;/strong&gt;. Compact packets, low latency, long range. Security wasn't part of the original spec, and it shows.&lt;/p&gt;

&lt;h2&gt;
  
  
  MAVLink in 30 seconds
&lt;/h2&gt;

&lt;p&gt;The drone and the GCS constantly exchange two kinds of messages: &lt;strong&gt;commands&lt;/strong&gt; going down (take off, go to this point, land) and &lt;strong&gt;telemetry&lt;/strong&gt; coming up (position, altitude, battery, status). It all starts with a &lt;code&gt;HEARTBEAT&lt;/code&gt; sent every second to keep the link alive.&lt;/p&gt;

&lt;p&gt;Simple, efficient… and, as far as I can tell, wide open.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem: MAVLink v1 protects nothing
&lt;/h2&gt;

&lt;p&gt;MAVLink version 1 has &lt;strong&gt;no encryption, no authentication, no signing&lt;/strong&gt;. From what I understand, an attacker within radio range can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;listen&lt;/strong&gt; to all telemetry in clear (your position, your flight plan);&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;inject&lt;/strong&gt; fake commands, since nothing checks who sends them;&lt;/li&gt;
&lt;li&gt;run a man-in-the-middle attack, or replay old packets.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This isn't just theory — it's documented in &lt;strong&gt;CVE-2020-10282&lt;/strong&gt; (CWE-306, "Missing Authentication for Critical Function"), rated around 9.6/10. The weakness isn't an implementation bug; it's in the protocol design itself.&lt;/p&gt;

&lt;h2&gt;
  
  
  The catch with v2
&lt;/h2&gt;

&lt;p&gt;MAVLink 2 added &lt;strong&gt;optional signing&lt;/strong&gt; based on HMAC-SHA256. On paper that's the right idea: a shared secret key, and each message carries an authentication code over its content plus a timestamp; unsigned or badly signed messages get rejected.&lt;/p&gt;

&lt;p&gt;But, from what I've read:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Signing is &lt;strong&gt;optional&lt;/strong&gt; and off by default.&lt;/li&gt;
&lt;li&gt;To stay backward-compatible, the GCS and drone &lt;strong&gt;negotiate&lt;/strong&gt; the version — and an attacker can craft packets that force a fallback to &lt;strong&gt;MAVLink v1&lt;/strong&gt;, where there's no protection at all. The classic &lt;em&gt;downgrade attack&lt;/em&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;So just turning signing on isn't enough if you don't also &lt;strong&gt;force&lt;/strong&gt; v2 and block the downgrade. (I'm honestly still figuring out the cleanest way to do that.)&lt;/p&gt;

&lt;h2&gt;
  
  
  What about the radio link?
&lt;/h2&gt;

&lt;p&gt;Telemetry is only half the picture. On a lot of FPV drones the control link runs over &lt;strong&gt;ExpressLRS (ELRS)&lt;/strong&gt;. Back in 2022, NCC Group published an analysis worth knowing about: the ELRS &lt;em&gt;binding phrase&lt;/em&gt; is &lt;strong&gt;not a security mechanism&lt;/strong&gt; — the developers say so themselves, it's anti-collision.&lt;/p&gt;

&lt;p&gt;The uncomfortable detail: a single sync packet apparently leaks about 75% of the unique identifier needed to take over the link, and the rest can be brute-forced. With a standard ELRS radio, an attacker could hijack the control link. (Worth noting the ELRS team pushed back on parts of how this was reported — but the core point stands.)&lt;/p&gt;

&lt;p&gt;The general lesson I'm taking from this: &lt;strong&gt;don't confuse "pairing" with "authentication."&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I tried on my own build
&lt;/h2&gt;

&lt;p&gt;I'm not trying to reinvent cryptography — way above my level. I just wanted to see whether I could reproduce, on a hobby budget, the basic ideas you find in proper solutions. I went for &lt;strong&gt;layered defense&lt;/strong&gt; on the telemetry link:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Layer 1 — Authentication: MAVLink2 signing (HMAC-SHA256).&lt;/strong&gt;&lt;br&gt;
Enabled on the autopilot side, it should block injection: without the key you can't forge a valid command, and the timestamp kills replays.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;&lt;span class="c"&gt;# Force MAVLink2 on the telemetry port (no v1 fallback)
&lt;/span&gt;&lt;span class="n"&gt;SERIAL1_PROTOCOL&lt;/span&gt; = &lt;span class="m"&gt;2&lt;/span&gt;
&lt;span class="c"&gt;# Signing (32-byte key) is set on the GCS side
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Layer 2 — Confidentiality: AES-256-GCM encryption.&lt;/strong&gt;&lt;br&gt;
Signing authenticates but doesn't &lt;strong&gt;encrypt&lt;/strong&gt; — telemetry stays readable. So I added an encryption proxy on a small companion computer, between the flight controller and the radio. GCM also gives integrity (a tampered packet is rejected).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Layer 3 — Stacking.&lt;/strong&gt;&lt;br&gt;
Both layers add up: signature &lt;strong&gt;and&lt;/strong&gt; encryption. If one fails, the other still stands. That's the whole idea of defense in depth — at least as I understand it.&lt;/p&gt;

&lt;p&gt;Rough takeaway: signing blocks injection, encryption blocks eavesdropping, and together they cover the link. I want to stress these were small tests, not a rigorous evaluation.&lt;/p&gt;

&lt;h2&gt;
  
  
  The real hard part: keys, not the algorithm
&lt;/h2&gt;

&lt;p&gt;Picking AES or ChaCha20 is the easy bit. The hard part — and the part I'm least sure about — is &lt;strong&gt;key management&lt;/strong&gt;. If a symmetric key sits in the drone's flash and someone gets hold of the drone, they can pull the key and impersonate a legit drone to your GCS.&lt;/p&gt;

&lt;p&gt;One idea I find interesting (still reading about it): a drone that stores &lt;strong&gt;no permanent secret&lt;/strong&gt;, deriving an ephemeral session key in RAM at each boot via a Diffie-Hellman exchange, so everything disappears on power-off. If the drone is captured, you'd recover generic hardware and an empty RAM. I haven't implemented this properly yet — it's on my "learn this next" list.&lt;/p&gt;

&lt;h2&gt;
  
  
  Takeaways (from a beginner)
&lt;/h2&gt;

&lt;p&gt;MAVLink is a great protocol — open, efficient, universal. But "open and efficient" doesn't mean "safe." Security isn't built in; it has to be added on top, ideally from the design stage, and on &lt;strong&gt;every&lt;/strong&gt; link, not just telemetry.&lt;/p&gt;

&lt;p&gt;If you run an open-source drone for anything beyond fun, maybe ask yourself: is my telemetry encrypted? are my commands signed &lt;strong&gt;and&lt;/strong&gt; is v1 blocked? does my control link rely on real authentication, or on a "binding phrase" that isn't one?&lt;/p&gt;

&lt;p&gt;I'm still early in this, so if you spot something I got wrong, please tell me in the comments — I'd genuinely like to learn.&lt;/p&gt;

&lt;p&gt;Next time: the other half of the problem — &lt;strong&gt;GPS&lt;/strong&gt;. How to spot spoofing, and how to keep flying with no satellite signal.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Questions or corrections very welcome below.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>cybersecurity</category>
      <category>drones</category>
      <category>iot</category>
      <category>mavlink</category>
    </item>
    <item>
      <title>Reverse engineering a DJI Mavic Pro remote: meeting the DUML protocol</title>
      <dc:creator>Oli</dc:creator>
      <pubDate>Sun, 21 Jun 2026 16:39:33 +0000</pubDate>
      <link>https://dev.to/oliopti/reverse-engineering-a-dji-mavic-pro-remote-meeting-the-duml-protocol-3j5e</link>
      <guid>https://dev.to/oliopti/reverse-engineering-a-dji-mavic-pro-remote-meeting-the-duml-protocol-3j5e</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;A hobby project on the side. I bought a Mavic Pro Gen1 shell and its &lt;strong&gt;GL200A&lt;/strong&gt; remote for a few euros, sold as non-functional. Rather than just repairing them, I wanted to understand &lt;strong&gt;how they talk to each other&lt;/strong&gt;. This is my logbook — and I want to be upfront that I'm a beginner at reverse engineering, standing on the shoulders of a community that did the hard work.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  First: is this legal?
&lt;/h2&gt;

&lt;p&gt;It's &lt;strong&gt;the&lt;/strong&gt; question to ask before touching someone else's hardware — and in Europe the answer is nuanced but reassuring.&lt;/p&gt;

&lt;p&gt;The EU Software Directive (2009/24/EC) explicitly allows you to &lt;strong&gt;observe, study and test&lt;/strong&gt; how a program works to understand its underlying principles (Article 5). Decompilation (Article 6) is permitted without authorisation when it's for &lt;strong&gt;interoperability&lt;/strong&gt; of an independently created program. Vulnerability research on a device &lt;strong&gt;you legally own&lt;/strong&gt; fits this frame, as I understand it (and to be clear, I'm not a lawyer).&lt;/p&gt;

&lt;p&gt;What you &lt;strong&gt;can't&lt;/strong&gt; do: build a substantially similar commercial clone, redistribute the proprietary code you extract, or ignore patents. My case: I bought the hardware, I explore it to understand and learn, I don't resell anything, and I don't break DJI's firmware encryption. It seems within bounds — but if you do this, check your own jurisdiction.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Personal rule: I document interoperability and security, never circumvention. No bypassing flight restrictions, no tweaking the device to do things it isn't allowed to.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  The playground: the GL200A over USB
&lt;/h2&gt;

&lt;p&gt;First reflex: plug the remote into a Linux machine and see what it exposes. And for a "closed consumer device," it turns out to be surprisingly &lt;strong&gt;chatty&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;USB enumeration reveals three interfaces at once:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a &lt;strong&gt;serial port&lt;/strong&gt; (CDC ACM, &lt;code&gt;/dev/ttyACM0&lt;/code&gt;);&lt;/li&gt;
&lt;li&gt;a &lt;strong&gt;network interface&lt;/strong&gt; (RNDIS), the remote presenting itself as a small gateway;&lt;/li&gt;
&lt;li&gt;a &lt;strong&gt;mass storage&lt;/strong&gt; gadget, proudly announced as &lt;em&gt;"DJI File-CD Gadget."&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A port scan on the network interface shows about a dozen open TCP ports. And the most telling part: an &lt;strong&gt;FTP open to anonymous access&lt;/strong&gt;, no credentials. Inside, part of a filesystem — logs, panic dumps, SDR configs, update files. The firmware itself is AES-encrypted by DJI (and I didn't try to break that). But the fact that all this is &lt;strong&gt;open to anyone who plugs in a cable&lt;/strong&gt; says a lot.&lt;/p&gt;

&lt;h2&gt;
  
  
  The heart of it: the DUML protocol
&lt;/h2&gt;

&lt;p&gt;All internal communication in the DJI ecosystem runs on &lt;strong&gt;DUML&lt;/strong&gt; (DJI Universal Markup Language). It's a binary protocol, and the good news for a learner is that it's &lt;strong&gt;already well documented&lt;/strong&gt; by the community — notably the open-source &lt;code&gt;dji-firmware-tools&lt;/code&gt; and &lt;code&gt;dji_rev&lt;/code&gt;, which include dissectors for DUML packets. I'm mostly retracing steps others mapped out.&lt;/p&gt;

&lt;p&gt;The packet structure is regular, which helps a lot: a &lt;strong&gt;magic byte&lt;/strong&gt; (&lt;code&gt;0x55&lt;/code&gt;) up front, length fields, a &lt;em&gt;command set&lt;/em&gt; and &lt;em&gt;command id&lt;/em&gt; identifying the order, an acknowledgement type, the payload, and a CRC. Once you have that template in mind, a raw serial capture becomes readable — you see the &lt;code&gt;0x55&lt;/code&gt; bytes scrolling by at regular intervals.&lt;/p&gt;

&lt;h3&gt;
  
  
  The detail that unlocked things
&lt;/h3&gt;

&lt;p&gt;At first the remote answered every message with a &lt;strong&gt;universal NACK&lt;/strong&gt;. Frustrating. The breakthrough: you need the right &lt;strong&gt;acknowledgement type&lt;/strong&gt;. With &lt;code&gt;ack_type = 2&lt;/code&gt; the radio (OFDM) module finally answers; with &lt;code&gt;ack_type = 1&lt;/code&gt; it's NACK every time. (To be clear, I found this by trial and error and by reading the tools, not by any cleverness of my own.)&lt;/p&gt;

&lt;p&gt;From there the device starts talking. The module even introduces itself: &lt;code&gt;WM220 SDR_HDVT_GND&lt;/code&gt;. I confirmed a handful of &lt;strong&gt;bidirectional&lt;/strong&gt; DUML commands on the remote — a version query (returning something like &lt;code&gt;ldr v08.00.00.09, app v00.00.01.28&lt;/code&gt;), device state, RC detection info, and so on.&lt;/p&gt;

&lt;p&gt;Exploring the TCP ports, I also stumbled onto a proprietary protocol (I nicknamed it &lt;strong&gt;f364&lt;/strong&gt;) where one stream spits out… &lt;strong&gt;plaintext debug logs&lt;/strong&gt; from the radio stack: MAC-layer internals, scheduler details, security frames. Information that really shouldn't be on an open channel.&lt;/p&gt;

&lt;h3&gt;
  
  
  A bit of tooling
&lt;/h3&gt;

&lt;p&gt;Most of the exploration used &lt;code&gt;dji-firmware-tools&lt;/code&gt; (the &lt;code&gt;comm_serialtalk.py&lt;/code&gt; utility, to talk to a specific module), plus a small homemade &lt;strong&gt;DUML fuzzer&lt;/strong&gt;: it sweeps the command space and only counts a reply as valid if it exactly matches the request (matching on &lt;code&gt;seq&lt;/code&gt; + command set + command id + ACK type), to avoid false positives. Less glamorous than an exploit, but that's where most of real reversing happens — patiently mapping an unknown surface.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it teaches, security-wise
&lt;/h2&gt;

&lt;p&gt;Beyond the fun of making an old radio module talk, this is a &lt;strong&gt;case study in classic mistakes&lt;/strong&gt; in embedded security — the ones &lt;strong&gt;not&lt;/strong&gt; to repeat if you design a connected product:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;An open anonymous FTP on a consumer device.&lt;/strong&gt; Plugging in a cable should never be enough to browse a filesystem.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Plaintext debug logs on an accessible channel.&lt;/strong&gt; The internals of a radio stack are exactly what an attacker wants. Debug should be disabled (or protected) in production.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lots of interfaces exposed by default.&lt;/strong&gt; Three USB gadgets plus a dozen ports: every open interface is a door. Attack surface should shrink, not sprawl.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The general lesson, drone or not: &lt;strong&gt;a "closed" device is only closed on the surface.&lt;/strong&gt; As long as there's a physical interface, there's something to observe — and therefore something to harden.&lt;/p&gt;

&lt;h2&gt;
  
  
  Takeaways (beginner edition)
&lt;/h2&gt;

&lt;p&gt;Reverse engineering hardware you own is a fantastic way to learn: you touch binary protocols, RF, embedded systems, and exploration methodology. And it's &lt;strong&gt;legal&lt;/strong&gt; when you respect the frame (legally acquired hardware, interoperability or research purpose, no clone, no redistribution of proprietary code).&lt;/p&gt;

&lt;p&gt;My advice for getting started — as someone who just got started: pick a device with mature community tooling (the Mavic Pro Gen1 is a great choice thanks to &lt;code&gt;dji-firmware-tools&lt;/code&gt;), &lt;strong&gt;observe&lt;/strong&gt; before you &lt;strong&gt;talk&lt;/strong&gt;, and document everything. Patience beats exploits.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Corrections and pointers very welcome — I'm here to learn.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>reverseengineering</category>
      <category>cybersecurity</category>
      <category>drones</category>
    </item>
  </channel>
</rss>
