
ماسح Bluetooth Low Energy (BLE) مع حل Resolvable Private Address (RPA) باستخدام Identity Resolving Keys (IRKs)
ماسح ضوئي لتقنية البلوتوث منخفض الطاقة (BLE) مع حل متقدم للعناوين الخاصة القابلة للحل (RPA). اكتشف أجهزة BLE القريبة، وتتبع جهازًا محددًا عبر عنوان MAC، أو حل العناوين العشوائية للخصوصية باستخدام مفتاح حل الهوية (IRK).
كتبه: David Kennedy (@HackingDave) الشركة: TrustedSec
-o -)يتطلب ختم موقع GPS تشغيل برنامج الخدمة gpsd مع مستقبل GPS متصل. إذا لم يكن gpsd قيد التشغيل، يستمر btrpa-scan بشكل طبيعي بدون GPS.
للتحقق من أن gpsd يعمل:
# Check that gpsd is listening
gpspipe -w -n 5
# Or use the curses monitor
cgps
يستخدم هذا المشروع pyproject.toml (PEP 621)، معيار التغليف الحديث في بايثون. يعرّف المشروع كحزمة قابلة للتثبيت مع أمر CLI مسجل — لا حاجة لتشغيل ملفات .py مباشرة.
uvx btrpa-scan --all
uvx --from git+https://github.com/hackingdave/btrpa-scan.git btrpa-scan --all
uv tool install btrpa-scan
أو مباشرة من GitHub:
uv tool install git+https://github.com/hackingdave/btrpa-scan.git
pip install btrpa-scan
لدعم الواجهة الرسومية (واجهة الرادار القائمة على Flask):
pip install btrpa-scan[gui]
git clone https://github.com/hackingdave/btrpa-scan.git
cd btrpa-scan
pip install .
usage: btrpa-scan [-h] [-a] [--irk HEX] [--irk-file PATH] [-t TIMEOUT]
[--output {csv,json,jsonl}] [-o FILE] [--log FILE]
[-v | -q] [--min-rssi DBM] [--rssi-window N] [--active]
[--environment {free_space,indoor,outdoor}]
[--ref-rssi DBM] [--name-filter PATTERN]
[--alert-within METERS] [--tui] [--gui] [--gui-port PORT]
[--no-gps] [--adapters LIST] [mac]
BLE Scanner — discover all devices or hunt for a specific one
positional arguments:
mac Target MAC address to search for (omit to scan all)
optional arguments:
-h, --help show this help message and exit
-a, --all Scan for all broadcasting devices
--irk HEX Resolve RPAs using this Identity Resolving Key (32 hex chars)
--irk-file PATH Read IRK(s) from a file (one per line, hex format)
-t, --timeout TIMEOUT Scan timeout in seconds (default: 30, or infinite for --irk)
--output {csv,json,jsonl}
Batch output format written at end of scan
-o, --output-file FILE
Output file path (default: btrpa-scan-results.<format>;
use - for stdout)
--log FILE Stream detections to a CSV file in real time
-v, --verbose Verbose mode — show additional details
-q, --quiet Quiet mode — suppress per-device output, show summary only
--min-rssi DBM Minimum RSSI threshold (e.g. -70) — ignore weaker signals
--rssi-window N RSSI sliding window size for averaging (default: 1 = no averaging)
--active Use active scanning (sends SCAN_REQ for additional data)
--environment {free_space,indoor,outdoor}
Distance estimation path-loss model (default: free_space)
--ref-rssi DBM Calibrated RSSI at 1 metre for distance estimation
--name-filter PATTERN Filter devices by name (case-insensitive substring match)
--alert-within METERS Proximity alert when device is within this distance
--tui Live-updating terminal table instead of scrolling output
--gui Launch web-based radar interface in the browser
--gui-port PORT Port for GUI web server (default: 5000)
--no-gps Disable GPS location stamping (GPS is on by default via gpsd)
--adapters LIST Comma-separated Bluetooth adapter names (e.g. hci0,hci1)
قم بفحص جميع أجهزة BLE التي تبث (المهلة الافتراضية 30 ثانية):
btrpa-scan --all
بمهلة مخصصة:
btrpa-scan --all -t 60
ابحث عن جهاز محدد عبر عنوان MAC:
btrpa-scan AA:BB:CC:DD:EE:FF
حل العناوين الخاصة القابلة للحل (RPA) باستخدام مفتاح حل الهوية. يعمل هذا الوضع إلى أجل غير مسمى افتراضيًا حتى يتم إيقافه بـ Ctrl+C:
btrpa-scan --irk 0123456789ABCDEF0123456789ABCDEF
يمكن توفير IRK بعدة صيغ:
| الصيغة | مثال |
|---|---|
| Hex عادي | 0123456789ABCDEF0123456789ABCDEF |
| مفصول بنقطتين | 01:23:45:67:89:AB:CD:EF:01:23:45:67:89:AB:CD:EF |
قم بتحميل مفتاح IRK واحد أو أكثر من ملف. يجب أن يحتوي كل سطر على IRK واحد بأي صيغة hex مدعومة. الأسطر التي تبدأ بـ # تُعامل كتعليقات:
btrpa-scan --irk-file keys.txt
مثال keys.txt:
# Alice's phone
0123456789ABCDEF0123456789ABCDEF
# Bob's watch
FEDCBA9876543210FEDCBA9876543210
عند تحميل عدة مفاتيح IRK، يتم فحص كل RPA مكتشف مقابل جميع المفاتيح. يعرض الملخص إجمالي التطابقات عبر جميع المفاتيح.
عيّن متغير البيئة BTRPA_IRK لتجنب تمرير المفتاح عبر سطر الأوامر:
export BTRPA_IRK=0123456789ABCDEF0123456789ABCDEF
btrpa-scan
الأولوية: --irk > --irk-file > BTRPA_IRK
اعرض فقط الأجهزة التي تكون قوة إشارتها أعلى من حد معين:
btrpa-scan --all --min-rssi -70
إشارة RSSI في BLE مزعجة بطبيعتها. استخدم متوسط نافذة منزلقة لتقديرات مسافة أكثر استقرارًا ولتصفية الاكتشافات الضعيفة الزائفة:
btrpa-scan --all --rssi-window 5
عند تفعيل النافذة، يعرض الشاشة كلاً من RSSI الخام والمتوسط (مثل RSSI: -65 dBm (avg: -62 dBm over 5 readings))، ويستخدم تقدير المسافة القيمة المتوسطة. يُطبق مرشح --min-rssi أيضًا على RSSI المتوسط، مما يمنع حدوث قمة مزعجة واحدة من إسقاط الجهاز.
قم بتصفية الأجهزة بالاسم باستخدام مطابقة نصية جزئية غير حساسة لحالة الأحرف:
btrpa-scan --all --name-filter "AirPods"
سيتم عرض الأجهزة التي يحتوي اسمها المُعلن على النمط المحدد فقط. تُستبعد الأجهزة التي ليس لها اسم عند تفعيل مرشح الاسم.
المسح السلبي (الافتراضي) يرى الإعلانات فقط. يرسل المسح النشط SCAN_REQ ويحصل على SCAN_RSP، مما يمكن أن يكشف معرفات UUID إضافية للخدمات وأسماء الأجهزة:
btrpa-scan --all --active
ملاحظة: على macOS، يقوم CoreBluetooth دائمًا بالمسح النشط بغض النظر عن هذا العلم. على Linux/BlueZ، قد يتطلب المسح النشط صلاحيات root أو
CAP_NET_ADMIN.
يستخدم تقدير المسافة أس فقدان مسار يختلف حسب البيئة. الافتراضي (free_space, n=2.0) يفترض عدم وجود عوائق. لتقديرات أكثر واقعية في الداخل:
btrpa-scan --all --environment indoor
| الإعداد المسبق | أس فقدان المسار (n) | حالة الاستخدام |
|---|---|---|
free_space | 2.0 | الهواء الطلق، خط الرؤية المباشر |
تنتج قيم n الأعلى تقديرات مسافة أكبر لنفس RSSI، مما يعكس توهين الإشارة من الجدران والعوائق.
افتراضيًا، يستنتج btrpa-scan قيمة RSSI المتوقعة عند متر واحد من قوة الإرسال المُعلنة TX Power باستخدام إزاحة 59 ديسيبل مُتحقق منها تجريبيًا (معيار iBeacon). للحصول على دقة أفضل، يمكنك توفير قيمة معايرة مقاسة في بيئتك الخاصة:
--ref-rssi:btrpa-scan --all --ref-rssi -55
عند تعيين --ref-rssi، يتم تجاهل TX Power تمامًا. وهذا يتيح أيضًا تقديرات المسافة للأجهزة التي لا تُعلن عن TX Power.
قم بتشغيل جرس صوتي وتنبيه مرئي عند تقدير وجود جهاز ضمن مسافة معينة. يتطلب أن يُعلن الجهاز المستهدف عن TX Power:
btrpa-scan AA:BB:CC:DD:EE:FF --alert-within 5.0
يعمل في جميع الأوضاع بما في ذلك حل IRK:
btrpa-scan --irk <key> --alert-within 3.0
استبدل مخرجات التمرير بجدول طرفية مباشر التحديث، مرتب حسب قوة الإشارة:
btrpa-scan --all --tui
يعرض TUI جميع الأجهزة المكتشفة في جدول مضغوط مع العنوان والاسم وRSSI ومتوسط RSSI والمسافة التقديرية وعدد الاكتشافات ووقت آخر ظهور. تظهر تطابقات IRK المحلولة بخط عريض، ويتم تمييز الأجهزة ضمن حد --alert-within.
يمكن دمجه مع أعلام أخرى:
btrpa-scan --irk <key> --tui --rssi-window 5 --environment indoor --alert-within 5.0
شغّل واجهة رادار قائمة على المتصفح مع مسح متحرك وتتبع الأجهزة في الوقت الفعلي وخريطة GPS:
btrpa-scan --all --gui
تتضمن الواجهة الرسومية:
يقوم وضع الواجهة الرسومية بالمسح بشكل مستمر افتراضيًا (بدون مهلة 30 ثانية). اضغط Ctrl+C للإيقاف. استخدم -t لتحديد مدة فحص محددة:
# Scan for 60 seconds with indoor path-loss model
btrpa-scan --all --gui -t 60 --environment indoor
# Custom port
btrpa-scan --all --gui --gui-port 8080
# Combine with RSSI averaging and proximity alerts
btrpa-scan --all --gui --rssi-window 5 --alert-within 5.0
ملاحظة: يتطلب
--guiتثبيت Flask و flask-socketio (pip install btrpa-scan[gui]). لا يمكن دمجه مع--tuiأو--quiet.
قم ببث كل اكتشاف إلى ملف CSV عند حدوثه (مفيد للفحوصات طويلة الأمد حيث تريد بيانات تدريجية):
btrpa-scan --all --log scan.csv
يمكن دمج ذلك مع --output لتصدير دفعة منفصلة:
btrpa-scan --all --log live.csv --output json -o results.json
قم بتصدير جميع النتائج في نهاية الفحص بصيغة CSV أو JSON أو JSONL (أسطر JSON):
btrpa-scan --all --output json -o results.json -t 30
btrpa-scan --all --output csv -t 30
btrpa-scan --all --output jsonl -o results.jsonl -t 30
يكتب JSONL كائن JSON واحد لكل سطر، مما يسهل تمريره عبر jq:
btrpa-scan --all --output jsonl -o results.jsonl -t 10
cat results.jsonl | jq .
اكتب الإخراج إلى stdout للتمرير:
btrpa-scan --all --output json -o - -t 10 -q | jq .
قم بالمسح بعدة محولات بلوتوث في وقت واحد لتغطية أوسع:
btrpa-scan --all --adapters hci0,hci1
يشغل كل محول مثيل الماسح الخاص به مع مشاركة نفس استدعاء الاكتشاف. تُدمج جميع الاكتشافات في إخراج واحد.
GPS مفعل افتراضيًا. يتم وضع علامة على كل اكتشاف بإحداثيات GPS الحالية من gpsd. يتتبع الماسح أيضًا أفضل تحديد GPS لكل جهاز — الإحداثيات من الاكتشاف بأقوى RSSI (أقرب قرب = الموقع الأكثر دقة).
إذا لم يكن gpsd قيد التشغيل، يطبع الماسح ملاحظة ويستمر بشكل طبيعي بدون GPS:
# With gpsd running — detections include lat/lon
btrpa-scan --all --output json
# Without gpsd — works fine, GPS fields are empty
btrpa-scan --all
# Explicitly disable GPS (skips connection attempt)
btrpa-scan --all --no-gps
تظهر إحداثيات GPS في:
latitude وlongitude وgps_altitudeشغّل في الوضع الهادئ (ملخص فقط، بدون إخراج لكل جهاز — مفيد مع --output أو --log):
btrpa-scan --all -q --output json -t 30
شغّل في الوضع المفصل (يعرض RPAs غير المتطابقة في وضع IRK):
btrpa-scan --irk 0123456789ABCDEF0123456789ABCDEF -v
تستخدم أجهزة البلوتوث منخفض الطاقة عناوين خاصة قابلة للحل (RPAs) لمنع التتبع. RPA هو عنوان MAC مؤقت يتغير بشكل دوري، ولكن يمكن حله من قبل أي شخص يمتلك مفتاح حل الهوية (IRK) الخاص بالجهاز.
يتكون RPA من:
01AES-128-ECB(IRK, padding || prand) مقتطعة إلى 3 بايتاتينفذ btrpa-scan دالة ah() من مواصفات البلوتوث الأساسية (المجلد 3، الجزء H، القسم 2.2.2) لحل هذه العناوين في الوقت الفعلي.
ملاحظة حول AES-ECB: استخدام AES بوضع ECB لدالة
ah()منصوص عليه في مواصفات البلوتوث الأساسية. نظرًا لأنه يتم تشفير كتلة واحدة فقط بحجم 16 بايت دائمًا، فإن نقص انتشار ECB عبر الكتل غير ذي صلة — هذه ليست ثغرة أمنية.
ps. لتجنب كشف IRK، استخدم --irk-file للقراءة من ملف، أو عيّن متغير البيئة BTRPA_IRK. يخفي إخراج وحدة التحكم مفاتيح IRK افتراضيًا (يعرض فقط أول وآخر 4 أحرف hex).--no-gps لتعطيل GPS تمامًا.--output-file و--log إلى المسار المحدد. تأكد من أن الوجهة لها الصلاحيات المناسبة لحالة الاستخدام الخاصة بك.pip install pytest
python -m pytest test_btrpa_scan.py -v
Mode: DISCOVER ALL - showing every broadcasting device
Scanning: passive
GPS: connected (37.774929, -122.419418)
Timeout: 30s | Press Ctrl+C to stop
------------------------------------------------------------
============================================================
DEVICE #1 - seen 1x
============================================================
Address : AA:BB:CC:DD:EE:FF
Name : MyDevice
RSSI : -45 dBm
TX Power : -59 dBm
Est. Distance: ~0.4 m
Manufacturer : 0x004C -> 0215abcdef
Best GPS : 37.774929, -122.419418
Timestamp : 14:32:07
============================================================
------------------------------------------------------------
Scan complete - 30.0s elapsed
Total detections : 142
Unique devices : 12
Results written to btrpa-scan-results.json
اضغط Ctrl+C في أي وقت لإيقاف الفحص بسلاسة وعرض إحصائيات الملخص.
| المنصة | التثبيت | التشغيل |
|---|
| macOS | brew install gpsd | gpsd -n /dev/tty.usbserial-* |
| Debian/Ubuntu | sudo apt install gpsd gpsd-clients | sudo systemctl start gpsd |
| Fedora/RHEL | sudo dnf install gpsd gpsd-clients | sudo systemctl start gpsd |
| Arch | sudo pacman -S gpsd | sudo systemctl start gpsd |
| ويندوز | استخدم gpsd عبر WSL أو MSYS2 | راجع تعليمات WSL أعلاه |
| المنصة | ملاحظات |
|---|
| macOS | يستخدم CoreBluetooth. يستفيد وضع IRK من واجهة برمجة تطبيقات غير موثقة لاسترجاع عناوين البلوتوث الحقيقية بدلاً من UUIDs. --active ليس له أي تأثير — يقوم CoreBluetooth دائمًا بالمسح النشط. |
| لينكس | قد يتطلب صلاحيات root أو خاصية CAP_NET_ADMIN للمسح. |
| ويندوز | واجهة WinRT Bluetooth الأصلية — عناوين MAC الحقيقية متاحة أصلاً. يتطلب TUI تثبيت pip install windows-curses. |
| مفصول بشرطة | 01-23-45-67-89-AB-CD-EF-01-23-45-67-89-AB-CD-EF |
| مسبوق بـ 0x | 0x0123456789ABCDEF0123456789ABCDEF |
outdoor | 2.2 | الحدائق، مواقف السيارات |
indoor | 3.0 | المكاتب، المنازل، المباني |