Skip to content
KitploitKITPLOIT
도구블로그
제출
도구블로그
제출

해킹, 침투 테스트 및 사이버 보안 도구를 당신의 보안 무기고에!

Kitploit은 해킹, 사이버 보안 및 침투 테스트 도구 디렉토리입니다. 최신 프로젝트 업데이트를 발견하여 취약점을 찾고, 시스템을 분석하고, 테스트를 자동화하고, 보안을 강화하세요.

··피드·문의·개인정보·© 2026 Kitploit

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
Sniffle — TI CC1352/CC26x2 하드웨어용 Bluetooth 5 및 4.x LE 스니퍼로, 확장 광고, 모든 PHY 모드, MAC/RSSI 필터링 및 Wireshark와 호환되는 PCAP 내보내기 기능을 지원합니다. | Kitploit
도구/GitHubGitHub/nccgroup/sniffle
Embedded Systems SecurityPacket Sniffing & AnalysisBluetooth SecurityNetwork MappingWireless SecurityHardware HackingHardware SecurityHardware & IoT SecurityBluetooth Security #4위Hardware Hacking #16위
1.2k1623211개월 전Kitploit 검토 완료

인기

모두 보기 →

커뮤니티에서 가장 많이 사용되는 도구를 찾아보세요.

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유
Hardware & IoT Security #15위
Hardware Security #18위
GitHubnccgroup/sniffle

Sniffle

TI CC1352/CC26x2 하드웨어용 Bluetooth 5 및 4.x LE 스니퍼로, 확장 광고, 모든 PHY 모드, MAC/RSSI 필터링 및 Wireshark와 호환되는 PCAP 내보내기 기능을 지원합니다.

저장소 보기웹사이트

Sniffle

Sniffle은 TI CC1352/CC26x2 하드웨어를 사용하는 Bluetooth 5 및 4.x (LE)용 스니퍼입니다.

Sniffle은 다음과 같은 유용한 기능을 제공합니다:

  • BT5/4.2 확장 길이 광고 및 데이터 패킷 지원
  • BT5 채널 선택 알고리즘 #1 및 #2 지원
  • 모든 BT5 PHY 모드 지원 (일반 1M, 2M 및 코디드 모드)
  • 광고만 스니핑하고 연결 무시 지원
  • 채널 맵, 연결 매개변수 및 PHY 변경 작업 지원
  • MAC 주소 및 RSSI 기준 광고 필터링 지원
  • BT5 확장 광고 (비주기적) 지원
  • 단일 스니퍼로 세 개의 모든 주요 광고 채널에서 대상 MAC의 광고 캡처 지원. 이로 인해 하나의 광고 채널만 스니핑하는 대부분의 다른 스니퍼보다 연결 탐지가 거의 3배 더 신뢰할 수 있습니다.
  • Python으로 작성된 확장 가능한 호스트 측 소프트웨어
  • Ubertooth와 호환되는 PCAP 내보내기
  • Wireshark 호환 플러그인

전제 조건

  • 다음 하드웨어 장치 중 하나 (Sniffle과 기능적으로 동등)
    • TI CC26x2R Launchpad Board: https://www.ti.com/tool/LAUNCHXL-CC26X2R1
    • TI CC2652RB Launchpad Board: https://www.ti.com/tool/LP-CC2652RB
    • TI CC1352R Launchpad Board: https://www.ti.com/tool/LAUNCHXL-CC1352R1
    • TI CC1352P Launchpad Board: https://www.ti.com/tool/LAUNCHXL-CC1352P
    • TI CC2652R7 Launchpad Board: https://www.ti.com/tool/LP-CC2652R7
    • TI CC1352P7 Launchpad Board: https://www.ti.com/tool/LP-CC1352P7
    • TI CC2651P3 Launchpad Board: https://www.ti.com/tool/LP-CC2651P3
    • TI CC1354P10 Launchpad Board: https://www.ti.com/tool/LP-EM-CC1354P10
    • SONOFF CC2652P USB Dongle Plus: https://itead.cc/product/sonoff-zigbee-3-0-usb-dongle-plus/
    • EC Catsniffer V3 CC1352 & RP2040 https://github.com/ElectronicCats/CatSniffer
  • AArch32 베어메탈 타겟용 ARM GNU 툴체인 (arm-none-eabi): https://developer.arm.com/downloads/-/arm-gnu-toolchain-downloads
  • TI SimpleLink Low Power F2 SDK 8.30.01.01: https://www.ti.com/tool/download/SIMPLELINK-LOWPOWER-F2-SDK/8.30.01.01
  • TI DSLite 프로그래머 소프트웨어: 아래 참조
  • Python 3.9+ 및 PySerial 설치 필요

펌웨어를 위한 빌드 환경을 설정하는 수고를 하지 않으려면, UniFlash/DSLite를 사용하여 미리 빌드된 펌웨어 바이너리를 플래시하면 됩니다. 미리 빌드된 펌웨어 바이너리는 이 프로젝트의 GitHub 릴리스 탭에 있는 릴리스에 첨부되어 있습니다. 미리 빌드된 펌웨어를 사용할 때는 master 브랜치보다 뒤쳐진 펌웨어와의 호환성 문제를 피하기 위해 master 대신 해당 릴리스 태그에 해당하는 Python 코드를 사용하십시오.

GCC 설치

다양한 Linux 배포판의 패키지 관리자를 통해 제공되는 arm-none-eabi-gcc는 종종 일부 헤더 파일이 부족하거나 링커 구성에 변경이 필요합니다. 최소한의 번거로움을 위해 위에 링크된 ARM GCC를 사용하는 것이 좋습니다. 미리 빌드된 실행 파일을 다운로드하여 압축을 풀기만 하면 됩니다.

TI SDK 설치

TI SDK는 라이선스 계약에 동의하면 많은 소스 코드를 추출하는 실행 바이너리로 제공됩니다. Linux 및 Mac에서 기본 설치 디렉토리는 ~/ti/ 안에 있습니다. 이는 잘 작동하며, 제 makefiles는 이 경로를 예상하므로 여기서 기본값을 그대로 사용하는 것이 좋습니다. TI SysConfig 도구에도 동일하게 적용됩니다.

