Initial commit
This commit is contained in:
@@ -0,0 +1,127 @@
|
||||
# Bluehound
|
||||
|
||||
Continuous BLE and Classic Bluetooth scanner with time-searchable logging, a REST API, and a web dashboard. Built for macOS and embedded/sensor-node deployments with WiFi streaming support.
|
||||
|
||||
Bluehound scans nearby Bluetooth devices in a loop, enriches each observation (manufacturer, service UUIDs, device class, estimated distance, Apple Continuity data), and persists everything to SQLite. A built-in HTTP server exposes the data for the bundled dashboard or any client.
|
||||
|
||||
## Features
|
||||
|
||||
- **Dual-stack scanning** — BLE via [SimpleBLE](https://github.com/OpenBluetoothToolbox/SimpleBLE), plus Classic Bluetooth inquiry and SDP service discovery on macOS via IOBluetooth.
|
||||
- **Time-searchable history** — every observation is stamped with date, time, hour, and minute and indexed for fast range queries.
|
||||
- **Device enrichment** — company/manufacturer lookup, standard service and characteristic UUID decoding, device-class decoding, and GATT characteristic enumeration on connect.
|
||||
- **Distance estimation** — RSSI + Tx power path-loss model, with per-device distance history.
|
||||
- **Apple Continuity decoding** — parses proximity/pairing advertisements.
|
||||
- **Passive security assessment** — flags risky services (OBEX, SPP, HID, audio) and known-vulnerable device signatures, assigning a HIGH/MEDIUM/LOW/NONE risk level.
|
||||
- **Device nicknames** — assign and manage human-readable labels per address.
|
||||
- **ESP32 ingestion** — remote sensor nodes can POST scan batches over WiFi to `/esp32/scan`.
|
||||
- **REST API + web dashboard** — a single-file HTML dashboard served over HTTP.
|
||||
|
||||
## Requirements
|
||||
|
||||
- macOS (Classic Bluetooth support uses IOBluetooth/CoreBluetooth frameworks)
|
||||
- CMake >= 3.15
|
||||
- SQLite3
|
||||
- Vendored dependencies (included in the repo):
|
||||
- SimpleBLE static library at `simpleble/simpleble/build/lib/libsimpleble.a`
|
||||
- cpp-httplib header at `third_party/httplib.h`
|
||||
|
||||
## Build
|
||||
|
||||
```sh
|
||||
./build.sh
|
||||
```
|
||||
|
||||
This verifies the vendored dependencies, configures with CMake into `build/`, and compiles. The resulting binary is `build/bluehound`.
|
||||
|
||||
To build manually:
|
||||
|
||||
```sh
|
||||
mkdir -p build && cd build
|
||||
cmake ..
|
||||
make -j
|
||||
```
|
||||
|
||||
Install system-wide with `sudo make install` from the `build/` directory.
|
||||
|
||||
## Run
|
||||
|
||||
```sh
|
||||
./build/bluehound
|
||||
```
|
||||
|
||||
On start, Bluehound initializes `ble_scans.db`, launches the HTTP server on port `8080` (bound to `0.0.0.0`), and begins scanning. Shut down cleanly with `Ctrl-C` (SIGINT/SIGTERM are handled gracefully).
|
||||
|
||||
Default configuration (compiled into `Config` in [bluehound.cpp](bluehound.cpp)):
|
||||
|
||||
| Setting | Default |
|
||||
| --- | --- |
|
||||
| Scan duration | 5000 ms per cycle |
|
||||
| Scan interval | 1000 ms between cycles |
|
||||
| Database path | `ble_scans.db` |
|
||||
| HTTP port | 8080 |
|
||||
| Max DB entries | 1,000,000 (rotates) |
|
||||
|
||||
## Web dashboard
|
||||
|
||||
Serve the dashboard with the helper script (static server on port 8090):
|
||||
|
||||
```sh
|
||||
python3 serve_dashboard.py
|
||||
```
|
||||
|
||||
Then open http://127.0.0.1:8090. The dashboard queries the scanner's API on port 8080, so run the `bluehound` binary alongside it.
|
||||
|
||||
## REST API
|
||||
|
||||
The scanner serves the following endpoints on port 8080:
|
||||
|
||||
| Method | Path | Description |
|
||||
| --- | --- | --- |
|
||||
| GET | `/health` | Health check |
|
||||
| GET | `/scans/recent?limit=N` | Most recent observations |
|
||||
| GET | `/scans/date/:date` | Observations for `YYYY-MM-DD` |
|
||||
| GET | `/scans/hour/:hour` | Observations for hour `HH` |
|
||||
| GET | `/stats` | Aggregate statistics |
|
||||
| GET | `/device/:address/count` | Observation count for a device |
|
||||
| GET | `/distance/:address` | Distance history for a device |
|
||||
| GET | `/characteristics/:address` | Discovered GATT characteristics |
|
||||
| GET | `/read/:address/:service/:characteristic` | Read a characteristic value |
|
||||
| GET | `/nickname/:address` | Get a device nickname |
|
||||
| POST | `/nickname/:address` | Set a device nickname |
|
||||
| DELETE | `/nickname/:address` | Remove a device nickname |
|
||||
| GET | `/nicknames` | List all nicknames |
|
||||
| GET | `/security/:address` | Security assessment for a device |
|
||||
| GET | `/security` | All security assessments |
|
||||
| GET | `/tracking/:address` | Tracking data (device info, Apple Continuity) |
|
||||
| POST | `/esp32/scan` | Ingest a scan batch from a remote ESP32 node |
|
||||
|
||||
CORS is enabled for all origins.
|
||||
|
||||
## Data model
|
||||
|
||||
Observations are stored in `ble_scans.db` (SQLite). Key tables:
|
||||
|
||||
- `ble_scans` — every observation, with timestamps, RSSI, manufacturer/company, service UUIDs, estimated distance, protocol type, and Classic device-class/SDP fields.
|
||||
- `device_distance_history` — per-device RSSI/distance samples over time.
|
||||
- `device_characteristics` — discovered GATT services and characteristics.
|
||||
- `device_nicknames` — user-assigned labels.
|
||||
- `security_assessments` — risk level, vulnerabilities, and recommendations per device.
|
||||
- `device_tracking_data` — device model/firmware/serial, Apple Continuity, pairing status, and tracking identifiers.
|
||||
|
||||
## Project layout
|
||||
|
||||
| Path | Purpose |
|
||||
| --- | --- |
|
||||
| [bluehound.cpp](bluehound.cpp) | Scanner core: scan loop, SQLite logging, HTTP API, BLE decoding, security assessment |
|
||||
| [classic_bluetooth.h](classic_bluetooth.h) / [classic_bluetooth.mm](classic_bluetooth.mm) | Classic Bluetooth inquiry and SDP via IOBluetooth (Objective-C++) |
|
||||
| [web_dashboard.html](web_dashboard.html) | Single-file web dashboard |
|
||||
| [serve_dashboard.py](serve_dashboard.py) | Static server for the dashboard |
|
||||
| [CMakeLists.txt](CMakeLists.txt) / [build.sh](build.sh) | Build configuration |
|
||||
| `simpleble/` | Vendored SimpleBLE |
|
||||
| `third_party/httplib.h` | Vendored cpp-httplib |
|
||||
|
||||
## Notes
|
||||
|
||||
- Classic Bluetooth scanning and the IOBluetooth-backed features are macOS-only. BLE scanning via SimpleBLE is portable, but the build as configured links macOS frameworks.
|
||||
- The ESP32 endpoint uses lightweight string-based JSON parsing; use a proper JSON library for production ingestion.
|
||||
- Security assessments are heuristic and intended for authorized inventory and awareness, not as a substitute for a full audit.
|
||||
Reference in New Issue
Block a user