Some Vulnerabilities about MAVLink Protocol v2.0

115 views
Skip to first unread message

F ei Du

unread,
Sep 16, 2024, 2:29:30 AM9/16/24
to MAVLink
Dear developers,

We have discovered several vulnerabilities in MAVLink protocol version 2 as follows: 
  1.  The current authentication mechanism of MAVLink protocol version 2.0 based on symmetric key cryptography is weak to the brute force attack. Even worse, some real-world GCS softwares can not update the secret key correctly and frequently (see Finding 1), which even enhances the probability to disclose the secret key.
  2. The current MAVLink protocol v2.0 lacks proper sequence number verification, meaning that a malicious message can use any sequence number between 0 and 255, and it will still be accepted by the UAV. This vulnerability allows attackers to bypass sequence number validation entirely. Additionally, the sequence number's intended functionality to detect packet loss is also ineffective, leaving the system vulnerable to potential message injection and disruption without triggering any packet loss detection mechanisms. 
  3. The current timestamp checking is not effective during the communication. A message with any time can be accepted and executed (e.g., 2015/01/01 or 2030/01/01) which violates the rules of timestamp verification.

In order to address them, we are preparing a paper whereby several countermeasures have been proposed. A portion of our drafted paper as well as the countermeasures are attached. 

Looking forward to your reply. 
Thank you!
Draft.pdf

Hamish Willee

unread,
Sep 17, 2024, 7:03:42 PM9/17/24
to MAVLink
Yes. MAVLink was not designed for security. The only security feature is the message signature, which is designed to ensure that a vehicle will only obey commands that have been signed by a trusted key.
If you can sample a bunch of messages and brute force attach that sample to decode them, that is something that should be noted - i.e. to outline just how much effort is is to break.

Those who need a secure link run MAVLink over an encrypted transport layer/radio link.

There has been some talk about making the protocol itself more secure at various points - including this implementation https://github.com/mavlink/mavlink/pull/1334.
From the discussions I've been part of it seems any robust solution would need to piggy-back on a transport layer that already implemented the security aspects: security is hard to get right and maintain so we'd need to borrow.
Even that would require a lot of work because MAVLink is designed to fun across a whole range of networks, some which are far lower bandwidth than you'd be expecting - and you need to think about whether security is worth the cost, and how to handle cases where you might be routed/bridged onto these networks.
Upshot, is that there isn't any strong pull to add this to MAVLink itself. If you're really interested in this as a practical rather than theoretical exercise you'd need to work with a flight stack and ground station and show that you can solve the various problems involved.

Just a couple of points to your points

 The current authentication mechanism of MAVLink protocol version 2.0 based on symmetric key cryptography is weak to the brute force attack. Even worse, some real-world GCS softwares can not update the secret key correctly and frequently (see Finding 1), which even enhances the probability to disclose the secret key.

True. It isn't even implemented on some flight stacks. 

>  
The current MAVLink protocol v2.0 lacks proper sequence number verification, meaning that a malicious message can use any sequence number between 0 and 255, and it will still be accepted by the UAV. This vulnerability allows attackers to bypass sequence number validation entirely. Additionally, the sequence number's intended functionality to detect packet loss is also ineffective, leaving the system vulnerable to potential message injection and disruption without triggering any packet loss detection mechanisms. 

The only purpose of the sequence number is for detecting packet loss.  It does that very well on networks where all packets from a source are directed to the sink (GCS). 
So yes, MAVLink will accept any sequence number. The messages are intended to be idempotent so that it doesn't matter if they arrive out of order in order to execute them.

> T
he current timestamp checking is not effective during the communication. A message with any time can be accepted and executed (e.g., 2015/01/01 or 2030/01/01) which violates the rules of timestamp verification.

There is no timestamp checking. Some messages have timestamps that are checked, but that is not part of the protocol per-se - it isn't standard in the packet. https://mavlink.io/en/guide/serialization.html



F ei Du

unread,
Sep 18, 2024, 4:58:52 AM9/18/24
to MAVLink
Regarding the issue of timestamp, we found that there is a statement saying "The timestamp on incoming signed messages should be checked against the previous timestamp for the incoming (linkID,srcSystem,SrcComponent) tuple and the message rejected if it is smaller." in the link https://mavlink.io/en/guide/message_signing.html;

However, when we inject the signed message using arbitrary timestamp, which can be accepted, and the timestamp wasn't checked against the previous timestamp.

