Hijacking drones with a MAVLink exploit

3689669085?profile=original

From Shellintel (via Hackaday)

Recently some of us here at shellntel have been building quadcopters and autonomous vehicles for fun.  We are big fans of the Pixhawk flight controller for its awesome autonomous capabilities.  We are also big fans of privacy.  As much as we like to build and fly these drones, we realize doing so in an irresponsible way can cause concern. We started looking into the various drone communications and discovered a design flaw that allowed us to take control of any drone flying with a specific telemetry protocol.

Telemetry allows the drone to exchange information and commands wirelessly with a ground station. This includes sending/receiving GPS coordinates, waypoints, throttle adjustments, arm and disarm commands, pretty much anything, including a serial shell.

The design flaw is not unique to PixHawk, but rather with the Mavlink protocol. Mavlink is used by many companies including:  Parrot AR.Drone (with Flight Recorder), ArduPilot, PX4FMU, pxIMU, SmartAP, MatrixPilot, Armazila 10dM3UOP88, Hexo+, TauLabs and AutoQuad. All of these companies make great products, but if they adopt the Mavlink protocol as is, it may be possible to hijack their drones (and any other drone using Mavlink).

According to its documentation, each Mavlink radio pair is setup with a NetID or channel.  This is done to prevent two radio pairs from interfering with each other.  By default this value is set to 25, but the user can change this setting. To hijack one of these drones, all you'd need to do is set your transmitter to the same NetID as the target drone.

Looking at the protocol spec, each data packet sent by the radio includes the NetID in its transmission!  This means that all we need to do is listen for a single packet within the frequency spectrum, capture it, carve the NetID, and set our radio to use it.  This, is surprisingly easy.

Using these radios, we can modify the OSS firmware to simply do this.  The following changes were made to  radio.c which when compiled is flashed to the transmitter.

Original Code:

 // decode the header     
errcount = golay_decode(6, buf, gout);
if (gout[0] != netid[0] || gout[1] != netid[1]) {
// its not for our network ID
debug("netid %x %x\n",
(unsigned)gout[0],
(unsigned)gout[1]);
goto failed; }

Modified Code:

// decode the header         
errcount = golay_decode(6, buf, gout);
if (gout[0] != netid[0] || gout[1] != netid[1]) {
// its not for our network ID
/* Modified by __int128 */
// Set our radio to use the captured packets NetID
param_set(PARAM_NETID, gout[0]))
// Save the value to flash
param_save();
// To read the new value we need to reboot. Rebooting
RSTSRC |= (1 << 4);
/* End of what was added by __int128*/ }


The variable gout[0] is set earlier in the radio.c; which is populated with the NetID of all captured packets.  This block of code is only hit when our radio hears a packet from another radio set on a different NetID from ours (which is good because don’t want to reboot each time we hear a new packet).  Anyway, that’s it, 3 lines of code is all it takes to hijack any drone using Mavlink.  Compile it, flash the radio and you’re good to go.  It works surprisingly well and is super quick.  

E-mail me when people leave their comments –

You need to be a member of diydrones to add comments!

Join diydrones

