docs: design recon identity enrichment
This commit is contained in:
+196
@@ -0,0 +1,196 @@
|
|||||||
|
# Recon Client Associations and Device Identity Design
|
||||||
|
|
||||||
|
## Summary
|
||||||
|
|
||||||
|
Enrich the Recon Scanning view with confirmed client-to-network associations
|
||||||
|
and best-available device identity. Associations must come from explicit
|
||||||
|
evidence and must never be inferred from proximity, channel, timing, or probe
|
||||||
|
requests. Access-point identity uses local device databases and existing
|
||||||
|
fallback data without requiring internet access.
|
||||||
|
|
||||||
|
The implementation remains compatible with the current constraints: Python
|
||||||
|
standard library only, no frontend build step, bounded scan-detail queries,
|
||||||
|
and read-only access to the stock Recon database.
|
||||||
|
|
||||||
|
## Confirmed Device Behavior
|
||||||
|
|
||||||
|
The target Pager Recon database contains:
|
||||||
|
|
||||||
|
- `ssid.type = 8`: access-point observations with BSSID and SSID.
|
||||||
|
- `ssid.type = 5`: directed probe observations with a device MAC and SSID but
|
||||||
|
no BSSID. These do not prove association.
|
||||||
|
- `ssid.type = 4`: unassociated observations used by the current landscape
|
||||||
|
count.
|
||||||
|
- `handshake.stahash` and `handshake.aphash`: explicit client/AP pairs that
|
||||||
|
resolve through `wifi_device.hash`.
|
||||||
|
- `hostap_client`: clients associated with an AP hosted by the Pineapple,
|
||||||
|
including client MAC, SSID, and connection timestamps.
|
||||||
|
|
||||||
|
The target has local manufacturer databases at
|
||||||
|
`/usr/share/nmap/nmap-mac-prefixes` and
|
||||||
|
`/usr/share/macchanger/wireless.list`. The Recon schema does not retain WPS or
|
||||||
|
other vendor information elements that would support dependable model
|
||||||
|
detection.
|
||||||
|
|
||||||
|
## Association Model
|
||||||
|
|
||||||
|
`recon_scan_data()` remains the canonical scan-detail builder. It emits only
|
||||||
|
confirmed associations from these sources:
|
||||||
|
|
||||||
|
1. WPA handshake rows, using `aphash` and `stahash` to resolve the AP and
|
||||||
|
client MAC addresses through `wifi_device`.
|
||||||
|
2. `hostap_client` rows scoped to the selected scan, representing clients that
|
||||||
|
associated with a Pineapple-hosted AP.
|
||||||
|
|
||||||
|
Directed probes and other `ssid` observations do not create associations.
|
||||||
|
There is no channel, signal, timing, or SSID-name inference.
|
||||||
|
|
||||||
|
Evidence for the same client/network pair is deduplicated. The resulting
|
||||||
|
association records preserve all evidence sources, for example
|
||||||
|
`["handshake", "hostap_client"]`.
|
||||||
|
|
||||||
|
### Client Shape
|
||||||
|
|
||||||
|
Each existing client object retains `mac`, `signal`, `freq`, and `packets` and
|
||||||
|
gains:
|
||||||
|
|
||||||
|
- `vendor`: best-available client manufacturer label.
|
||||||
|
- `associations`: an array of confirmed association objects.
|
||||||
|
|
||||||
|
Each association can contain:
|
||||||
|
|
||||||
|
- `ssid`
|
||||||
|
- `bssid`, when known
|
||||||
|
- `ap_identity`
|
||||||
|
- `sources`
|
||||||
|
- `connected_time`, when supplied by `hostap_client`
|
||||||
|
- `disconnected_time`, when supplied by `hostap_client`
|
||||||
|
|
||||||
|
An absent relationship is represented by an empty array. The UI labels this
|
||||||
|
state `Unknown`; it does not invent an SSID.
|
||||||
|
|
||||||
|
### Access-Point Shape
|
||||||
|
|
||||||
|
Each existing AP object retains its current fields and gains:
|
||||||
|
|
||||||
|
- `device_identity`: structured manufacturer, optional model, OUI, and source
|
||||||
|
metadata.
|
||||||
|
- `clients`: confirmed associated-client summaries.
|
||||||
|
- `client_count`: the number of unique confirmed client MAC addresses.
|
||||||
|
|
||||||
|
Handshake evidence resolves an AP by BSSID. The current `hostap_client` schema
|
||||||
|
does not contain a BSSID, so those rows create SSID-only associations and are
|
||||||
|
not assigned to an AP row. A matching SSID alone is insufficient to claim a
|
||||||
|
specific BSSID.
|
||||||
|
|
||||||
|
## Device Identity Resolution
|
||||||
|
|
||||||
|
Identity resolution follows this precedence:
|
||||||
|
|
||||||
|
1. `/usr/share/nmap/nmap-mac-prefixes`.
|
||||||
|
2. `/usr/share/macchanger/wireless.list`.
|
||||||
|
3. The existing built-in `OUI_VENDORS` map.
|
||||||
|
4. `Unknown`.
|
||||||
|
|
||||||
|
The parsed local maps are cached once per server process. Missing, malformed,
|
||||||
|
or unreadable files are skipped without failing Recon.
|
||||||
|
|
||||||
|
The identity object includes the visible three-byte OUI prefix. Locally
|
||||||
|
administered MAC addresses report `Local/Randomized` rather than a vendor.
|
||||||
|
Globally administered addresses absent from all sources report `Unknown`.
|
||||||
|
The current sources identify manufacturers, not models, so `model` is `null`.
|
||||||
|
Vendor names, SSIDs, and MAC patterns are not treated as models.
|
||||||
|
|
||||||
|
## Recon UI
|
||||||
|
|
||||||
|
The existing Recon layout, tabs, pagination, and focus sidebar remain intact.
|
||||||
|
|
||||||
|
### Access Points
|
||||||
|
|
||||||
|
The table gains two default-visible columns:
|
||||||
|
|
||||||
|
- `Device Identity`: the best reliable display label. It shows manufacturer
|
||||||
|
and model when both are explicitly available, manufacturer alone when only
|
||||||
|
the OUI resolves, and `Unknown (AA:BB:CC)` when unresolved.
|
||||||
|
- `Clients`: the confirmed unique-client count.
|
||||||
|
|
||||||
|
The richer `Device Identity` column replaces the current `Vendor` column to
|
||||||
|
avoid duplicate information. Selecting an AP continues to open the existing
|
||||||
|
focus sidebar, which gains a `Confirmed Clients` section listing client MAC,
|
||||||
|
client vendor, and evidence sources.
|
||||||
|
|
||||||
|
### Clients
|
||||||
|
|
||||||
|
The table gains two default-visible columns:
|
||||||
|
|
||||||
|
- `Vendor`
|
||||||
|
- `Associated SSID`
|
||||||
|
|
||||||
|
A single association shows its SSID. Multiple associations show the first
|
||||||
|
SSID followed by `+N`; the cell title contains every SSID, BSSID when known,
|
||||||
|
AP identity, and evidence source. Clients without confirmed evidence show
|
||||||
|
`Unknown`.
|
||||||
|
|
||||||
|
Search includes the new identity and association values. Existing column
|
||||||
|
preferences in `pw_recon_cols` are merged with current defaults, so users keep
|
||||||
|
their settings while newly introduced columns receive their default-visible
|
||||||
|
state.
|
||||||
|
|
||||||
|
## Exports and Reports
|
||||||
|
|
||||||
|
All exports use the same enriched scan-detail objects:
|
||||||
|
|
||||||
|
- JSON preserves structured identity and association arrays.
|
||||||
|
- CSV adds flattened identity, client count, and association fields. Multiple
|
||||||
|
associations are separated unambiguously with semicolons.
|
||||||
|
- HTML adds AP identity and confirmed-client count to AP details and includes
|
||||||
|
a confirmed-client table. The report labels these as confirmed associations
|
||||||
|
and does not mix in directed probes.
|
||||||
|
|
||||||
|
## Error Handling and Performance
|
||||||
|
|
||||||
|
- Association reads are scoped to the selected scan.
|
||||||
|
- Existing bounded scan-detail behavior remains bounded; enrichment must not
|
||||||
|
introduce unbounded cross-scan joins.
|
||||||
|
- Missing optional tables or schema differences yield empty association data
|
||||||
|
while preserving existing AP and client results.
|
||||||
|
- Missing OUI files fall back through the resolver chain and never make the
|
||||||
|
Recon endpoint fail.
|
||||||
|
- No external lookup or network dependency is introduced.
|
||||||
|
- Duplicate handshake or host-AP evidence collapses deterministically by
|
||||||
|
normalized client MAC and network identity.
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
|
||||||
|
Backend tests cover:
|
||||||
|
|
||||||
|
- Nmap, macchanger, and built-in OUI precedence.
|
||||||
|
- Missing and malformed local OUI files.
|
||||||
|
- Local/randomized and unknown MAC handling.
|
||||||
|
- Handshake-derived client/AP/SSID associations.
|
||||||
|
- `hostap_client` associations remain SSID-only and do not attach to an AP row.
|
||||||
|
- Deduplication and combined evidence sources.
|
||||||
|
- Explicit exclusion of `ssid.type = 5` probe rows.
|
||||||
|
- Missing optional association data.
|
||||||
|
- Enriched JSON, CSV, and HTML output.
|
||||||
|
|
||||||
|
Frontend tests or source assertions cover:
|
||||||
|
|
||||||
|
- New default columns and stored-column preference migration.
|
||||||
|
- Confirmed association display and the `Unknown` state.
|
||||||
|
- Search over identity and association values.
|
||||||
|
- Confirmed clients in the AP focus sidebar.
|
||||||
|
|
||||||
|
On-device verification uses read-only SQLite queries to compare API
|
||||||
|
associations with source evidence, confirms local OUI resolution, and checks
|
||||||
|
the Recon view at desktop and mobile widths. Verification does not alter
|
||||||
|
radio, PineAP, or wireless configuration.
|
||||||
|
|
||||||
|
## Out of Scope
|
||||||
|
|
||||||
|
- Inferring associations from probe requests, frequency, signal, time, or
|
||||||
|
physical proximity.
|
||||||
|
- Active probing, deauthentication, or traffic capture to discover clients.
|
||||||
|
- Internet OUI or device-fingerprinting services.
|
||||||
|
- Guessing AP models from manufacturer, SSID naming, or MAC patterns.
|
||||||
|
- Redesigning the Recon navigation or table framework.
|
||||||
Reference in New Issue
Block a user