
Proof-of-Concept zur Ausnutzung der DUML-Befehlsinjektion über Bluetooth bei DJI-Drohnen, das unauthentifizierte Befehle sendet, um Anmeldedaten auszulesen, die Wi-Fi-Konfiguration zu ändern und die Flugsysteme zu steuern.
DJI-Drohnen stellen eine Bluetooth-Schnittstelle bereit, die verwendet wird, um eine Verbindung zur Wi-Fi-Schnittstelle der Drohne herzustellen und Wi-Fi-Anmeldedaten auszutauschen.
Die Bluetooth-Schnittstelle prüft die vertrauenswürdige UUID des Geräts für drei Befehle:
Die übrigen Befehle erfordern nicht dieselbe Authentifizierungsprüfung. Infolgedessen könnte ein Angreifer in Bluetooth-Reichweite unbefugte DUML-Befehle an die Drohne senden.
Je nach Befehl könnte ein Angreifer die Konfiguration der Drohne ändern, einschließlich des Änderns des Wi-Fi-Passworts und möglicherweise des Zugriffs auf das interne Netzwerk der Drohne, des Aktivierens oder Deaktivierens von Funkschnittstellen, des Neustartens oder Ausschaltens des Fluggeräts, des Zurücksetzens der Konfiguration und anderer Aktionen.
Der POC stellt eine Befehlsregistrierung bereit, mit der die verfügbaren Befehle getestet werden können, ohne den Python-Quellcode zu ändern. Die Befehlsregistrierung, einschließlich des Befehls, des Empfängers, der Authentifizierungsanforderungen und der Beschreibung jedes Befehls, ist in commands.json definiert.
| Produkt | Betroffene Version |
|---|---|
| DJI Neo | 0 – 01.00.0400 |
| DJI Neo 2 | 0 – 01.00.0500 |
| DJI Flip | 0 – 01.00.1200 |
| DJI Air 3 | 0 – 01.00.1600 |
| DJI Air 3S | 0 – 01.00.1400 |
| DJI Avata 2 | 0 – 01.00.0400 |
| DJI Avata 360 | 0 – 01.00.0300 |
| DJI Mavic 3 | 0 – 01.00.1400 |
| DJI Mavic 3 Classic | 0 – 01.00.0800 |
| DJI Mavic 3 Pro | 0 – 01.01.0700 |
| DJI Mavic 4 Pro | 0 – 01.00.0500 |
| DJI Mini 2 | 0 – 01.07.0200 |
| DJI Mini 3 | 0 – 01.00.0500 |
| DJI Mini 3 Pro | 0 – 01.00.0900 |
| DJI Mini 4 Pro | 0 – 01.00.1100 |
| DJI Mini 5 Pro | 0 – 01.00.0600 |
https://github.com/user-attachments/assets/57f51df2-5160-404c-9fd3-2a3a8b700008
# Clone the repository
git clone https://github.com/Wh02m1/CVE-2026-78306-POC.git
cd CVE-2026-78306-POC
# Create and activate a Python virtual environment
python3 -m venv venv
source venv/bin/activate
# Install dependencies
pip install -r requirements.txt
python3 ble_console.py
Die folgenden Befehle sind in commands.json registriert. Der POC unterteilt Befehle in Lese-, Konfigurations-, Funksteuerungs-, Reset-, System- und Parameteroperationen.
Diese Operationen sind im POC als danger klassifiziert und erfordern daher eine ausdrückliche Bestätigung, bevor sie gesendet werden.
Die Funksteuerungsbefehle sind über die entsprechenden dji_network-Handler implementiert.
| Befehl | Was er bewirkt |
|---|---|
| Factory Reset WIFI | Stellt die Wi-Fi-Konfiguration auf ihren Standardzustand wieder her. |
| Factory Restore Params | Stellt die Netzwerkkonfigurations-Parametertabelle auf Werkseinstellungen wieder her. |
Der POC markiert beide Operationen als gefährlich, da sie die persistente Konfiguration ändern.
| Befehl | Was er bewirkt |
|---|---|
| Change a parameter | Ändert einen Drohnenkonfigurationsparameter unter Verwendung seines 32-Bit-Namens-Hashs. |
| Reset a parameter | Setzt einen Konfigurationsparameter auf seinen Firmware-Standard zurück. |
Der POC bezieht Parameternamen aus flyc_parameters.txt und bietet eine interaktive Parameterauswahl. Um einen bekannten Parameter hinzuzufügen, den Sie ändern oder zurücksetzen möchten, fügen Sie seinen Namen zu flyc_parameters.txt hinzu. Der Parameter ist dann bei Start des POC zur Auswahl verfügbar.
commands.json bearbeiten, nicht den CodeDas Menü wird beim Start aus commands.json generiert. Um einen Befehl hinzuzufügen, fügen Sie ein neues Objekt zur commands-Liste eines Abschnitts hinzu. Der Befehl erscheint beim nächsten Start des POC.
Beispiel:
{
"label": "GET Channel",
"cmd_set": "0x07",
"cmd_id": "0x2c",
"receiver": "0x07",
"payload": "",
"tier": "read",
"bt_reply": true,
"note": "wms_evt_get_chan -> wifi_mgmt_get_chan."
}
Der Standardempfänger ist 0x07 (network:0) und der Standardsender ist 0x02 (mobile:0).
Interaktive Payload-Builder sind in payload_builders.py definiert.
Verfügbare Builder sind unter anderem:
ssidpskcountrymacchannelbss_typepower_levelrawUm einen neuen Builder hinzuzufügen, implementieren Sie die Funktion, registrieren Sie sie in BUILDERS und referenzieren Sie ihren Namen aus commands.json.
Als danger klassifizierte Befehle erfordern eine ausdrückliche Bestätigung vor der Übertragung.
Der Bestätigungsbildschirm zeigt Informationen an wie:
──────────────────────────────────────────────────────────────────────
!!! DANGEROUS COMMAND !!!
──────────────────────────────────────────────────────────────────────
COMMAND device_reset L1 config
ROUTE 00/de -> ve_air:1
PAYLOAD 11 01 00 00 00 00
DOES system / FC / gimbal / camera / wifi / sdr config reset
WARNING The FC configuration reset can restart the motors.
──────────────────────────────────────────────────────────────────────
Type YES to send:
Die DOES-Informationen stammen aus dem note-Feld des Befehls, während zusätzliche Warnungen aus dem warn-Feld in commands.json stammen.
Die Funktion Change a parameter bietet Zugriff auf die bekannten Konfigurationsparameter, die in flyc_parameters.txt aufgeführt sind.
Ein Parameter kann nach Namen ausgewählt, mit einem Wert versehen, in die ausgewählte Little-Endian-Breite konvertiert und mit set_cfg_item (0x03/0xf9) gesendet werden.
Reset a parameter verwendet reset_cfg_item (0x03/0xfa), um den ausgewählten Parameter auf seinen Firmware-Standard zurückzusetzen.
Der POC stellt außerdem mehrere vordefinierte Makros bereit:
| Makro | Beschreibung |
|---|---|
| Restart Wifi | Stoppt und startet Wi-Fi (0x42 gefolgt von 0x41). |
| SET NEW PSK + Restart wifi | Ändert den PSK und startet dann Wi-Fi neu. |
| Probe read commands | Sendet die registrierten Lesebefehle und meldet, welche Befehle antworten. |
Die Makros sind getrennt von den einzelnen Befehlseinträgen definiert.
⚠️ WARNUNG: Dieser Proof of Concept ist ausschließlich für Bildungs-, Sicherheitsforschungs- und autorisierte Penetrationstest-Zwecke bestimmt.
Dieser POC demonstriert Sicherheitsprobleme in der DJI-Bluetooth/DUML-Befehlsschnittstelle. Einige Befehle können die Gerätekonfiguration ändern, Funkschnittstellen deaktivieren, die Konnektivität unterbrechen, das Fluggerät neu starten oder ausschalten, die Konfiguration zurücksetzen oder gespeicherte Daten löschen.
⚠️ Verwenden Sie diesen POC NICHT gegen Fluggeräte, Geräte, Netzwerke oder Systeme, die Ihnen nicht gehören oder für die Sie keine ausdrückliche Testgenehmigung haben.
Einige Befehle können Datenverlust, Konfigurationsänderungen, Konnektivitätsverlust, Gerätestörungen oder andere unbeabsichtigte Folgen verursachen. Tests sollten nur in einer kontrollierten Umgebung durchgeführt werden, in der das Fluggerät sowie umstehende Personen und Sachen nicht gefährdet sind.
Die Autoren sind nicht verantwortlich für Schäden, Datenverlust, Dienstunterbrechungen, den Betrieb des Fluggeräts oder andere Folgen, die aus der Verwendung oder dem Missbrauch dieses POC resultieren.
⚠️ Durch die Verwendung dieses POC übernehmen Sie die Verantwortung dafür, sicherzustellen, dass Ihre Tests autorisiert sind und alle geltenden Gesetze, Vorschriften und Anforderungen zur verantwortungsvollen Offenlegung eingehalten werden.
| Befehl | Was er bewirkt |
|---|
| GET SSID | Ruft die konfigurierte Wi-Fi-SSID ab. |
| GET PSK | Ruft den Wi-Fi-WPA2-Pre-Shared-Key ab. |
| GET MAC | Ruft die Wi-Fi-AP-MAC-Adresse ab. |
| GET Country Code | Ruft den zweibuchstabigen regulatorischen Ländercode ab. |
| GET Channel | Ruft den aktuell aktiven Wi-Fi-Kanal ab. |
| GET Band | Ruft die konfigurierte 2,4/5-GHz-Bandauswahl ab. |
| GET RSSI | Fragt den RSSI-Handler ab; dieser Firmware-Build enthält eine Stub-Implementierung. |
| GET WiFi/BT status | Ruft den Funkstatus von Wi-Fi und Bluetooth ab. |
| GET Device Info/Model | Ruft Geräte- und Modellinformationen ab. |
| GET Version | Ruft die Daemon-Version ab. |
| GET Bluetooth Name | Ruft den Bluetooth-Gerätenamen ab. |
| Befehl | Was er bewirkt |
|---|
| SET SSID | Ändert die konfigurierte Wi-Fi-SSID. |
| SET PSK | Ändert das konfigurierte Wi-Fi-Passwort. |
| SET MAC Address | Ändert die Laufzeit-Wi-Fi-BSSID-Konfiguration. |
| SET Country Code | Ändert den konfigurierten regulatorischen Ländercode. |
| SET Country Code Ext | Behandelt die erweiterte Ländercode-Konfiguration. |
| SET Channel | Ändert den Wi-Fi-Kanal und veranlasst den AP zum Neustart. |
| Befehl | Was er bewirkt |
|---|
| Start WIFI | Startet die Wi-Fi-Schnittstelle und zugehörige Dienste. |
| Stop WIFI | Stoppt die Wi-Fi-Schnittstelle. |
| Restart WIFI + BT | Startet die Wi-Fi- und Bluetooth-Subsysteme neu. |
| Start Bluetooth | Startet das Bluetooth-Subsystem. |
| Stop Bluetooth | Stoppt das Bluetooth-Subsystem und beendet die aktuelle Sitzung. |
| Sysmode power control | Steuert den Energiezustand von Wi-Fi/Bluetooth. |
| Befehl | Was er bewirkt |
|---|
ftpd_start | Startet den dji_ftpd-Dienst. |
storage_export_enable | Aktiviert die Storage-Export-Konfiguration. |
storage_export_disable | Deaktiviert die Storage-Export-Konfiguration. |
play_sound | Löst einen Ton des Fluggeräts aus. |
mute | Schaltet den Lautsprecher des Fluggeräts stumm. |
unmute | Hebt die Stummschaltung des Lautsprechers des Fluggeräts auf. |
reboot_plain | Startet das Fluggerät neu. |
reboot_poweroff | Schaltet das Fluggerät aus. |
reboot_powersave | Versetzt das Fluggerät in den Energiesparmodus. |
device_reset L1 config | Setzt System-, Flugcontroller-, Gimbal-, Kamera-, Wi-Fi- und SDR-Konfiguration zurück. |
device_reset L2 +MEDIA | Führt den L1-Reset durch und formatiert Medien/Speicher. |
device_reset L3 +log | Führt den L2-Reset durch und löscht zusätzlich das Systemprotokoll. |
| Feld | Erforderlich | Bedeutung |
|---|
label | Ja | Im Menü angezeigter Text. |
cmd_set | Ja | DUML-Befehlssatz-Bezeichner. |
cmd_id | Ja | DUML-Befehlsbezeichner. |
receiver | Ja | Wire-Empfänger-Byte, (index << 5) | type. |
payload | Nein | Hex-Payload. |
tier | Nein | read, write oder danger. |
builder | Nein | Interaktiver Payload-Builder. |
auth | Nein | Gibt an, dass eine vertrauenswürdige UUID erforderlich ist. |
bt_reply | Nein | Steuert, ob der POC auf eine Bluetooth-Antwort wartet. |
sender | Nein | Sender-Byte; Standardwert ist 0x02. |
after | Nein | Optionale Folgeaktion. |
note | Nein | Vom POC angezeigte Reverse-Engineering-Beschreibung. |
warn | Nein | Zusätzlicher Warnungstext, der für gefährliche Befehle angezeigt wird. |
| Datei | Rolle |
|---|
ble_console.py | Haupteinstiegspunkt, Menü und Befehlsausführung. |
commands.json | Befehlsregistrierung und Befehlsbeschreibungen. |
ble_transport.py | Bluetooth-GATT-Scanning, Verbindungs- und Antwortverarbeitung. |
duml_protocol.py | DUML-v1-Paketkonstruktion und CRC-Verarbeitung. |
duml_decoders.py | Antwortdekodierung und Return-Code-Verarbeitung. |
payload_builders.py | Interaktive Payload-Generierung. |
parameters.py | Konfigurationsparameter-Hashing und -Operationen. |
terminal.py | Terminal-UI, Eingabeaufforderungen und Ausgabeverarbeitung. |
flyc_parameters.txt | Bekannte Konfigurationsparameternamen. |
requirements.txt | Python-Abhängigkeiten. |