SDK가 추출되면 빌드 환경에 맞게 하나의 makefile을 편집해야 합니다. ~/ti/simplelink_cc13xx_cc26xx_sdk_8_30_01_01 (또는 SDK가 설치된 곳) 안에 imports.mak라는 makefile이 있습니다. Sniffle을 빌드하기 위해 여기서 설정해야 하는 유일한 경로는 GCC, XDC, cmake 및 SysConfig입니다. CCS 컴파일러는 필요하지 않습니다. 아래 diff를 참고로 하여 설치 위치에 맞게 조정하십시오.``` diff --git a/imports.mak b/imports.mak index b2cf5bf59..389d1a7c3 100644 --- a/imports.mak +++ b/imports.mak @@ -18,14 +18,14 @@

will build using each non-empty *_ARMCOMPILER cgtool.

-XDC_INSTALL_DIR ?= /home/username/ti/xdctools_3_62_01_15_core -SYSCONFIG_TOOL ?= /home/username/ti/ccs1270/ccs/utils/sysconfig_1.21.1/sysconfig_cli.sh +XDC_INSTALL_DIR ?= $(HOME)/ti/xdctools_3_62_01_15_core +SYSCONFIG_TOOL ?= $(HOME)/ti/sysconfig_1.21.1/sysconfig_cli.sh

-CMAKE ?= /home/username/cmake-3.21.3/bin/cmake +CMAKE ?= cmake PYTHON ?= python3

TICLANG_ARMCOMPILER ?= /home/username/ti/ccs1270/ccs/tools/compiler/ti-cgt-armllvm_3.2.2.LTS-0 -GCC_ARMCOMPILER ?= /home/username/arm-none-eabi-gcc/12.3.Rel1-0 +GCC_ARMCOMPILER ?= $(HOME)/arm_tools/arm-gnu-toolchain-14.3.rel1-x86_64-arm-none-eabi IAR_ARMCOMPILER ?= /home/username/iar9.50.2

Uncomment this to enable the TFM build

root@kitploit:~
SDK 버전 8.30.01.01 기준으로, 최신 버전의 GCC (및 binutils)로 컴파일하려면,
링크 오류 "Unknown destination type (ARM/Thumb)" 및 "dangerous relocation: unsupported relocation"를 피하기 위해
SDK를 약간 수정해야 합니다.```
diff --git a/kernel/tirtos7/packages/ti/sysbios/family/arm/m3/Hwi_asm_gcc.s b/kernel/tirtos7/packages/ti/sysbios/family/arm/m3/Hwi_asm_gcc.s
index 187cfd744..4cbf0d384 100644
--- a/kernel/tirtos7/packages/ti/sysbios/family/arm/m3/Hwi_asm_gcc.s
+++ b/kernel/tirtos7/packages/ti/sysbios/family/arm/m3/Hwi_asm_gcc.s
@@ -236,6 +236,7 @@ lab$1:
 @ user code has set the PRIMASK and not cleared it, or when single
 @ stepping with interrupts disabled.
 
+.type ti_sysbios_family_arm_m3_Hwi_interruptsAreDisabledButShouldNotBe, %function
 ti_sysbios_family_arm_m3_Hwi_interruptsAreDisabledButShouldNotBe:
         b   ti_sysbios_family_arm_m3_Hwi_interruptsAreDisabledButShouldNotBe
 
diff --git a/kernel/tirtos7/packages/ti/sysbios/family/arm/v8m/Hwi_asm_gcc.s b/kernel/tirtos7/packages/ti/sysbios/family/arm/v8m/Hwi_asm_gcc.s
index 717f49c9a..1c83ed725 100644
--- a/kernel/tirtos7/packages/ti/sysbios/family/arm/v8m/Hwi_asm_gcc.s
+++ b/kernel/tirtos7/packages/ti/sysbios/family/arm/v8m/Hwi_asm_gcc.s
@@ -226,6 +226,7 @@ lab$1:
 @ user code has set the PRIMASK and not cleared it, or when single
 @ stepping with interrupts disabled.
 
+.type ti_sysbios_family_arm_v8m_Hwi_interruptsAreDisabledButShouldNotBe, %function
 ti_sysbios_family_arm_v8m_Hwi_interruptsAreDisabledButShouldNotBe:
         b   ti_sysbios_family_arm_v8m_Hwi_interruptsAreDisabledButShouldNotBe

이 수정을 한 후에는 SDK를 다시 컴파일해야 합니다.``` cd ~/ti/simplelink_cc13xx_cc26xx_sdk_8_30_01_01 make build-gcc -j5

root@kitploit:~
### DSLite 받기

DSLite는 XDS110 디버거용 TI의 명령줄 프로그래밍 및 디버그 서버 도구입니다. CC26xx 및 CC13xx Launchpad 보드에는 XDS110 디버거가 모두 포함되어 있습니다. 불행히도 TI는 독립 실행형 명령줄 DSLite 다운로드를 제공하지 않습니다. DSLite를 얻는 가장 쉬운 방법은 TI의 [UniFlash](http://www.ti.com/tool/download/UNIFLASH)를 설치하는 것입니다. Linux, Mac 및 Windows에서 사용할 수 있습니다. DSLite 실행 파일은 UniFlash 설치 디렉터리 기준 `deskdb/content/TICloudAgent/linux/ccs_base/DebugServer/bin/DSLite`에 있습니다. Linux에서 기본 UniFlash 설치 디렉터리는 `~/ti/` 안에 있습니다.

DSLite 실행 파일 디렉터리를 `$PATH`에 추가해야 합니다.

## 펌웨어 빌드

GCC, DSLite 및 SDK가 설치되어 작동 중이면 Sniffle 빌드는 간단합니다. `fw` 디렉터리로 이동하여 `make`를 실행하기만 하면 됩니다. SDK를 기본 디렉터리에 설치하지 않은 경우 makefile에서 `SIMPLELINK_SDK_INSTALL_DIR`을 편집해야 할 수 있습니다.

CC26x2R 이외의 Launchpad 변종용으로 빌드하거나 설치하는 경우 `PLATFORM=xxx`를 make 인수로 지정하거나 make를 호출하기 전에 환경 변수로 정의해야 합니다. `PLATFORM`에 지원되는 값은 펌웨어 makefile에서 확인할 수 있습니다. 다른 플랫폼용으로 빌드하기 전에 반드시 `make clean`을 수행하세요.

## 펌웨어 설치 (TI Launchpad 보드)

DSLite를 사용하여 (연결된) CC26x2R Launchpad에 Sniffle을 설치하려면 `fw` 디렉터리 내에서 `make load`를 실행합니다. 다른 Launchpad 모델의 경우 위에서 설명한 대로 make에 `PLATFORM` 인수를 지정해야 합니다. 또한 컴파일된 `sniffle.hex` 바이너리를 UniFlash GUI를 사용하여 플래시할 수 있습니다.

## 펌웨어 설치 (SONOFF USB 동글)

SONOFF CC2652P 동글(CP2102N USB/UART 브리지 장착)에 Sniffle을 설치하려면 [JelmerT/cc2538-bsl](https://github.com/JelmerT/cc2538-bsl) 유틸리티를 사용하여 내장 ROM 부트로더를 통해 다음 명령으로 펌웨어를 플래시하세요:```
python3 cc2538-bsl.py -p /dev/ttyUSB0 --bootloader-sonoff-usb -ewv sniffle_cc1352p1_cc2652p1.hex