We also found the following statement from the official website, wasn't implemented:
微信图片_20240918165456.png
Thanks.

Hamish Willee

unread,
Sep 18, 2024, 8:48:13 PM9/18/24
to MAVLink
Thanks very much. We're very interested in fixing vulnerabilities, and if we say that signing provides a certain level of security then it needs to do so (and that level needs to be clear).
Note though that not all of these issues may be in the scope of MAVLink itself to fix, or are design decisions based on the environment that the protocol is used.
Some of them however may be be things that should be considered by adopter GCS.

1. >  Vulnerability 1: The current authentication mechanism of MAVLink protocol version 2.0 based on symmetric key cryptography is weak to the brute force attack. Even worse, some real-world GCS softwares can not update the secret key correctly and frequently (see Finding 1), which even enhances the probability to disclose the secret key. b) Injection Attack: On the basis of

The passphrase policy is not enforced in MAVLink and shouldn't be: what MAVLink provides is a way for users of the libraries to exchange and use a passphrase. It is up to the GCS to do proper enforcement.

My understanding is that Mission Planner GCS allows any passphrase, so that is a arguably a vulnerability in that GCS - it is not something we can or should fix in MAVLink.
I say "arguably", because users have a choice here - if they want to use a rubbish password that is reasonable to allow in open source software. I would expect an enterprise GCS to enforce strong passwords.

A vulnerability would be that the key length we use for the signature is too short, so that a brute force attack even on a good password can be cracked in a useful timeframe - is that the case?

2. Vulnerability 2: The current MAVLink protocol v2.0 lacks proper sequence number verification, meaning that a malicious message can use any sequence number between 0 and 255, a

There is no expectation by the receiver that messages will be sequential.
Messages may be routed anywhere, and the same message might be routed over both low and high latency links.
Further, packet loss on low bandwidth telemetry radios is high, and this isn't a "reliable communication protocol" like TCPIP.
Presenting this as a vulnerability is therefore unreasonable when the expectation of sequential numbers is not required.

3.  Vulnerability 3: The current timestamp checking is not effective during the communication. A message with any time can be accepted and executed (e.g., 2015/01/01 or 2030/01/01) which violates the rules of timestamp verification.

Yes, signed packets do include a timestamp and the documentation you point to should be followed for accepting signed packets (sorry about my previous comments)

