Detection Engineering

Command Injection Logs: What to Watch

Command injection detection from logs — the telemetry that exposes OS command injection, Sigma and Suricata rules, a CVE-2024-3400 case study, and hardening.

A dark Linux terminal showing a shell command log with one injected command line flagged in red

Command injection detection comes down to one unmistakable signal: a web or application service process spawning a shell. Web servers serve pages; they do not run bash, sh, cmd.exe, or powershell. When nginx, java, or php-fpm launches a shell interpreter, that is command injection in progress. The web-tier signatures catch the noisy attempts; the process-creation signal catches the one that worked. This guide ships both.

OS command injection turns a web request into code execution with the privileges of the service. It maps to A03:2021 — Injection and remains a favorite of both nation-state and opportunistic attackers. The 2024 PAN-OS flaw CVE-2024-3400 — a CVSS 10.0 command injection in GlobalProtect, exploited in the wild as Operation MidnightEclipse — is the worked example here.

What is OS command injection?

OS command injection is an attack where untrusted input is passed into a shell the application invokes, so the attacker’s text becomes additional operating-system commands. The app meant to run ping <host>; the attacker supplies 8.8.8.8; cat /etc/passwd and the shell happily runs both. Unlike SQL injection, which stays in the database, command injection lands the attacker a shell on the host.

The payoff is code execution as the service account, which is why it maps to T1190 — Exploit Public-Facing Application for entry and T1059 — Command and Scripting Interpreter for the shell it spawns.

What are the types of command injection?

Three variants matter for detection, and each surfaces in a different place.

VariantWhat the attacker seesTelemetry fingerprintBest detection layer
In-band (results returned)Command output in the HTTP responseShell metacharacters in params + odd responseWeb logs
BlindNo output; infers successTime delays, or out-of-band DNS/HTTP callbacksEgress + process telemetry
Out-of-bandForces a callback to attacker hostDNS/HTTP to a freshly seen domain from the web hostDNS + egress logs

The lesson: web parameters catch in-band attempts, but blind and out-of-band injection only show up in process-creation and egress telemetry. That is why the shell-spawn signal is the backbone of command injection detection.

How to detect command injection

Layer it from the web request to the shell it spawns.

The backbone: a service process spawning a shell

This is the highest-fidelity rule you can deploy, and it catches every variant regardless of how the payload arrived — the same process-creation logic behind SQL injection detection’s database-shell rule.

Sigma Web Service Process Spawning a Shell Interpreter
title: Web Service Process Spawning a Shell Interpreter
id: 3a7c2e91-darkpwn-illustrative
status: experimental
logsource:
  category: process_creation
detection:
  parent:
    ParentImage|endswith: ['\nginx.exe','\httpd','\apache2','\java.exe','\php-fpm','\w3wp.exe']
  child:
    Image|endswith: ['\bash','\sh','\cmd.exe','\powershell.exe','\python','\perl']
  condition: parent and child
falsepositives:
  - CGI apps that legitimately shell out (allowlist the specific parent/child pair)
level: high

Web tier: shell metacharacters in parameters

A triage signal for the in-band variant — pair it with rate thresholds so a single scanner request does not page anyone.

Sigma Suspicious Command Tokens in Web Request Parameters
title: Suspicious Command Tokens in Web Request Parameters
id: 5b9d1f64-darkpwn-illustrative
status: experimental
logsource:
  category: webserver
detection:
  selection:
    cs-uri-query|contains: [';cat ',';id',';whoami','|nc ','$(', '`id`','&&curl','%3Bcat']
  condition: selection
falsepositives:
  - Scanners and DAST runs; allowlist their source IPs
level: medium

For perimeter IDS, a Suricata rule flags shell metacharacters in request bodies (reserve SID 1000004+):

Suricata Shell Metacharacters in HTTP Request
alert http any any -> $HTTP_SERVERS any (
    msg:"DARKPWN Shell metacharacters in HTTP request (possible command injection)";
    flow:established,to_server; http.uri;
    pcre:"/(\x3b|\x7c|%3b|%7c|\x60|\x24\x28)\s*(id|whoami|cat|curl|wget|nc)\b/i";
    classtype:web-application-attack; sid:1000004; rev:1;)