2025년 1월 10일 기준, cc2538-bsl에는 Sonoff 동글에서 CC2562P 칩을 플래싱 후 리셋하지 못하게 하는 버그가 있습니다. 이에 대한 수정은 아직 병합되지 않은 풀 리퀘스트 173에 있습니다. 해당 풀 리퀘스트가 병합될 때까지 기다리는 동안 https://github.com/sultanqasim/cc2538-bsl에서 제 포크를 사용할 수 있습니다.

2022년에는 COVID-19 팬데믹으로 인한 칩 부족으로 인해, 일부 Sonoff CC2652P 동글이 921600 보드레이트로 제한된 CP2102(비N) USB/UART 브리지 칩으로 제조되었습니다. 이러한 동글을 가지고 있다면, 더 느린 921600 보드레이트를 사용하는 다른 펌웨어 이미지를 플래싱해야 합니다. 이 특별한 느린 보드레이트 빌드는 sniffle_cc1352p1_cc2652p1_1M.hex(빌드 변형 CC2652P1F_1M)로 명명되었습니다. 또한 Sniffle 유틸리티를 호출할 때 기본 보드레이트 2000000을 재정의하기 위해 -b 921600 옵션을 사용해야 합니다.

경고: 부트로더를 사용하여 잘못된 빌드 변형을 플래싱하지 마십시오. 그렇게 하면 기기가 손상되어 부트로더에서 잠길 위험이 있습니다. Sonoff CC2652P 기기의 경우 sniffle_cc1352p1_cc2652p1.hex 파일(CC2652P1F 빌드 변형) 또는 921600 보드레이트용 sniffle_cc1352p1_cc2652p1_1M.hex 파일(CC2652P1F_1M 빌드 변형)을 사용하십시오. 잘못된 변형을 플래싱하고 부트로더에서 잠긴 경우, JTAG/SWD를 사용하여 기기를 복구할 수 있습니다.

펌웨어 설치 (Catsniffer V3)

Electronic Cats는 펌웨어 로딩을 위한 Catnip Uploader 도구를 제공합니다. 자세한 내용은 저장소를 참조하십시오. 도구를 다운로드하고 다음 명령을 따르십시오:```bash

Fetch the CatSniffer tools and their dependencies

[ec@sniffle]$ git clone https://github.com/ElectronicCats/CatSniffer-Tools.git [ec@sniffle]$ cd CatSniffer-Tools/catnip_uploader [ec@sniffle]$ pip install -r requirements.txt

Download the available firmwares

[ec@sniffle]$ python3 catnip_uploader.py releases [INFO] Fetching assets from https://api.github.com/repos/ElectronicCats/CatSniffer-Firmware/releases/latest [INFO] Release: board-v3.x-v1.1.0 [INFO] Fetching assets from https://api.github.com/repos/nccgroup/Sniffle/releases/latest [INFO] Release: v1.10.0 [INFO] Found local release: releases_board-v3.x-v1.1.0 [SUCCESS] Local release is up to date: board-v3.x-v1.1.0 [SUCCESS] Available releases: 0: sniffer_fw_CC1352P_7_v1.10.hex 1: airtag_scanner_CC1352P_7_v1.0.hex 2: nccgroup_v1.10.0_sniffle_cc1352p7_1M.hex 3: airtag_spoofer_CC1352P_7_v1.0.hex 4: sniffle_CC1352P_7_v1.7.hex

Install the firmware

[ec@sniffle]$ python3 catnip_uploader.py load 2 COMPORT

root@kitploit:~
보드에 맞는 경로로 *COMPORT*를 변경해야 합니다.
`python3 catnip_uploader.py load 2 COMPORT` 명령어를 사용하여
`2: nccgroup_v1.10.0_sniffle_cc1352p7_1M.hex` 펌웨어를 로드합니다.
**펌웨어를 로드하려면 Catsniffer V3는 SerialPassthroughwithboot가 필요합니다**.

**경고:** 부트로더를 사용하여 잘못된 빌드 변형을 플래시하지 마십시오. 그렇지 않으면
장치가 손상되고 부트로더에서 잠길 위험이 있습니다.
`catnip_uploader.py` 스크립트를 사용하여 펌웨어를 가져와 설치하면
호환되는 펌웨어만 제공합니다. 단, 수동으로 펌웨어를 컴파일하여 설치하려는 경우
올바른 빌드 변형을 사용해야 합니다. CatSniffer v3 장치의 경우
`sniffle_cc1352p7_1M.hex` 파일(`CC1352P74_1M` 빌드 변형)을 사용하십시오.
CatSniffer v1.x/v2.x 장치는 다른 칩 변형(CC1352P1)을 사용하며
다른 펌웨어 빌드(`CC1352P1F3_1M` 변형, `sniffle_cc1352p1_cc2652p1_1M.hex`
이미지)가 필요합니다. Sniffle은 CatSniffer v1.x/v2.x 장치에서 테스트되지 않았지만
적절한 빌드 변형을 플래시하면 작동할 가능성이 높습니다. 잘못된 변형을 플래시하여
부트로더에서 잠긴 경우 JTAG/SWD를 사용하여 장치를 복구할 수 있습니다.

## 스니퍼 사용법```
[skhan@serpent python_cli]$ ./sniff_receiver.py --help
usage: sniff_receiver.py [-h] [-s SERPORT] [-b BAUDRATE] [-c {37,38,39}] [-p] [-r RSSI]
                         [-m MAC] [-i IRK] [-S STRING] [-a] [-A] [-e] [-H] [-l] [-q]
                         [-Q PRELOAD] [-n] [-C] [-d] [-o OUTPUT]

