Covert Data Exfiltration via Bluetooth LE Advertising Packet Encoding (Beacon Stuffing)
Bluetooth Low Energy advertising packets (the broadcast frames used by beacons such as iBeacon/Eddystone) can carry up to 31 bytes of arbitrary manufacturer-specific data and are transmitted connectionlessly — no pairing, no GATT session, and no bonding ever occurs. An adversary or insider with a foothold on a Linux host (or an Android/embedded device) can encode staged data directly into the advertising payload using raw HCI commands (`hcitool cmd 0x08 0x0008`/`0x0006`, `btmgmt add-adv`) or a scripting library (bleak, bluepy, pybluez, gatttool) and repeatedly rewrite that payload at a fixed interval, effectively trickling data out a few dozen bytes at a time to any passive scanner within radio range — a phone, SBC, or dedicated receiver carried past the facility. This is a materially different exfiltration mechanism from the existing T1011.001 coverage on this platform (THREAT-Bluetooth-AirGapCourierExfil), which keys on a policy-disabled Bluetooth service being re-enabled and a subsequent OBEX file transfer following device pairing. The advertising-channel variant requires none of that: it needs no pairing, no bonding, no established connection, and can run on a host where Bluetooth was never disabled by policy in the first place (routine peripheral use), making the pairing/OBEX-based detection blind to it entirely. The reliable discriminator is process lineage and cadence rather than protocol state: legitimate BLE beacon deployments (retail/asset-tracking beacons) are configured once via a vendor daemon or systemd-managed service and left static, whereas advertising-based exfiltration requires the same low-level CLI tool or script to repeatedly re-issue the advertising-data-set command with a changing payload in a short window — a pattern with essentially no benign equivalent outside of BLE development/testing.
What is THREAT-BLEBeacon-AdvertisingChannelExfil Covert Data Exfiltration via Bluetooth LE Advertising Packet Encoding (Beacon Stuffing)?
Covert Data Exfiltration via Bluetooth LE Advertising Packet Encoding (Beacon Stuffing) (THREAT-BLEBeacon-AdvertisingChannelExfil) maps to the Exfiltration tactic — the adversary is trying to steal data in MITRE ATT&CK.
This page provides production-ready detection logic for Covert Data Exfiltration via Bluetooth LE Advertising Packet Encoding (Beacon Stuffing), covering the data sources and telemetry it touches: Microsoft Defender for Endpoint for Linux (DeviceProcessEvents), Process: Process Creation (Linux), BlueZ / D-Bus advertising registration logs. The queries below are rated medium severity at medium confidence, and ship for 7 SIEM platforms — KQL, SPL, Elastic, QRadar, Sumo, YARA-L, LogScale.
MITRE ATT&CK
- Tactic
- Exfiltration
let AdvertisingCliTools = dynamic(["hcitool", "btmgmt"]);
let BleScriptMarkers = dynamic(["bleak", "bluepy", "pybluez", "gatttool"]);
// Signal 1: raw HCI advertising-data-set command issued directly via CLI rather than a vendor beacon daemon
let RawHciAdvertising = DeviceProcessEvents
| where Timestamp > ago(24h)
| where DeviceOS =~ "Linux"
| where FileName in~ (AdvertisingCliTools)
| where ProcessCommandLine has_any ("cmd 0x08 0x0008", "cmd 0x08 0x0006", "add-adv", "advertise on", "advertising on")
| extend Signal = "RawHciAdvertisingCommand"
| project Timestamp, DeviceName, AccountName, FileName, ProcessCommandLine, Signal;
// Signal 2: scripted BLE advertising via a Python BLE library
let ScriptedBleAdvertising = DeviceProcessEvents
| where Timestamp > ago(24h)
| where DeviceOS =~ "Linux"
| where FileName in~ ("python", "python3")
| where ProcessCommandLine has_any (BleScriptMarkers)
| where ProcessCommandLine has_any ("advertis", "adv_data", "set_advertising", "AdvertisingData")
| extend Signal = "ScriptedBleAdvertising"
| project Timestamp, DeviceName, AccountName, FileName, ProcessCommandLine, Signal;
// Correlate: same host repeatedly re-issuing an advertising-set command/script within a short window
RawHciAdvertising
| union ScriptedBleAdvertising
| summarize InvocationCount = count(), FirstSeen = min(Timestamp), LastSeen = max(Timestamp),
Commands = make_set(ProcessCommandLine, 25), Signals = make_set(Signal)
by DeviceName, AccountName
| where InvocationCount >= 8
| where LastSeen - FirstSeen <= 10m
| sort by InvocationCount desc Detects connectionless BLE advertising-channel exfiltration (beacon stuffing) using Microsoft Defender for Endpoint Linux process telemetry. Signal 1 flags raw HCI advertising-data-set invocations (hcitool/btmgmt) issued directly from the command line rather than through a vendor beacon-management daemon. Signal 2 flags Python processes invoking a BLE scripting library (bleak/bluepy/pybluez/gatttool) with advertising-related arguments. The two signals are then aggregated per device/account: eight or more invocations within a 10-minute window is the discriminator, since a legitimate beacon is configured once and left static while advertising-based exfiltration requires repeatedly rewriting the payload to trickle data out.
Data Sources
Required Tables
False Positives
- BLE application developers or QA engineers repeatedly testing advertising payloads with hcitool/btmgmt or a BLE library during active development
- Legitimate beacon fleet management software that intentionally rotates advertising payloads on a schedule (e.g., rotating ephemeral tokens for a contact-tracing or asset-tracking beacon)
- Security researchers or red team operators authorized to test BLE covert channels as part of an approved engagement
- Automated BLE test harnesses / CI pipelines exercising an embedded device's advertising stack
Sigma rule & cross-platform mapping
The detection logic for Covert Data Exfiltration via Bluetooth LE Advertising Packet Encoding (Beacon Stuffing) (THREAT-BLEBeacon-AdvertisingChannelExfil) above is provided in a vendor-neutral
form so you can deploy it on any SIEM. The same logic is shipped here as native
KQL (Microsoft Sentinel / Defender), SPL (Splunk), Elastic (Elastic Security (EQL)), QRadar (IBM QRadar (AQL)), Sumo (Sumo Logic CSE), YARA-L (Google Chronicle / SecOps), LogScale (CrowdStrike LogScale (CQL)) queries. In Sigma terms, this detection targets the
following logsource:
logsource:
category: process_creation
product: windows Browse the community-maintained Sigma rules for this technique:
Platform-specific guides for THREAT-BLEBeacon-AdvertisingChannelExfil
Testing Methodology
Validate this detection against 3 adversary techniques from Atomic Red Team. Each test below lists the behaviour to exercise and the telemetry you should expect to see. Executable commands and cleanup steps are available with Pro.
- Test 1Set Custom BLE Advertising Data via Raw HCI Command
Expected signal: auditd EXECVE record for hcitool with 'cmd 0x08 0x0008' in argv and the hex advertising payload as trailing arguments. BlueZ bluetoothd/btmon capture (if enabled) showing the HCI_LE_Set_Advertising_Data command.
- Test 2Repeatedly Rewrite Advertising Payload to Simulate Data Trickle
Expected signal: Ten sequential auditd EXECVE records for hcitool within roughly 50 seconds, each with a distinct hex payload in argv.
- Test 3Advertise Custom Payload via Python BLE Library (bleak)
Expected signal: auditd EXECVE record for python3 with '-c' and the inline script referencing bleak and 'advertis' in the command line.
Response Playbook
Triage
- Confirm whether the host is expected to run any legitimate BLE beacon or advertising workload — check for a known vendor beacon-management daemon or systemd unit; if none exists, treat direct CLI/script advertising invocation as anomalous.
- Pull the full set of ProcessCommandLine/a0 values captured across the flagged invocations and attempt to decode any hex-encoded advertising payload fields (manufacturer-specific data, service data) for recognizable plaintext, base64, or structured data.
- Identify the account and interactive/remote session active on the host during the window — is this a known developer or automation account, or an unexpected session?
- Check whether the host has an unusually high number of distinct advertising-payload rewrites in a short window versus its historical baseline (a fixed beacon rarely if ever changes payload after initial configuration).
- Review DeviceFileEvents (or auditd file-open records) immediately preceding the advertising activity for access to sensitive files, credential stores, or archive creation that could be the source of the staged data.
- Check physical proximity/scanning logs if available (facility BLE scanners, mobile device management BLE inventory) for any newly observed nearby BLE receiver during the activity window.
Containment
- Terminate the offending process and, if the host has no legitimate BLE workload, disable the Bluetooth adapter/service (`rfkill block bluetooth` or `systemctl stop bluetooth`) pending investigation.
- Isolate the host from the network via EDR if the data being encoded is confirmed sensitive, since the exfiltration channel itself bypasses network-based controls entirely.
- Revoke or rotate any credentials/tokens found decoded from the captured advertising payloads.
- If tied to an interactive user session, coordinate with HR/Legal before personnel action if insider activity is suspected.
Evidence Collection
- Full auditd EXECVE records (argv) for every hcitool/btmgmt/python invocation in the flagged window, including exact advertising-payload hex strings
- BlueZ D-Bus advertising registration logs (`btmon` capture or `bluetoothd` debug log) if collected, showing the LE Set Advertising Data HCI command sequence
- Process ancestry for the flagged CLI/script invocation (parent shell, script file path, and any preceding file access to a staged data source)
- Host BLE adapter presence/state history (rfkill status, `hciconfig` output) to establish whether BLE was expected to be active on this asset class
Escalation Criteria
- ! The host is in a segment designated air-gapped, classified, isolated OT/ICS, or otherwise prohibited from having an active BLE radio by policy
- ! Decoded advertising payload content includes recognizable credentials, PII, or proprietary source/data fragments
- ! The invocation pattern spans multiple hosts, suggesting a coordinated or repeated exfiltration operation rather than isolated development/testing activity
- ! No legitimate BLE workload, change ticket, or documented exception exists for the flagged host
Investigation Guide
Forensic Artifacts
- >
auditd EXECVE records (/var/log/audit/audit.log) for hcitool/btmgmt/python process invocations with full argv, including the hex advertising payload - >
BlueZ bluetoothd logs and `btmon`/`hcidump` captures (if enabled) showing the raw HCI LE Set Advertising Data command sequence and payload history - >
Shell history (~/.bash_history, ~/.zsh_history) or script files referencing hcitool, btmgmt, bleak, bluepy, or gatttool - >
rfkill and systemd unit state history establishing whether the Bluetooth adapter was expected to be active/inactive on this asset class - >
Any staged data file referenced immediately prior to the advertising loop in file-access or auditd logs
Tuning Guidance
This detection is highest-value on asset classes that should never run a BLE advertising workload at all (general-purpose servers, hardened workstations, OT/ICS endpoints) — apply the invocation-count threshold loosely there since even a single occurrence is worth reviewing. On hosts with legitimate BLE development or beacon-management functions, raise the InvocationCount/window thresholds and maintain an allowlist keyed on the specific host/service account combination rather than the tool name, since hcitool/btmgmt/bleak are also the standard legitimate tooling for that exact workload. Where available, cross-reference facility BLE scanning logs or MDM BLE device inventories to corroborate that a receiving device was actually present during the flagged window, which meaningfully raises confidence beyond the process-telemetry signal alone.
Hunting Queries
30-day hunt across the fleet for any host invoking BLE advertising CLI tools or scripting libraries at all, regardless of frequency — establishes a baseline of expected BLE development/beacon-management hosts to allowlist and surfaces any asset class (particularly hardened or air-gapped tiers) where this activity has no legitimate explanation.
DeviceProcessEvents
| where Timestamp > ago(30d)
| where DeviceOS =~ "Linux"
| where FileName in~ ("hcitool", "btmgmt", "python", "python3")
| where ProcessCommandLine has_any ("cmd 0x08 0x0008", "add-adv", "advertise", "bleak", "bluepy", "pybluez", "gatttool")
| summarize Executions = count(), FirstSeen = min(Timestamp), LastSeen = max(Timestamp), Commands = make_set(ProcessCommandLine, 20)
by DeviceName, AccountName, FileName
| where Executions >= 3
| sort by Executions desc index=linux sourcetype="linux:audit" type=EXECVE exe IN ("*/hcitool","*/btmgmt","*/python","*/python3")
(a0="*0x0008*" OR a0="*add-adv*" OR a0="*advertise*" OR a0="*bleak*" OR a0="*bluepy*" OR a0="*pybluez*" OR a0="*gatttool*")
| stats count as Executions, values(a0) as Args by host, uid, exe
| where Executions >= 3
| sort - Executions Atomic Red Team Tests
Simulates encoding data into a BLE advertising payload using a raw HCI command via hcitool, the core mechanism of connectionless advertising-channel exfiltration.
Command
sudo hciconfig hci0 up && sudo hcitool -i hci0 cmd 0x08 0x0008 1E 02 01 1A 1A FF 4C 00 02 15 74 65 73 74 64 61 74 61 30 30 30 31 00 00 00 00 C5 00 Cleanup
sudo hcitool -i hci0 cmd 0x08 0x000A 00 2>/dev/null; sudo hciconfig hci0 down 2>/dev/null || true Expected Telemetry
auditd EXECVE record for hcitool with 'cmd 0x08 0x0008' in argv and the hex advertising payload as trailing arguments. BlueZ bluetoothd/btmon capture (if enabled) showing the HCI_LE_Set_Advertising_Data command.
Expected Detection
KQL/SPL RawHciAdvertisingCommand signal fires on the hcitool invocation matching 'cmd 0x08 0x0008'.
Loops the raw HCI advertising-data-set command with a changing payload to simulate trickling staged data out over multiple advertising intervals, the frequency signature this detection keys on.
Command
for i in $(seq 1 10); do sudo hcitool -i hci0 cmd 0x08 0x0008 1E 02 01 1A 1A FF 4C 00 02 15 $(printf '%02x' $i)$(printf '%02x' $i)000000000000000000000000000000 C5 00; sleep 5; done Cleanup
sudo hcitool -i hci0 cmd 0x08 0x000A 00 2>/dev/null; sudo hciconfig hci0 down 2>/dev/null || true Expected Telemetry
Ten sequential auditd EXECVE records for hcitool within roughly 50 seconds, each with a distinct hex payload in argv.
Expected Detection
KQL/SPL aggregation stage fires once InvocationCount reaches the 8-invocation threshold within the 10-minute window, flagging the DeviceName/AccountName pair.
Simulates a scripted, library-driven variant of the same technique using the bleak BLE library instead of raw hcitool commands, reflecting a more common real-world implementation approach.
Command
python3 -c "import asyncio; from bleak import BleakScanner; print('bleak advertis_data simulation: set_advertising_data test-payload-0001')" Cleanup
true Expected Telemetry
auditd EXECVE record for python3 with '-c' and the inline script referencing bleak and 'advertis' in the command line.
Expected Detection
KQL/SPL ScriptedBleAdvertising signal fires on the python3 invocation matching a BLE script marker (bleak) combined with an advertising-related keyword.
Related Detections
Tactic Hub
Detection Variants (1)
Different telemetry and tradecraft for the same technique — pick the one that matches the data you collect.