How to test your command injection detection

Validate in a lab you own, never against a third party:

  1. Stand up a deliberately vulnerable app (DVWA’s command-injection module, or a throwaway endpoint that shells out).
  2. Trigger the in-band variant and confirm the web-token and process-spawn rules fire.
  3. Trigger a blind/out-of-band variant (a callback to a host you control) and confirm the egress/DNS signal fires.
  4. Replay benign traffic and your DAST scan to confirm the rules stay quiet, then record the false-positive sources in each rule.

How to prevent command injection

  • Run services at least privilege so a shell that does spawn is boxed in (NIST 800-53 AC-6).
  • Patch internet-facing appliances fast — CVE-2024-3400 was added to CISA’s KEV catalog and exploited within days of disclosure.
  • Default-deny egress from web hosts so blind/out-of-band callbacks become blocked, logged events.

Common command injection detection mistakes

  • WAF-only coverage. Parameter signatures miss filename-smuggled and blind variants — exactly the CVE-2024-3400 pattern.
  • No process-creation telemetry. Without it, the backbone signal is invisible.
  • Ignoring egress. Blind and out-of-band injection live in DNS and outbound logs, not request logs.
  • Untuned metacharacter rules that page on every scan and get muted.

Command injection detection checklist

  1. Forward process-creation, web access, and DNS/egress logs to the SIEM.
  2. Deploy the service-process-spawns-a-shell rule — the highest-fidelity signal.
  3. Add the web-parameter metacharacter rule with a per-IP rate threshold.
  4. Add the Suricata metacharacter rule where you have TLS visibility.
  5. Chain shell-spawn alerts to child processes (curl/wget/base64) and new egress.
  6. Default-deny egress from web hosts; alert on new outbound destinations.
  7. Replace shelled-out commands with argument-array APIs in code review.
  8. Run services at least privilege; patch internet-facing appliances on a KEV cadence.
  9. Fire every rule in a lab against true-positive and benign traffic.

The takeaway

Command injection detection is a behavior problem, not a string-matching one. Watch for a service process spawning a shell, chain it to what the shell does next, and remove the bug class by never building shell commands from untrusted input. Command execution also arrives straight from the keyboard — see USB Rubber Ducky detection patterns. Continue across the web-application attack surface with SQL injection detection and SSRF detection, or follow the data back out of the network with DNS tunneling detection. Or browse the full Detection Engineering pillar.

Training & tools referenced

Disclosure: Some links below are affiliate links. If you buy through them, darkpwn may earn a commission at no extra cost to you. We only recommend training and tools we actually use in our own lab, and affiliate links never influence editorial coverage.

  • TryHackMeAuthorized labs to practice command-injection detection against real telemetrySecurity Training
    Start training

Frequently asked questions

How do you detect command injection in logs?

The highest-fidelity signal is a web or application service process (nginx, apache, java, php-fpm) spawning a shell interpreter such as bash, sh, cmd.exe, or powershell. At the web tier, watch request parameters for shell metacharacters and command tokens, and watch for unexpected outbound connections from the web host.

What is the difference between command injection and code injection?

Command injection runs operating-system commands through a shell the application invokes (for example, passing input to system() or a shell call). Code injection runs code in the application's own language or runtime. Command injection maps to MITRE ATT&CK T1059; the detection signal is a service process spawning a shell.

Which MITRE ATT&CK technique covers command injection?

Command injection against an internet-facing app maps to T1190 (Exploit Public-Facing Application) for the entry and T1059 (Command and Scripting Interpreter) for the shell execution it produces.

Can a WAF stop command injection?

A WAF blocks obvious shell-metacharacter payloads and is worth running, but encoding, blind, and second-order variants bypass tuned-down rules. The durable control is avoiding shell calls with untrusted input; the durable detection is process-creation telemetry showing a service spawning a shell.

Newsletter

Liked this breakdown?

Defensive security research — detection, hardening, and hardware — delivered when there is something worth saying. No spam, unsubscribe anytime.