Host-side receiver for Sniffle BLE5 sniffer

options:
  -h, --help            show this help message and exit
  -s SERPORT, --serport SERPORT
                        Sniffer serial port name
  -b BAUDRATE, --baudrate BAUDRATE
                        Sniffer serial port baud rate
  -c {37,38,39}, --advchan {37,38,39}
                        Advertising channel to listen on
  -p, --pause           Pause sniffer after disconnect
  -r RSSI, --rssi RSSI  Filter packets by minimum RSSI
  -m MAC, --mac MAC     Filter packets by advertiser MAC
  -i IRK, --irk IRK     Filter packets by advertiser IRK
  -S STRING, --string STRING
                        Filter for advertisements containing the specified string
  -a, --advonly         Passive scanning, don't follow connections
  -A, --scan            Active scanning, don't follow connections
  -e, --extadv          Capture BT5 extended (auxiliary) advertising
  -H, --hop             Hop primary advertising channels in extended mode
  -l, --longrange       Use long range (coded) PHY for primary advertising
  -q, --quiet           Don't display empty packets
  -Q PRELOAD, --preload PRELOAD
                        Preload expected encrypted connection parameter changes
  -n, --nophychange     Ignore encrypted PHY mode changes
  -C, --crcerr          Capture packets with CRC errors
  -d, --decode          Decode advertising data
  -o OUTPUT, --output OUTPUT
                        PCAP output file name

Launchpad 보드의 XDS110 디버거는 두 개의 직렬 포트를 생성합니다. Linux에서는 일반적으로 ttyACM0 및 ttyACM1로 명명됩니다. 생성된 두 개의 직렬 포트 중 첫 번째 포트가 Sniffle과 통신하는 데 사용됩니다. 기본적으로 Python CLI는 TI XDS110 USB VID:PID 콤보와 일치하는 첫 번째 CDC-ACM 장치 또는 발견된 첫 번째 Sonoff 동글과 통신합니다. 다른 USB 직렬 어댑터를 사용하거나 추가 USB CDC-ACM 장치가 연결된 경우 -s 명령줄 옵션으로 이를 재정의해야 할 수 있습니다.

-r (RSSI 필터) 옵션의 경우, 스니퍼가 전송 장치에 매우 가깝거나 거의 닿아 있을 때 -40 값이 잘 작동하는 경향이 있습니다. RSSI 필터는 혼잡한 RF 환경에서 관련 없는 광고를 무시하는 데 매우 유용합니다. RSSI 필터는 광고를 캡처할 때만 활성화됩니다. 추적 중인 연결의 데이터 채널 트래픽은 항상 캡처해야 하기 때문입니다. MAC 필터링이 활성화된 경우 RSSI 필터를 사용하지 않는 것이 좋습니다. RSSI가 너무 낮으면 관심 MAC 주소의 광고를 놓칠 수 있기 때문입니다.

광고를 따라 이동하며 안정적인 연결 스니핑을 위해서는 -m 옵션으로 MAC 필터를 설정해야 합니다. 중앙 장치가 아닌 주변 장치의 MAC 주소를 지정해야 합니다. 어떤 MAC 주소를 스니핑할지 알아내려면 스니퍼를 대상 근처에 두고 RSSI 필터링을 사용하여 스니퍼를 실행하면 됩니다. 그러면 대상 장치의 광고와 함께 해당 MAC 주소가 표시됩니다. 많은 BLE 장치는 라벨에 적힌 '실제' 고정 MAC이 아닌 무작위화된 MAC 주소로 광고한다는 점에 유의해야 합니다.

대부분의 새로운 BLE 장치는 고정된 정적 또는 공용 주소 대신 해결 가능한 개인 주소(RPA)를 사용합니다. 특정 RPA에 MAC 필터를 설정할 수 있지만, 장치는 주기적으로 RPA를 변경합니다. ID 확인 키(IRK)를 알고 있으면 RPA를 확인(특정 장치와 연결)할 수 있습니다. Sniffle은 IRK가 제공될 때 자동 RPA 확인을 지원합니다. 이렇게 하면 RPA가 변경될 때마다 MAC 필터를 업데이트할 필요가 없습니다. -i 옵션으로 Sniffle에 IRK를 지정할 수 있습니다. IRK는 16진수 형식으로 제공되며, 최상위 바이트(MSB)가 먼저 와야 합니다. IRK를 지정하면 Sniffle이 MAC 필터와 동일한 방식으로 광고자와 채널을 호핑할 수 있습니다. IRK 기반 MAC 필터링 기능(-i)은 정적 MAC 필터링 기능(-m)과 상호 배타적입니다.