Comments

  • // decode the header
    errcount = golay_decode(6, buf, gout);
    if (gout[0] != netid[0] || gout[1] != netid[1]) {
    // its not for our network ID
    /* Modified by __int128 */
    // Set our radio to use the captured packets NetID
    param_set(PARAM_NETID, gout[0]))
    // Save the value to flash
    param_save();
    // To read the new value we need to reboot. Rebooting
    RSTSRC |= (1 << 4);
    /* End of what was added by __int128*/

    You said that this modified code will work when NetID's of both transmitter and receiver radio are different. But this modified code is not working. Can you please give the updated code.

    Anyone reply for this?
  • Ugh, not a design flaw. Like already said before, this isn't a hack/exploit, it's a feature of the MAVLink protocol that can be used for malicious purposes. It's a good thing that this (=current implementation of control links as a whole) gets more public attention, I just wish it wasn't done with clickbaits.

    Oh well, once ready made devices with one big "crash all drones" button are sold for $20 from China, things will change fast.

  • Developer

    The general agreement made a long time ago, was that it made more sense to rely on the security of the transmission system, and not try and build security into the MAVLink.

    It is very important that the MAVLink is keep as light weight as possible since it is meant to support all types of scenarios. If you add encryption at that stage you then suddenly exclude a whole range of applications like for example any 8-bit AVR's system like APM1&2.

    The 433mhz transmission many of us use today, is a very basic system (original made with DIY in mind) without support for encryption. But there are plenty of other solutions out there that has. For example you could rely on WiFI WPA, or if you run Linux at both ends you could make a VPN/SSH pipe regardless of transmission system used.

  • The context of the article is not correct, it is NOT about hacking mavlink. Mavlink in itself is not secure, it is not designed to be at the moment so there is nothing to hack.

    It is about 'hacking' a specific 3DR radio, so any other telemetry link (bluetooth, xbee, wifi etc) using mavlink would in this context be without problems.

    But on the topic of taking control, that is really only possible IF the mavlink command implementation on the flightcontroller allows it. For example AutoQuad that is mentioned.. There is no control schema that makes it possible to take over the flightcontroller during flight. It is not in the code to take mavlink commands during flight. 

    Only on alternate codes follow me or point to flight exists and can take commands, but a simple switch to manual is all needed to stop it.

    So.. although a good find on the 3DR radio exploit, it is NOT about a mavlink exploit hence the article heading and context is not correct.

  • Very nice find. Thank you for posting the code. 

    The ability to hijack MAVLink is a bit more complicated than just knowing the NetID, although this will work if the many other radio configuration settings are left unchanged.

    There's a great analysis by a U.S. Air Force Captain given at the link below. As explained on pages 52 & 53 of the report, there are 3,790,800 possible radio configuration combinations! Therein lies the complication for a radio hijacker. For those worried about being hijacked, simply change a few of your radio config settings to greatly enhance your security. 

    Note: The link below will download a 2.9MB PDF file containing the report.

    VULNERABILITY ANALYSIS OF THE MAVLINK PROTOCOL FOR COMMAND AND CONT...

  • Excellent find. Exposing a vulnerability like this will bring about competition and change for a more secure and robust telemetry network for drones. As a user, I'm glad to hear that there are already some options from the comments above. 

  • This may force release of SiK AES128 firmware for Si1030 based radios which is already partially developed.

  • Christian,

    "The changes result in an overhead of 16 bytes of additional bandwidth use per MAVLink frame, which is potentially composed of many message. The computational overhead is dominated by encryption and decryption operations for each message send and receive."

    Means that you add additionnal processing and latency in your control link. Migt work if you get a lot of processing power, but it rules out most of the arduino bases autopilots.  

    So basically it is a question of purpose:

    do you want to make a conrol link for an application that is -by design - running on a Personnal Aera Network ??

  • I remember there was a discussion about secure Mavlink (sMavlink) started by Lorenz Meier in 2013.

    I don't know what was the result of this discussion...

    And i found the SMACCMPilot project, that uses a secured Mavlink communication:

    http://smaccmpilot.org/software/commsec-overview.html

    I haven't fully understood how this works in detail, but i assume they use a custom firmware for the SiK radios and a protocol wrapper between pure Mavlink protocol and the SiK radio protocol:

    http://smaccmpilot.org/software/gcs-smaccm-sik.html

  • I'm not quite sure if labelling it a Mavlink flaw or exploit is correct. From my point of view it's the radio and SIk code that is not securing the serial stream, which in this case is the Mavlink messages. From what I understand the NetID package headers are from the radio not the APM/PXH mavlink code.

    The question is where the security should be implemented, either on the radio to secure all communications regardless of protocol ie Mavlink or in the serial encapsulation itself. I'd expect that radio security would get better mileage and be more universally adopted. 

    BTW the RFD900+ supports AES out of the box, I'm not sure about the other HopeRF based radios as I don't use them much anymore. Might be time to turn it on.

    It's nice to know how to find out the NetID of other users though. Should come in handy for a stir! ;-)

This reply was deleted.