Security researchers have disclosed a previously undocumented malware framework dubbed BambooToken, active since at least 2023, that commandeers both Windows and Linux systems using the Message Queuing Telemetry Transport (MQTT) protocol for command-and-control (C2). This is not a theoretical curiosity — it is a confirmed, actively operating intrusion framework with a multi-year dwell time, which means it evaded mainstream detection for roughly two years before public reporting.
MQTT is a lightweight publish/subscribe messaging protocol designed for IoT and telemetry workloads. It typically rides on TCP 1883 (plaintext) and TCP 8883 (TLS). Because MQTT is legitimate, ubiquitous infrastructure in environments with IoT, OT, or message-bus architectures, C2 traffic tunneled through it blends into expected network flows. Traditional beaconing detection — periodic HTTP(S) callbacks to rare domains — does not apply here. Defenders running flat networks where any endpoint can egress to 1883/8883 are the most exposed.
If your SOC does not currently baseline MQTT traffic or alert on non-IoT assets speaking MQTT, treat this as a priority-one detection engineering task this week.
Technical Analysis
What BambooToken Is
BambooToken is a modular malware framework with builds for both Windows and Linux, in operation since at least 2023 per reporting on the BleepingComputer disclosure. Its defining characteristic is its C2 channel: rather than HTTP(S), DNS tunneling, or raw TCP callbacks, BambooToken acts as an MQTT client. Infected hosts connect to an attacker-controlled (or abused legitimate) MQTT broker, subscribe to a topic unique to the implant, and receive tasking by consuming published messages. Results are exfiltrated by publishing back to a response topic.
This architecture gives the operator several advantages:
- Broker indirection: The implant never talks directly to an attacker IP. It talks to a broker. Brokers can be legitimate cloud services (public brokers, IoT platforms), making blocklisting by IP reputation unreliable.
- Asymmetric, low-noise traffic: MQTT keep-alives and small publish packets look like ordinary telemetry. Payloads are small, binary, and easily overlooked in NetFlow.
- Cross-platform uniformity: One C2 protocol stack works identically on Windows and Linux, simplifying the operator's infrastructure.
Attack Chain (Defender's View)
- Initial access / staging: The implant binary is delivered to the target (exact vector varies by campaign). On Linux, expect droppers in world-writable or user-writable paths (
/tmp,/var/tmp,~/.config, hidden directories). On Windows, expect user-profile locations (%APPDATA%,%LOCALAPPDATA%,%ProgramData%) with benign-sounding names. - Persistence: Cross-platform frameworks typically pair scheduled tasks or registry Run keys (Windows) with systemd units, cron entries, or rc.local modifications (Linux). A multi-year operation implies reliable persistence — assume it until ruled out during IR.
- C2 establishment: The implant initiates an outbound TCP connection to port 1883 or 8883 on a broker, sends an MQTT
CONNECTpacket, and subscribes to its tasking topic. MQTT keep-alive intervals (often 60s+) produce low-frequency, periodic connection maintenance that resembles beacon timing in NetFlow even though application-layer content differs. - Tasking & exfiltration: Commands arrive as MQTT
PUBLISHmessages; output returns the same way. Because payloads are opaque binary, TLS on 8883 further blinds content inspection.
Exploitation Status
- Confirmed active in the wild since at least 2023 (per the source reporting).
- No CVE is associated with this disclosure — BambooToken is a malware framework, not a vulnerability. It is not on CISA KEV (KEV tracks vulnerabilities, not malware families).
- The disclosure itself will drive copycat adoption: MQTT-as-C2 is now publicly documented, and other operators will fold the technique into their toolkits. Detection value extends beyond BambooToken specifically.
Why This Evaded Detection
Most SOCs alert on (a) known-bad infrastructure, (b) anomalous user agents / JA3 on HTTP(S), and (c) high-volume exfil. MQTT C2 defeats all three: the broker may be legitimate infrastructure, there is no HTTP layer, and message sizes are tiny. The gap is protocol-aware egress monitoring — which processes, on which hosts, are speaking MQTT at all.
Detection & Response
The highest-fidelity detection primitive is simple: workstations, servers, and any non-IoT/OT asset should virtually never initiate outbound MQTT. A broker-side client-ID pattern or an endpoint process connecting to 1883/8883 outside an approved inventory is a strong signal. The rules below operationalize that.
Sigma Rules
---
title: Outbound MQTT Connection from Non-Standard Process
description: Detects processes outside an approved MQTT client list initiating connections to MQTT broker ports (1883/8883). BambooToken uses MQTT for C2 on Windows and Linux; legitimate MQTT should be confined to known IoT/agent binaries.
references:
- https://www.bleepingcomputer.com/news/security/bambootoken-malware-controls-windows-and-linux-systems-via-mqtt/
- https://attack.mitre.org/techniques/T1071/
author: Security Arsenal
date: 2026/02/14
tags:
- attack.command_and_control
- attack.t1071
logsource:
category: network_connection
product: windows
detection:
selection_ports:
DestinationPort:
- 1883
- 8883
filter_approved:
Image|endswith:
- '\mosquitto.exe'
- '\mosquitto_pub.exe'
- '\mosquitto_sub.exe'
- '\emqx.exe'
- '\iotedge.exe'
condition: selection_ports and not filter_approved
falsepositives:
- Approved IoT gateway software or custom telemetry agents — build an environment-specific allowlist of broker destinations and client binaries before enabling at high level
level: high
---
title: Linux Outbound MQTT Connection from Suspicious Path
description: Detects processes executing from world-writable or user-level paths on Linux initiating MQTT broker connections. BambooToken implants on Linux are staged from /tmp, /var/tmp, /dev/shm, or hidden user directories.
references:
- https://www.bleepingcomputer.com/news/security/bambootoken-malware-controls-windows-and-linux-systems-via-mqtt/
- https://attack.mitre.org/techniques/T1071/
author: Security Arsenal
date: 2026/02/14
tags:
- attack.command_and_control
- attack.t1071
- attack.t1036
logsource:
category: network_connection
product: linux
detection:
selection_ports:
DestinationPort:
- 1883
- 8883
selection_paths:
Image|startswith:
- '/tmp/'
- '/var/tmp/'
- '/dev/shm/'
- '/home/'
- '/run/user/'
condition: selection_ports and selection_paths
falsepositives:
- Developers running ad-hoc MQTT test clients from home directories — validate against change records
level: high
---
title: MQTT Client Utility Execution on Endpoint
description: Detects execution of standalone MQTT publish/subscribe utilities on systems where no IoT messaging role exists. Operators or staging scripts may invoke these to test broker reachability before implant deployment.
references:
- https://www.bleepingcomputer.com/news/security/bambootoken-malware-controls-windows-and-linux-systems-via-mqtt/
- https://attack.mitre.org/techniques/T1105/
author: Security Arsenal
date: 2026/02/14
tags:
- attack.command_and_control
- attack.t1105
logsource:
category: process_creation
product: windows
detection:
selection:
- Image|endswith:
- '\mosquitto_pub.exe'
- '\mosquitto_sub.exe'
- '\mqtt.exe'
- '\mqttx.exe'
- CommandLine|contains:
- 'mosquitto_pub'
- 'mosquitto_sub'
- 'mqtt pub'
- 'mqtt sub'
falsepositives:
- IoT development and QA workstations — scope to server and general-user populations
level: medium
KQL — Microsoft Sentinel / Defender
Hunt across endpoints for any process initiating MQTT connections, enriched with process and path context. Baseline first: export the distinct set of (DeviceName, InitiatingProcessFileName, RemoteIP) tuples over 30 days and classify them before treating outliers as incidents.
let MQTTPorts = dynamic([1883, 8883]);
DeviceNetworkEvents
| where TimeGenerated > ago(7d)
| where RemotePort in (MQTTPorts)
| where ActionType == "ConnectionSuccess"
| extend ProcessPath = tostring(InitiatingProcessFolderPath)
| summarize Connections = count(),
FirstSeen = min(TimeGenerated),
LastSeen = max(TimeGenerated),
RemoteIPs = make_set(RemoteIP, 20),
RemoteUrls = make_set(RemoteUrl, 20)
by DeviceName, InitiatingProcessFileName, ProcessPath, InitiatingProcessCommandLine, RemotePort
| where Connections >= 2
| order by FirstSeen asc;
// Correlate with process lineage to find the implant's parent/stager
let MQTTPorts = dynamic([1883, 8883]);
let mqtt_hosts = DeviceNetworkEvents
| where TimeGenerated > ago(7d) and RemotePort in (MQTTPorts)
| summarize by DeviceName, InitiatingProcessFileName, InitiatingProcessSHA256;
DeviceProcessEvents
| where TimeGenerated > ago(7d)
| where SHA256 in (mqtt_hosts | project InitiatingProcessSHA256)
or ProcessCommandLine has_any ("1883", "8883", "mqtt", "subscribe", "publish")
| project TimeGenerated, DeviceName, FileName, ProcessCommandLine,
InitiatingProcessFileName, InitiatingProcessCommandLine,
InitiatingProcessParentFileName, AccountName, SHA256
| order by TimeGenerated asc;
// Syslog/CEF path for Linux estates forwarding to Sentinel
Syslog
| where TimeGenerated > ago(7d)
| where SyslogMessage has_any ("1883", "8883", "mqtt")
| project TimeGenerated, Computer, ProcessName, SyslogMessage
| order by TimeGenerated desc;
Velociraptor VQL
Use this artifact for live triage of a suspected host: enumerate current MQTT connections joined with owning-process metadata, then sweep persistence locations commonly abused by cross-platform implants.
-- BambooToken triage: MQTT connections, owning processes, and persistence sweep
LET conns = SELECT Pid, Name, RemoteAddress, RemotePort, Status
FROM netstat()
WHERE RemotePort in (1883, 8883)
SELECT c.Pid AS Pid,
c.Name AS ConnName,
c.RemoteAddress AS BrokerIP,
c.RemotePort AS BrokerPort,
c.Status AS ConnStatus,
p.Exe AS ProcessPath,
p.CommandLine AS CommandLine,
p.Username AS Username,
p.CreateTime AS ProcessStart
FROM conns AS c
JOIN pslist() AS p ON c.Pid = p.Pid
-- Linux persistence sweep: systemd units and cron entries referencing user-writable paths
SELECT FullPath, Mtime, Size,
read_file(filename=FullPath) AS Content
FROM glob(globs=['/etc/systemd/system/*.service',
'/etc/systemd/user/*.service',
'/etc/cron.d/*',
'/var/spool/cron/*',
'/home/*/.config/systemd/user/*.service'])
WHERE Content =~ '/tmp/|/var/tmp|/dev/shm|/home/'
OR Content =~ '1883|8883|mqtt'
Remediation / Hardening Script
Default-deny egress for MQTT from non-IoT assets, then audit what breaks — that breakage list is your MQTT inventory (and possibly your compromise list).
# BambooToken containment - Windows endpoint egress control for MQTT
# Run elevated. Blocks outbound MQTT except from approved broker IPs.
$ApprovedBrokers = @("10.10.5.20", "10.10.5.21") # Replace with sanctioned broker IPs
# Audit first: log current outbound MQTT attempts
New-NetFirewallRule -DisplayName "MQTT-Egress-Audit-1883" -Direction Outbound `
-Protocol TCP -RemotePort 1883 -Action Allow -Profile Any -Enabled True | Out-Null
New-NetFirewallRule -DisplayName "MQTT-Egress-Audit-8883" -Direction Outbound `
-Protocol TCP -RemotePort 8883 -Action Allow -Profile Any -Enabled True | Out-Null
# Allow approved brokers, then default-deny the rest
New-NetFirewallRule -DisplayName "MQTT-Allow-Approved-1883" -Direction Outbound `
-Protocol TCP -RemotePort 1883 -RemoteAddress $ApprovedBrokers -Action Allow | Out-Null
New-NetFirewallRule -DisplayName "MQTT-Allow-Approved-8883" -Direction Outbound `
-Protocol TCP -RemotePort 8883 -RemoteAddress $ApprovedBrokers -Action Allow | Out-Null
New-NetFirewallRule -DisplayName "MQTT-Block-Default-1883" -Direction Outbound `
-Protocol TCP -RemotePort 1883 -Action Block | Out-Null
New-NetFirewallRule -DisplayName "MQTT-Block-Default-8883" -Direction Outbound `
-Protocol TCP -RemotePort 8883 -Action Block | Out-Null
# Hunt: any local process with an established MQTT connection right now
Get-NetTCPConnection -State Established |
Where-Object { $_.RemotePort -in 1883,8883 } |
ForEach-Object {
$proc = Get-Process -Id $_.OwningProcess -ErrorAction SilentlyContinue
[PSCustomObject]@{
RemoteIP = $_.RemoteAddress
RemotePort = $_.RemotePort
Process = $proc.ProcessName
Path = $proc.Path
PID = $_.OwningProcess
}
} | Format-Table -AutoSize
# BambooToken containment - Linux egress control + live MQTT connection audit
# Run as root. Default-deny MQTT egress except approved brokers.
APPROVED_BROKERS="10.10.5.20 10.10.5.21" # Replace with sanctioned broker IPs
# Allow approved brokers
for broker in $APPROVED_BROKERS; do
iptables -A OUTPUT -p tcp -d "$broker" --dport 1883 -j ACCEPT
iptables -A OUTPUT -p tcp -d "$broker" --dport 8883 -j ACCEPT
done
# Log and drop all other MQTT egress (logs feed your SIEM via syslog)
iptables -A OUTPUT -p tcp --dport 1883 -j LOG --log-prefix "MQTT-EGRESS-BLOCK: "
iptables -A OUTPUT -p tcp --dport 8883 -j LOG --log-prefix "MQTT-EGRESS-BLOCK: "
iptables -A OUTPUT -p tcp --dport 1883 -j DROP
iptables -A OUTPUT -p tcp --dport 8883 -j DROP
# Audit: identify any process currently holding an MQTT connection
echo "=== Established MQTT connections ==="
ss -tnp state established '( dport = :1883 or dport = :8883 )'
# Audit: binaries with MQTT client libraries linked (quick implant surface check)
echo "=== Processes referencing MQTT libraries ==="
for pid in $(ls /proc | grep -E '^[0-9]+$'); do
grep -qs "mqtt\|mosquitto\|paho" /proc/$pid/maps 2>/dev/null && \
echo "PID $pid: $(readlink /proc/$pid/exe 2>/dev/null)"
done
# Audit: persistence locations referencing suspicious paths or MQTT
grep -rlsE "/tmp/|/var/tmp|/dev/shm|1883|8883|mqtt" \
/etc/systemd/system/ /etc/cron.d/ /var/spool/cron/ 2>/dev/null
Remediation
There is no vendor patch for BambooToken — it is a malware framework, not a product vulnerability. Remediation is architectural and operational:
- Egress control (highest priority): Block outbound TCP 1883/8883 at the perimeter and host firewalls for all assets except an explicit allowlist of sanctioned MQTT brokers. There is almost never a reason a finance workstation or domain-joined server needs to reach an arbitrary MQTT broker.
- Inventory your legitimate MQTT estate: Enumerate every approved broker, client application, and IoT/OT segment. Anything outside that inventory speaking MQTT is an incident until proven otherwise. Feed firewall logs for 1883/8883 into your SIEM as a dedicated watchlist.
- Hunt before you block: Run the KQL and VQL queries above across a 30-day lookback before enabling blocking rules. Blocking first tips off an implant and destroys evidence of the broker infrastructure — capture the broker IPs, client IDs, and timing patterns for your IR case.
- Broker-side controls: If you operate internal brokers, require TLS with mutual authentication, disable anonymous access, enforce per-client ACLs on topics, and log CONNECT/SUBSCRIBE events. An internal broker with anonymous access is a C2 relay waiting to be abused.
- Persistence review on confirmed hits: For any host with an unauthorized MQTT connection, triage systemd units, cron, rc.local, and shell profiles (Linux) plus Run keys, scheduled tasks, and services (Windows). A framework with two-plus years of dwell time will have redundant persistence.
- Segment IoT/OT: MQTT-heavy segments should be isolated VLANs with no route to general server/user networks. This both contains legitimate broker compromise and removes the "cover traffic" that BambooToken-style C2 hides inside.
- IR escalation: If hunting surfaces confirmed unauthorized MQTT C2, treat it as a full intrusion — preserve memory and disk images before remediation, identify initial access, and scope laterally. Dwell time measured in years means the operator has had time to entrench.
Reference: BleepingComputer — BambooToken malware controls Windows and Linux systems via MQTT
Related Resources
Security Arsenal Penetration Testing Services AlertMonitor Platform Book a SOC Assessment vulnerability-management Intel Hub
Is your security operations ready?
Get a free SOC assessment or see how AlertMonitor cuts through alert noise with automated triage.