또한 광고 또는 스캔 응답에 지정된 문자열(바이트 시리즈)이 포함된 광고자의 MAC 주소를 자동으로 식별하는 편의 기능이 있습니다. 이는 IRK를 알 수 없지만 광고에 식별에 적합한 충분히 고유한 정적 문자열이 포함된 RPA 장치에 유용합니다. 이 기능은 -S 옵션을 사용하며, 문자열은 표준 이스케이프 시퀀스를 사용하여 지정합니다. 예를 들어, 광고에 16진수 바이트 시퀀스 DE AD BE EF가 포함된 광고자를 찾으려면 -S "\xDE\xAD\xBE\xEF"를 지정합니다. "hello" 문자열이 포함된 광고자를 찾으려면 간단히 -S "hello"를 지정합니다. 문자열 검색 기능을 사용하면 처음에는 검색 문자열이 포함된 광고를 찾을 때까지 모든 MAC 주소가 허용됩니다. 그 후에는 해당 광고자의 MAC 주소로 MAC 필터가 설정되고 RSSI 필터는 자동으로 비활성화됩니다.

Bluetooth 5 확장 광고에서 보조 포인터를 추적하려면 -e 옵션을 활성화하세요. 확장 광고 캡처의 성능과 안정성을 향상시키기 위해 이 옵션은 MAC 필터가 설정된 경우에도 기본 광고 채널에서의 호핑을 비활성화합니다. 연결이 레거시 광고를 통해 설정될지 확장 광고를 통해 설정될지 확실하지 않은 경우 -H 플래그를 -e와 함께 활성화하여 레거시 광고로 기본 채널 호핑을 수행하고 확장 광고 보조 패킷에 대한 예약된 수신을 수행할 수 있습니다. -e와 -H를 결합하면 기본(레거시) 또는 보조(확장) 광고 채널만 호핑하는 것에 비해 연결 감지의 신뢰성이 낮아질 수 있습니다.

기본 광고 채널에서 장거리 PHY를 스니핑하려면 -l 옵션을 지정하세요. 모든 장거리 광고는 BT5 확장 메커니즘을 사용하므로 장거리 모드에서는 기본 광고 채널 간 호핑이 지원되지 않습니다. 확장 메커니즘에서는 세 기본 채널의 보조 포인터가 모두 동일한 보조 패킷을 가리키므로 기본 채널 간 호핑이 필요하지 않습니다.

연결을 추적하는 동안 빈 데이터 패킷을 화면에 출력하지 않으려면 -q 플래그를 사용하세요. 이렇게 하면 실시간으로 의미 있는 통신을 관찰하기 쉬워지지만, 연결 추적이 불안정하거나 끊어졌을 때를 모호하게 만들 수 있습니다.

암호화된 연결의 경우, Sniffle은 암호화 키를 알 수 없는 경우에도 연결 매개변수 업데이트를 감지하고 새 매개변수를 측정하려고 시도합니다. 그러나 암호화된 연결 매개변수 업데이트에서 예상되는 새 연결 간격 및 Instant 델타를 알고 있다면 --preload/-Q 옵션으로 이를 지정하여 성능/신뢰성을 향상시킬 수 있습니다. 예상 Interval:DeltaInstant 쌍은 콜론으로 구분된 정수로 제공되어야 합니다. Interval은 1.25ms의 배수를 나타내는 정수입니다(LL_CONNECTION_UPDATE_IND에 정의됨). DeltaInstant는 연결 업데이트 패킷이 전송된 시점부터 새 매개변수가 적용되는 시점까지의 연결 이벤트 수입니다. DeltaInstant는 중앙 장치에 대한 Bluetooth 사양 요구 사항에 따라 6 이상이어야 합니다. 여러 암호화된 매개변수 업데이트가 예상되는 경우 쉼표로 구분된 여러 매개변수 쌍을 제공할 수 있습니다(예: 6:7,39:8). PHY를 변경하지 않는 암호화된 PHY 업데이트 PDU를 발행하거나 PHY 변경 없이 암호화된 LE 전력 제어 PDU를 내보내는 장치가 있는 경우 --nophychange/-n 옵션을 사용할 수 있습니다.

스니퍼를 중지하려면 Ctrl-C를 누르세요.

어떤 이유로 스니퍼 펌웨어가 잠겨 필터를 비활성화해도 트래픽을 캡처하지 않는 경우 스니퍼 MCU를 재설정해야 합니다. Launchpad 보드에서 재설정 버튼은 마이크로 USB 포트 옆에 있습니다.

Scanner Usage```

usage: scanner.py [-h] [-s SERPORT] [-b BAUDRATE] [-c {37,38,39}] [-r RSSI] [-l] [-d] [-o OUTPUT]

Scanner utility for Sniffle BLE5 sniffer

options: -h, --help show this help message and exit -s SERPORT, --serport SERPORT Sniffer serial port name -b BAUDRATE, --baudrate BAUDRATE Sniffer serial port baud rate -c {37,38,39}, --advchan {37,38,39} Advertising channel to listen on -r RSSI, --rssi RSSI Filter packets by minimum RSSI -l, --longrange Use long range (coded) PHY for primary advertising -d, --decode Decode advertising data -o OUTPUT, --output OUTPUT PCAP output file name

root@kitploit:~
스캐너 명령줄 인수는 스니퍼와 동일하게 작동합니다. 스캐너 유틸리티의 목적은 스니퍼 유틸리티에서 발생하는 빠르게 스크롤되는 데이터의 홍수를 피하면서, 근처에서 광고하는 장치 목록을 수집하고, 관찰된 장치에 대해 적극적으로 스캔 요청을 발행하는 것입니다. 하드웨어/펌웨어는 수신된 광고를 보고, 스캔 가능한 광고에 대해 스캔 요청을 발행하고, 수신된 스캔 응답을 보고하는 능동 스캔 모드로 진입합니다. 스캐너 유틸리티는 관찰된 MAC 주소를 한 번만 기록하고 보고하여 디스플레이를 어지럽히지 않습니다. 광고 캡처가 끝나면 Ctrl-C를 눌러 스캔을 중지하고 결과를 보고합니다. 스캐너는 각 대상의 마지막 광고 및 스캔 응답을 표시합니다. 스캔 결과는 RSSI 내림차순으로 정렬됩니다.

## 사용 예제

채널 38에서 모든 광고를 스니핑하고, RSSI < -50을 무시하며, CONNECT\_REQs가 보여도 광고 채널에 머무릅니다.```
./sniff_receiver.py -c 38 -r -50 -a