What makes you think this is not implemented? The signature check returns false here if the packets are out of date:  https://github.com/ArduPilot/pymavlink/blob/master/generator/C/include_v2.0/mavlink_helpers.h#L191 in the C library, and there is similar code in Pymavlink.
As per those docs (https://mavlink.io/en/guide/message_signing.html#accepting_incorrectly_signed_packets), it is then up to the systems using MAVLink to determine how they handle an incorrectly signed packet.
I don't know what various systems do in this case but I suspect they drop the packets and reject communication - except commonly they will allow it when connected via USB, as physical possession of the drone is considered reasonable access.

Thoughts?

Peter Barker

unread,
Sep 18, 2024, 9:39:34 PM9/18/24
to MAVLink
Firstly, *thankyou* for looking into these issues.  We do appreciate the time people invest into this sort of analysis!

A couple of points on your draft.

seqno was never put forward as a protection against replay attacks.  Ever, AFAIK.  The fact it wraps at 256 and is used on links where hundreds of messages can be transfered each second should be sufficient to see its inadequate for this purpose.

seqno was fit-for-purpose as an indication of link quality when mavlink connections were point-to-point.  In today's increasingly complex mavlink networking setups its utility is decreating.  We've given some thought to a replacement mechanism but nothing concrete has been proposed.


Your paper makes reference to using SITL, and MAVProxy's "output add".  Those are warning signs for me.

Some background: when using a physical autopilot, ArduPilot *trusts* that if you are connected to the USB port of the autopilot then you are an authorized user of the autopilot and bypasses all signing checks.  We do this so that if a user loses their passphrase then they can recover their vehicle.  This is absolutely a trade-off, convenience versus security, but we believe that the physical proximity to the autopilot is sufficient to permit this bypass.  See https://ardupilot.org/copter/docs/common-MAVLink2-signing.html where USB is explicitly mentioned as being excluded from these checks.

When you start ArduPilot SITL, the ArduPilot process connects to port 5760.  That port is effectively treated as a USB port!  Which is to say, *no signing checking is done on that port*.  If you create a link to another GCS via "output add" (or "--output" on the command-line), then that forwarded link *gains the same bypass nature* as that original MAVProxy started as part of "sim_vehicle.py"!  I have created https://github.com/ArduPilot/ardupilot_wiki/pull/6289 to avoid this confusion.

The correct way to test signing is working is to connect another GCS to a port which enforces signing when it is configured - typically port 5762.



On the matter of the MissionPlanner key interface, I confess to not being overly familiar with it.  I have brought it to the attention of the maintainer.  As you push this paper through I would suggest linking to an issue created against the MissionPlanner github repository would be appropriate.

MissionPlanner using a stale key to continue to talk to the vehicle is a deliberate choice; instantly losing link to the vehicle isn't necessarily what the user wants.


The use of a poor passphrase is an operator error, albeit one where the GCS which is helping the user set up the signing should warn that user.  The MissionPlanner maintainer agrees that a "passphrase strength" indicator where you enter the passphrase would be a good improvement.  The dictionary attack you describe could be applied against any service which relies on a user-generated secret to maintain security.  Creating a "session key" protocol seems unnecessary if the user has chosen a suitably strong secret.  It is possible we do not emphasize enough in our documentation that the strength of this passphrase is absolutely vital.


The use of public-key cryptography and the possibility of encryption was discussed extensively before the current MAVLink2 signing was implemented.  The nature of the implementation environment poses significant challenges to these - mostly around resource limitations but also around connectivity limitations of the devices.  Our usual response to queries on implementing these features is to accomplish these goals at a lower layer.


Please note I am *very* interested in your assertion that our timestamp protection is not working in MAVLink signing - particularly in ArduPilot.  If that is, indeed, the case, then please provide more details on this attack.

Also note that over time the resources available to secure these connections will improve.  However, signing was first introduced into ArduPilot in January 2016.  While the upper-end of STM32 processors (STM32 processors comprise the vast majority of ArduPilot installatiions) has improved in capabilities significantly, the majority of new boards ArduPilot supports are actually based on STM32F405 - which was released in 2011!

Yours,

Peter

F ei Du

unread,
Sep 19, 2024, 8:50:51 AM9/19/24
to MAVLink
Dear,

Really thanks for your clarifying about the points I mentioned. I have a clear understanding about them :)

For the vulnerability 1, from now on we tested some simple password, and it is easy for brute force attack. For the most complex password maybe it is more secure, we might do more tests for your question about vulnerability 1.

As you said, the port 5760 is featured as  *no signing checking is done on that port*, I think that's right, for the injection attack using this port, a return-to-launch command is successfully accepted and implemented, and I post a snapshot, showing the malicious message captured using wireshark below. For this port, any timestamp can be valid.幻灯片1.PNG

And for port 5762 you suggested, I did another test. The Ardupilot was started with command "sim_vehicle.py --console --map", and for MAVProxy, I indicate the master with "--master=tcp:127.0.0.1:5762", and output "--out=udp:10.0.2.8:14551" for connecting the MissionPlanner. Then establish the connection with port 14551. Then the message will be transmitted through the 5762 tcp port and 14551 udp port. There are same result, I think the timestamp verification is still bypass. The snapshots shown below:
幻灯片1.PNG2.png

If there are any mistakes on my test please figure out :)

Thank You.

Peter Barker

unread,
Oct 26, 2024, 11:56:58 PM10/26/24
to mav...@googlegroups.com
This *may* be the same issue discussed here: https://github.com/ArduPilot/pymavlink/issues/961

I've poked tridge to make sure we get to the bottom of this.

Peter


--
Sie erhalten diese Nachricht, weil Sie in Google Groups ein Thema der Gruppe "MAVLink" abonniert haben.
Wenn Sie sich von diesem Thema abmelden möchten, rufen Sie https://groups.google.com/d/topic/mavlink/V2YApLwUROw/unsubscribe auf.
Wenn Sie sich von dieser Gruppe und allen Themen dieser Gruppe abmelden möchten, senden Sie eine E-Mail an mavlink+u...@googlegroups.com.
Wenn Sie diese Diskussion im Web verfolgen möchten, rufen Sie https://groups.google.com/d/msgid/mavlink/66d964a9-10cd-4db8-ae60-6c27e0b00c1fn%40googlegroups.com auf.
Reply all
Reply to author
Forward
0 new messages