HackproofHacks
Vulnerability walkthrough · Injection

How to Exploit Command Injection: A Step-by-Step Lab Walkthrough

13 min read · Lab: DVWA

In one line

Command injection is when an app runs a system command using your input, so you sneak in an extra command and the server runs it for you.

What this is, for a beginner

Some applications build and run operating-system commands using user input, for example a network tool that pings an address you type. If the app passes your input into a shell without sanitising it, you can append your own command using shell metacharacters, and the server runs it with the privileges of the web application.

This is one of the highest-impact web flaws because it moves the attacker from the application into the underlying operating system. From there they can read sensitive files, enumerate the host, and often work toward a full shell. The root cause is the same as SQL injection: untrusted input reaching an interpreter, here the shell, without separation between code and data.

The legal lab we use: DVWA

DVWA has a command injection page (a ping tool). Run it locally so any command you inject executes only on your own machine.

DVWA project page →

Full walkthrough: exploiting it step by step

Step 1 — Open DVWA command injection on Low

Set DVWA Security to Low and open the Command Injection page, which pings an IP address you provide.

Expected result: A field that accepts an IP address and shows the output of a ping command run on the server.

Step 2 — Establish baseline behaviour

Enter a normal address and observe that the raw output of the server-side ping is displayed. That reflected command output is what you will hijack.

IP field
127.0.0.1

Expected result: The page shows the output of ping against 127.0.0.1, confirming your input is placed into a shell command.

Step 3 — Chain an extra command

Use a shell separator to append your own command after the ping. On Low there is no filtering, so both run and both outputs appear.

IP field
127.0.0.1; whoami

Expected result: The ping output is followed by the username the web server runs as, proving your injected command executed.

Step 4 — Read sensitive files

Escalate from proof to impact by reading a file the app should never expose, demonstrating real consequences.

IP field
127.0.0.1; cat /etc/passwd

Expected result: The contents of /etc/passwd are printed, showing you can read arbitrary files as the web-server user.

Step 5 — Bypass filters on higher levels

Set security to Medium and High. Medium strips some separators like semicolons, which you bypass with alternatives such as & or newline-based injection; High tightens this further, teaching you how filtering fails against a determined attacker.

alternative separator
127.0.0.1 && whoami

Expected result: An alternative separator still chains your command where a naive filter removed only the obvious one.

Free resource

Get the free 35-week ethical hacking roadmap

The exact order I'd learn this in, every vulnerability and tool, week by week, with the labs to practise each one. Enter your email and I'll send it over, plus one practical lesson each week.

How to detect and fix this

How to detect it

  • For any feature that looks like it runs a system command (ping, traceroute, conversions, exports), append shell separators and a benign command such as one that causes a measurable delay, to detect even blind command injection.
  • Watch timing and output differences; blind command injection is confirmed by an intentional delay or an out-of-band callback even when no output is shown.
  • In source, look for calls that pass user input to a shell; those are the direct culprits and are fastest to fix.

How to fix it

  • Avoid calling the shell with user input at all; use language APIs that perform the task directly instead of shelling out.
  • Where a system command is unavoidable, pass arguments as a list to the process rather than building a shell string, so input cannot be interpreted as extra commands.
  • Validate input strictly against an expected format (for example, a valid IP address) and reject anything else.
  • Run the application with least privilege so a successful injection cannot read or change more than necessary.

Common beginner mistakes

  • Trying only one separator; different shells and filters call for ;, &, |, or newlines, so keep several ready.
  • Expecting output for blind cases; use timing or out-of-band techniques when the result is not printed.
  • Confusing command injection with code injection; here you are injecting into the operating-system shell specifically.
  • Running these payloads anywhere but DVWA or a machine you own.

FAQ

What is the difference between command injection and SQL injection?

Both inject into an interpreter, but the target differs. SQL injection reaches the database query language, while command injection reaches the operating-system shell. Command injection often leads to fuller control of the host because it runs OS commands directly.

What is blind command injection?

It is command injection where the output is not returned to you. You confirm it by making the server take a measurable action, such as sleeping for a set number of seconds or making an outbound request you control, and observing the effect.

Why is command injection rated so severe?

Because it moves the attacker from the application into the operating system, where they can read files, enumerate the host, and often escalate toward a full shell. That is typically far more damaging than a flaw confined to the app.

Where to go from here

You just exploited one vulnerability in a lab. Here's the structured path.

Scattered tutorials teach you tricks; they don't make you a pentester. My mentorship is 35 weeks of exactly this, every vulnerability and tool in a deliberate order, on real labs, with one-on-one feedback on your work so your mistakes get caught early instead of becoming habits.

Keep practising