MAC 12:34:56:78:9A:BC로부터 광고를 스니핑하고, CONNECT_REQs가 보여도 광고 채널에 머무르며, 광고를 data1.pcap에 저장합니다.``` ./sniff_receiver.py -m 12:34:56:78:9A:BC -a -o data1.pcap

root@kitploit:~
RSSI >= -40인 첫 번째 MAC 주소에 대한 광고 및 연결을 스니핑합니다. MAC 주소가 고정되면 RSSI 필터가 자동으로 비활성화됩니다. 캡처된 데이터를 `data2.pcap`에 저장합니다.```
./sniff_receiver.py -m top -r -40 -o data2.pcap

빅 엔디안 IRK를 가진 주변 장치로부터 광고 및 연결을 스니핑합니다. 4E0BEA5355866BE38EF0AC2E3F0EBC22. 두 개의 예상된 암호화된 연결 파라미터 업데이트를 미리 로드합니다; 첫 번째는 Interval이 6이고, Instant 6에서 발생하며, 이는 암호화된 LL_CONNECTION_UPDATE_IND가 관찰된 후 6개의 연결 이벤트 후에 스니퍼에 의해 관찰됩니다. 두 번째 예상된 암호화된 연결 업데이트는 Interval 이 39이고, DeltaInstant도 6입니다.``` ./sniff_receiver.py -i 4E0BEA5355866BE38EF0AC2E3F0EBC22 -Q 6:6,39:6

root@kitploit:~
근처(RSSI >= -55) 장치로부터 BT5 확장 광고 및 연결을 스니핑합니다.```
./sniff_receiver.py -r -55 -e

지정된 MAC 주소를 가진 기기에서 레거시 및 확장 광고와 연결을 스니핑합니다. 캡처된 데이터를 data3.pcap에 저장합니다.``` ./sniff_receiver.py -eH -m 12:34:56:78:9A:BC -o data3.pcap

root@kitploit:~
긴 범위 기본 PHY를 사용하여 채널 38에서 확장된 광고 및 연결을 스니핑합니다.```
./sniff_receiver.py -le -c 38

채널 39에서 RSSI가 -50보다 큰 광고를 적극적으로 스캔합니다.``` ./scanner.py -c 39 -r -50

root@kitploit:~
## IRK 확인하기

루팅된 Android 기기가 있다면 Bluedroid 구성 파일에서 IRK(및 LTK)를 찾을 수 있습니다. Android 8.1에서는 `/data/misc/bluedroid/bt_config.conf`에 위치합니다. `LE_LOCAL_KEY_IRK`는 Android 기기 자체의 IRK를 지정하며, 파일에 있는 각 페어링된 기기의 `LE_KEY_PID` 처음 16바이트는 해당 기기의 IRK를 나타냅니다. 이 파일에 저장된 키는 리틀 엔디언이므로 **파일 내 키의 바이트 순서를 반전해야 합니다.** 예를 들어, 리틀 엔디언 IRK 22BC0E3F2EACF08EE36B865553EA0B4E는 Sniffle에 `-i` 옵션으로 전달할 때 4E0BEA5355866BE38EF0AC2E3F0EBC22 (빅 엔디언)로 변경해야 합니다.

기기를 루팅하지 않고 Android 또는 iOS에서 캡처한 HCI Snoop 로그를 통해 IRK와 LTK를 찾을 수도 있습니다:

* Android: <https://novelbits.s3.us-east-2.amazonaws.com/Developer+Guides/Android+Bluetooth+Debugging+Guide.pdf>
* iOS: <https://novelbits.s3.us-east-2.amazonaws.com/Developer+Guides/iOS+Bluetooth+Debugging+Guide.pdf>

## Wireshark 플러그인

Sniffle에는 Wireshark GUI에서 'Sniffle' 캡처 인터페이스를 선택하여 Sniffle을 자동으로 시작할 수 있는 Wireshark 플러그인이 포함되어 있습니다.

Sniffle 플러그인을 설치하려면 먼저 'Wireshark 정보' 대화상자(*Help* > *About Wireshark* > *Folders* > *Personal Extcap path*)에서 Personal Extcap 폴더의 위치를 찾으십시오. 최신 Wireshark(4.2.0+)를 실행하는 POSIX(Linux 및 Mac OS) 시스템에서 이 폴더는 `~/.local/lib/wireshark/extcap`에 위치합니다. Windows에서는 `%USERPROFILE%\AppData\Roaming\Wireshark\extcap`에서 찾을 수 있습니다.

POSIX 시스템에서는 Sniffle extcap 플러그인을 Wireshark 개인 extcap 디렉토리에 심볼릭 링크로 연결하면 됩니다:```
mkdir -p ~/.local/lib/wireshark/extcap
ln -s $(pwd)/python_cli/sniffle_extcap.py ~/.local/lib/wireshark/extcap

Mac OS에서 Wireshark는 셸 프로필에 지정된 PATH의 Python 대신 Xcode Python을 사용하려고 할 수 있습니다. 따라서 PySerial이 Xcode Python에 설치되어 있지 않으면 Sniffle 플러그인이 extcap 인터페이스에 나타나지 않을 수 있습니다. 이 문제를 해결하려면 sniffle_extcap.py의 shebang 라인을 /usr/bin/env python3 대신 PySerial이 설치된 Python을 직접 가리키도록 편집할 수 있습니다. 예를 들어 Homebrew Python의 /opt/homebrew/bin/python3와 같이 말입니다.

Windows에서는 python_cli 디렉터리에서 다음 파일 및 디렉터리를 개인 Extcap 폴더로 복사할 수 있습니다:``` sniffle/ sniffle_extcap.py sniffle_extcap.bat

root@kitploit:~
Windows에서는 설치 디렉터리가 PATH에 포함되어 있지 않은 경우, python 인터프리터의 위치를 지정하기 위해 `sniffle_extcap.bat`를 편집해야 할 수 있습니다. 예를 들어:```
@echo off
C:\my_python_install\python.exe "%~dp0sniffle_extcap.py" %*

