Skip to main content
Command injection happens when user input ends up concatenated into a shell command the application runs server-side, a “ping this IP” feature, a file conversion tool, anything that shells out internally. If the input isn’t sanitized, you’re not injecting a payload into the application, you’re writing directly into the operating system’s command line.

Visible (In-Band)

Command output appears directly in the application’s response. Confirm and move fast, this is the easy case.

Blind

No output returned. Confirm via time delay (sleep/ping) or out-of-band channel (DNS/HTTP callback to a server you control) instead.

Injection Operators

Which operator works (and what gets executed) depends on the shell and on whether the original command succeeds or fails.
|| is particularly useful when you don’t control the original input enough to guarantee success or failure, chaining && onto an already-failing ping just never executes, while || only needs the legitimate command to fail once, often easy to force with a malformed IP.

Confirming Blind Command Injection

When there’s no visible output, a time delay proves execution without needing to see anything back.
If even timing isn’t observable (async processing, a queued job), an out-of-band callback confirms execution by making the target reach out to infrastructure you control instead. A DNS lookup is the most reliable OOB channel since it rarely gets blocked by egress filtering the way raw HTTP might.
Burp Collaborator (or any DNS logging service you control) catches the callback and proves execution even with zero visible feedback.

Filtered Character Bypasses

Both of these abuse a variable that’s guaranteed to contain a / at a known offset, extracting just that character.
Same idea, pulling a ; out of an environment variable known to contain one.
tr can shift every character in a string by a fixed offset, letting you construct a blocked character from an allowed one and reverse the shift at execution time (see man ascii for the ordering).

Blacklisted Command Name Bypasses

The shell strips matched quote pairs before executing, so splitting a blocked command name with empty quotes doesn’t change what runs, just defeats a literal string match on the blacklist.

Obfuscation Tools

Automates obfuscating a bash payload well beyond what’s practical to hand-craft, useful against signature-based WAF/IDS detection rather than a basic keyword blacklist.

Reverse Shell via Injection

Once you’ve confirmed command injection, chaining into a reverse shell is usually the next move, see the Shells Cheatsheet for the full reference.

PHP Code Injection

Distinct from OS command injection, this targets an endpoint that evaluates PHP directly (often via eval() on user input) rather than shelling out to the OS. Worth testing both when a parameter looks dynamic, the payload and the impact are different even though they often get lumped together.

Quick Reference Tools

Hackviser: Command Injection

Reference used for this page.

HackTricks: Command Injection

Deeper dive into additional bypasses and edge cases.

PayloadsAllTheThings: Command Injection

Large categorized payload and bypass collection.

Commix

Automated command injection detection and exploitation tool.

Bashfuscator

Bash payload obfuscation framework.

Invoke-DOSfuscation

PowerShell/cmd payload obfuscation framework.
Command injection almost always means full code execution as the web server’s user. Confirm scope explicitly before moving past a whoami/sleep confirmation into a reverse shell or data exfiltration.