🔍 Contexte
Publié le 27 août 2026 sur le blog personnel d’Olivier Laflamme (boschko.ca), cet article constitue une analyse technique exhaustive (~85 min de lecture) de deux chaînes d’exploitation critiques affectant le robot humanoïde Unitree G1 (20 000 USD). La recherche a duré environ 3 mois et a produit deux CVE : CVE-2026-76639 et CVE-2026-76640, récompensés par une prime de 5 000 USD.
🎯 Cibles et surface d’attaque
Le G1 embarque plusieurs ordinateurs communicant sur le réseau interne 192.168.123.0/24 :
- Dev PC (Jetson Orin NX, Ubuntu, SSH ouvert, credentials par défaut
unitree:123) à192.168.123.164 - Locomotion PC (Rockchip RK3588, Linux 5.10.176-rt86+, 28 services root) à
192.168.123.161— cible principale
Le Locomotion PC n’expose qu’un seul port TCP : 9991 (WebRTC signaling), plus DDS sur Domain 0 en UDP. Tous les services tournent en root sans séparation de privilèges.
🔗 RCE #1 — CVE-2026-76639 : Path traversal chat_go + exécution bashrunner
Chaîne en 3 bugs :
- Path traversal dans le service IA
chat_go(service.py) : l’APIUPLOAD_KNOWLEDGE(api_id 1006) écrit un fichier arbitraire à un chemin contrôlé par l’attaquant via le champuidsans validation (../../../../module/bashrunner/content_acquisition/pwn) - bashrunner (
bashrunner.py) construit sa whitelist viaos.listdir()à l’import — un redémarrage du service suffit à inclure le fichier injecté - bashrunner exécute tout fichier de la whitelist via
shsans vérification d’extension (.mdaccepté)
Livraison via WebRTC (port 9991) nécessitant la clé AES-128 per-device, ou via DDS direct (CycloneDDS Domain 0, sans authentification).
🔗 RCE #2 — CVE-2026-76640 : Chaîne BLE en 5 bugs
- GATT 0xFFE2 sans pairing : la caractéristique BLE accepte des écritures avec permission
BT_ATT_PERM_WRITE(0x02) sans chiffrement ni authentification - Bootstrap 0xF2 pré-auth : l’opcode 0xF2 retourne le blob RSA-OAEP-SHA256 contenant la clé AES-128 du robot à tout client BLE sans pairing
- Oracle cloud : l’endpoint
POST /device/bindExtDatasurglobal-robot-api.unitree.comdéchiffre le blob pour n’importe quel compte Unitree (gratuit) sans vérifier la liaison compte↔robot (authentification présente, autorisation absente) — patché en juillet 2026 - Injection heredoc WiFi : l’opcode 0x05 (WIFI_PWD) injecte des données dans
wpa_supplicant.confvia le fallback manuel dewpa_connect.sh(heredoc non quoté), forçant le robot à rejoindre le hotspot de l’attaquant - BSS buffer overflow dans
btgatt-server: le bufferwifi_ssid(500 octets) est dépassé via l’opcode 0x04 sans vérification de borne ; le curseurwifi_ssid_lengthpersiste entre les connexions BLE ; un payload de 1050 octets écraseepoll_terminate(→1) etmainloop_list[2](→ pointeur vers fausse structuremainloop_data), redirigeant le cleanup loop verssystem(command)en root
🧩 Primitives techniques clés
- Leak PIE base : via RCE #1, lecture de
/proc/<pid>/mapsdebtgatt-server(PIE activé, ASLR actif) - Payload circulaire : la fausse structure
mainloop_data, la commande shell et le pointeur corrompu résident tous dans le même bufferwifi_ssid - Wormabilité : un G1 compromis peut propager l’exploit aux G1 voisins via BLE
- Bypass WebRTC : exploitation possible via DDS pur (CycloneDDS Domain 0 sans auth) après reconstruction des IDL depuis les bindings Python du firmware
📦 Firmware et extraction
Le format OTA .upk utilise TEA-ECB (16 rounds, delta 0x9E3779B9) avec clé dérivée d’une graine en clair dans l’en-tête (offset 0x1C). Deux constantes hardcodées (0x6e35ba0c, 0x9a8b7c6e) dans les binaires OTA. Extraction via le projet UniTEABag (CVE-2026-1442).
📋 Secrets exposés post-exploitation
Après RCE sur le Locomotion PC : clés AWS Polly, iFlytek, Aliyun NLS, Volc Doubao, NetEase Music, DashScope (Alibaba), secrets JWT, secrets de signature d’app, stockage MinIO — ~15 secrets à fort impact (déclarés comme rotés).
📌 Type d’article
Analyse technique approfondie et publication de recherche offensive indépendante, incluant des PoC complets (Python, C), une timeline de divulgation coordonnée avec Unitree, et deux CVE réservés via VulnCheck.
🧠 TTPs et IOCs détectés
TTP
- T1190 — Exploit Public-Facing Application (Initial Access)
- T1203 — Exploitation for Client Execution (Execution)
- T1059.004 — Command and Scripting Interpreter: Unix Shell (Execution)
- T1083 — File and Directory Discovery (Discovery)
- T1005 — Data from Local System (Collection)
- T1548 — Abuse Elevation Control Mechanism (Privilege Escalation)
- T1552.001 — Unsecured Credentials: Credentials In Files (Credential Access)
- T1071 — Application Layer Protocol (Command and Control)
- T1210 — Exploitation of Remote Services (Lateral Movement)
- T1574 — Hijack Execution Flow (Defense Evasion)
IOC
- IPv4 :
192.168.123.161— AbuseIPDB · VT · ThreatFox - IPv4 :
192.168.123.164— AbuseIPDB · VT · ThreatFox - Domaines :
global-robot-api.unitree.com— VT · URLhaus · ThreatFox - CVEs :
CVE-2026-76639— NVD · CIRCL - CVEs :
CVE-2026-76640— NVD · CIRCL - CVEs :
CVE-2026-27509— NVD · CIRCL - CVEs :
CVE-2026-27510— NVD · CIRCL - CVEs :
CVE-2026-1442— NVD · CIRCL - Fichiers :
btgatt-server - Fichiers :
wpa_connect.sh - Fichiers :
service.py - Fichiers :
bashrunner.py - Fichiers :
chat_go - Fichiers :
xfkTon - Chemins :
/unitree/etc/key/aes_key.bin - Chemins :
/unitree/module/bashrunner/content_acquisition/pwn.md - Chemins :
/unitree/module/network_manager/upper_bluetooth/btgatt-server - Chemins :
/unitree/module/chat_go/service.py - Chemins :
/unitree/module/bashrunner/bashrunner.py - Chemins :
/unitree/etc/config/sn - Chemins :
/tmp/r.py
⚠️ À propos de ces IOC — ils sont extraits automatiquement de l’article original le 28 août 2026 et n’ont pas fait l’objet d’une vérification externe. Un indicateur peut avoir été réattribué depuis : une IP de C2 peut redevenir un service légitime, un domaine sinkholé peut changer de propriétaire. Aucune garantie d’exactitude ni d’actualité — contrôlez leur validité avant tout usage opérationnel, en particulier avant de les injecter dans une blocklist ou un SIEM.
Malware / Outils
- UniTEABag (tool)
- frida-dexdump (tool)
- CycloneDDS (framework)
🟡 Indice de vérification factuelle : 55/100 (moyenne)
- ⬜ boschko.ca — source non référencée (0pts)
- ✅ 162928 chars — texte complet (fulltext extrait) (15pts)
- ✅ 21 IOCs (IPs/domaines/CVEs) (10pts)
- ⬜ 0/3 IOCs confirmés externellement (0pts)
- ✅ 10 TTPs MITRE identifiées (15pts)
- ✅ date extraite du HTML source (10pts)
- ⬜ aucun acteur de menace nommé (0pts)
- ✅ 5/5 CVE(s) confirmée(s) (CIRCL) (5pts)
🔗 Source originale : https://boschko.ca/g1-ble-rce/