플러그인이 설치된 후, Wireshark를 다시 시작하거나 Capture > Refresh Interfaces를 선택하여 Sniffle 인터페이스를 활성화하십시오.

전송 기능

원래 2019년 Sniffle 펌웨어는 순전히 수동 청취자였지만, 이후 펌웨어 버전에서는 다양한 방식으로 패킷을 능동적으로 전송하는 여러 기능이 추가되었습니다. 현재 Sniffle 펌웨어는 능동 스캐닝, 레거시 및 확장 광고, 연결 시작, 중앙 또는 주변 역할로 연결되는 것을 포함하여 GAP 중앙 및 주변 장치 역할을 모두 지원합니다. scanner.py 스크립트는 능동 스캐닝을 수행합니다. initiator.py 스크립트는 주변 장치에 연결을 시작한 후 연결된 중앙 장치 역할을 합니다. advertiser.py 스크립트는 레거시 광고를 수행하고 다른 장치의 연결 요청을 수락하여 연결된 주변 장치 역할로 전환됩니다.

Sniffle의 전송 기능은 기존 HCI 기반 블루투스 컨트롤러와는 약간 다릅니다. 링크 계층에서 전송되는 정확한 PDU에 대한 매우 낮은 수준의 제어를 제공하기 때문입니다. 이 낮은 수준의 제어를 통해 호스트 측 코드는 링크 계층 퍼즈 테스트 또는 링크 계층 릴레이 공격과 같은 추가 기능을 구현할 수 있습니다.

아직 Sniffle 펌웨어의 API를 공식적으로 문서화할 시간을 내지 못했지만, sniffle_hw.py의 호스트 측 구현을 보면 상당히 자명합니다. (스캔 요청을 전송하는) 능동 스캐닝은 cmd_scan에 의해 활성화됩니다. 연결 시작은 cmd_connect에 의해 트리거되지만, initiate_conn 래퍼를 사용하는 것이 가장 쉽습니다. 광고(선택적으로 연결 가능)는 레거시 광고의 경우 cmd_advertise에 의해, 확장 광고의 경우 cmd_advertise_ext에 의해 활성화됩니다.

XDS110 UART 지연 시간

2024년 중반에 TI 문제 EXT-EP-11735가 수정된 이후, XDS110 디버거(TI Launchpad 보드에 포함)는 Sniffle에서 사용하는 2M과 같은 높은 전송 속도를 과도한 지연 없이 합리적인 방식으로 처리합니다. 그러나 최신 XDS110 펌웨어는 여전히 이러한 전송 속도에서 UART의 버퍼링된 DMA 구동 방식을 사용하므로 최대 30ms의 지연이 발생할 수 있습니다. 이 지연은 스니퍼로 사용하는 데는 문제가 없지만, GATT 클라이언트 또는 서버 역할을 하는 호스트 측 코드나 릴레이 공격 수행과 같은 보다 적극적인 작업에는 해가 될 수 있습니다. 아래에 설명된 인터럽트 기반 작동을 위한 XDS110 펌웨어 버전 3.0.0.28의 수정은 이러한 시간에 민감한 작업의 지연을 크게 줄일 수 있습니다. 최신 XDS110 펌웨어에도 유사한 수정을 적용할 수 있어야 하지만, 아직 리버스 엔지니어링하여 올바른 비트를 찾을 시간을 내지 못했습니다.

2024년 중반 및 그 이전에는 TI XDS110 디버거(Launchpad 보드에 포함)의 펌웨어가 USB-UART 브리지에서 바람직하지 않은 동작을 보였습니다. 높은 전송 속도에서, 특히 Sniffle 펌웨어가 수행하는 것처럼 잦은 작은 쓰기 작업이 있는 경우 심각한 지연이 발생할 수 있었습니다. 이 문제는 수년간 존재했으며, UniFlash 8.6.0에 포함된 XDS110 펌웨어 3.0.0.28에서도 2024년 4월까지 여전히 존재했습니다. 근본 원인은 DMA 기반 작업에서 XDS110 펌웨어가 전송 속도에 비례하는 크기의 버퍼에 UART 데이터를 축적하고, 데이터를 전송하기 전에 이 버퍼가 채워질 때까지 기다렸기 때문입니다. 지난 15밀리초 동안 새 데이터가 도착하지 않으면 이 버퍼를 플러시하는 로직이 있었지만, Sniffle이 몇 밀리초마다 연결 이벤트의 작은 패킷을 자주 추가할 때 이 플러시 로직이 트리거되지 않았습니다. 이 차선의 동작으로 인해 스니핑된 데이터는 호스트에서 지연된 버스트로 나타날 수 있었습니다.

XDS110 펌웨어에는 UART 수신 시마다 인터럽트가 트리거되어 데이터가 즉시 호스트로 전달되는 UART 작업의 대체 모드도 있습니다. 이 인터럽트 기반 작업 모드는 지연 시간이 훨씬 짧습니다. 그러나 펌웨어는 230400 미만의 전송 속도에 대해서만 이 모드를 사용합니다. 잦은 작은 데이터 청크가 있는 DMA 모드 작업의 높은 지연 시간에 대한 해결 방법으로, 높은 전송 속도(Sniffle에서 사용하는 2M 전송 속도 등)에서도 인터럽트 기반 USB-UART 브리징을 사용하도록 펌웨어를 수정할 수 있습니다. 펌웨어 3.0.0.28(Uniflash 8.6.0에 포함)에서는 오프셋 0x0A14의 바이트를 61 3F에서 00 1F로 16진수 편집할 수 있습니다. 이렇게 하면 DMA 기반 UART 작업으로 전환되는 전송 속도가 230400에서 0x200000(2097152)으로 변경됩니다.

위에 설명된 오프셋 및 바이트 수정은 펌웨어 3.0.0.28에만 해당되며, 다른 펌웨어 버전에서는 다릅니다. 디버거에 유효하지 않은 펌웨어를 플래싱하면 손상될 수 있으며, 발생할 수 있는 손상에 대해 어떠한 책임도 지지 않습니다.

다음 명령은 Linux에서 높은 전송 속도에서 낮은 지연 시간 UART를 위해 XDS110 펌웨어를 수정하는 데 사용할 수 있습니다.``` cd ~/ti/uniflash_8.6.0/deskdb/content/TICloudAgent/linux/ccs_base/common/uscif/xds110/ cp firmware_3.0.0.28.bin firmware_3.0.0.28_fastuart.bin printf '\x00\x1f' | dd of=firmware_3.0.0.28_fastuart.bin bs=1 seek=$((0x0A14)) conv=notrunc sha256sum firmware_3.0.0.28_fastuart.bin

root@kitploit:~
플래싱 전에 수정된 펌웨어의 SHA256 해시가 `c226f2e9cb2b9f0bc111ca11f2903d58d4065293468623428c0e8eeb22086dcf`인지 확인하세요. 확인 후 다음 명령어를 실행하여 수정된 XDS110 디버거 펌웨어를 플래싱하세요:```
./xdsdfu -m
./xdsdfu -f firmware_3.0.0.28_fastuart.bin -r

링크 계층 트래픽 중계

Sniffle을 사용하여 Bluetooth LE 트래픽의 링크 계층 중계를 수행할 수 있습니다. 중계를 수행할 때, 하나의 Sniffle 장치는 BLE 중앙 장치( relay_master.py 사용)로 작동하고, 두 번째 Sniffle 장치는 BLE 주변 장치( relay_slave.py 사용)로 작동합니다. 마스터와 슬레이브는 각각 BLE 중앙 장치와 주변 장치를 가리키는 역사적인 용어입니다. 중계 마스터는 실제 주변 장치로부터 광고 및 스캔 응답 데이터를 캡처하여 중계 슬레이브에 전달합니다. 중계 슬레이브는 실제 주변 장치를 모방한 광고 및 스캔 응답을 전송하고 연결을 수락합니다. 연결을 수락하면 중계 슬레이브는 중계 마스터에 알리고, 중계 마스터는 실제 주변 장치에 연결을 시작합니다. 이 시점부터 모든 링크 계층 패킷이 중계 마스터와 슬레이브 간에 전달됩니다.

중계 마스터 스크립트는 지연 시간을 줄이기 위해 중계의 한쪽 또는 양쪽에서 더 빠른 연결 간격을 요청하는 기능을 제공합니다. XDS110을 USB/UART 브리지로 사용하는 경우, 위에서 설명한 대로 수정하지 않으면 XDS110 펌웨어가 중계에 추가 지연을 유발한다는 점에 유의하세요.

중계 마스터 스크립트는 모든 인터페이스(0.0.0.0)에 바인딩되는 네트워크 리스너를 생성하며, 중계 장치 간 통신에 사용되는 네트워크 프로토콜은 보안을 제공하지 않습니다. 이 스크립트는 신뢰할 수 있는 네트워크 환경에서만 사용하세요.

중계 마스터(중앙) 및 슬레이브(주변) 스크립트의 사용법은 아래에 나와 있습니다. 현재 중계 스크립트는 확장 광고를 지원하지 않습니다.``` usage: relay_master.py [-h] [-s SERPORT] [-c {37,38,39}] [-m MAC] [-i IRK] [-S STRING] [-P] [-q] [-Q PRELOAD] [-f] [-p] [-F] [-o OUTPUT]

Relay master script for Sniffle BLE5 sniffer

options: -h, --help show this help message and exit -s, --serport SERPORT Sniffer serial port name -c, --advchan {37,38,39} Advertising channel to listen on -m, --mac MAC Specify target MAC address -i, --irk IRK Specify target IRK -S, --string STRING Specify target by advertisement search string -P, --public Supplied MAC address is public -q, --quiet Don't show empty packets -Q, --preload PRELOAD Preload expected encrypted connection parameter changes -f, --fastslave Relay slave should request a fast connection interval -p, --pause Wait for key press on master before relaying -F, --fastmaster Relay master should specify a fast connection interval -o, --output OUTPUT PCAP output file name

root@kitploit:~
". Wait, the user message says "INPUT:" and then there is a blank line, then nothing else? Actually, looking at the text: "INPUT:\n\n response". That seems like the user might have accidentally cut off the content. The user says "INPUT:" and then nothing. Possibly the chunk content was supposed to follow but it's missing. Or perhaps this chunk is empty? But then they say " response" meaning they expect the assistant's response? No, the instructions are clear: we must translate the provided content. Since no content is provided after "INPUT:", there is nothing to translate. The user might have intended to include the chunk text but it's absent. In such a case, we should not output anything? But the instruction says "Return ONLY the translated text." If there is no text, we should return nothing? However, we must ensure we don't add any meta. The safest is to respond with an empty string? But that might break the concatenation. Possibly the user expects us to indicate something? No, we must follow instructions strictly.

Given the input is empty, the translation is also empty. I should return nothing. But the user message ends with "response" which is not part of the content; that is likely the start of the assistant's response section? Actually, in the typical format, the user provides "INPUT:" then the content. Here, it's just "INPUT:" then a blank line, then " response". That might be an artifact. I will assume there is no content for chunk 43, so my output should be nothing. But to be safe, I will not output anything, as per the rules: return ONLY the translated text. If there is no text, there is nothing to return. However, an empty response might be considered invalid. Alternatively, I could check if maybe the chunk is just a continuation marker? But the note says "DO NOT add introductory headings... DO NOT add ... ellipsis markers". So if the chunk is empty, the translation is empty.

I will output nothing.```
usage: relay_slave.py [-h] [-s SERPORT] [-M MASTERADDR] [-q]

Relay slave script for Sniffle BLE5 sniffer

options:
  -h, --help            show this help message and exit
  -s, --serport SERPORT
                        Sniffer serial port name
  -M, --masteraddr MASTERADDR
                        IP address of relay master
  -q, --quiet           Don't show empty packets
도구 다운로드