DEV Community

Cover image for Command Injection: How Can You Test It Safely and Fix It Fast?
Jer Catallo
Jer Catallo

Posted on

Command Injection: How Can You Test It Safely and Fix It Fast?

Command injection happens when an app puts user input into a system command without safe checks. If this happens, an attacker can add extra commands and make the server run them.

In this case, the page asks for an IP address and then runs ping. The input is passed directly to the shell.

Example of vulnerable code:

<?php
$address = $_GET["address"];
$result = passthru("/bin/ping -c 4 " . $address);
?>
Enter fullscreen mode Exit fullscreen mode

If address includes shell operators like &, ;, or |, the command flow changes and extra commands can run.

Ethical Considerations

Use this only in a legal lab, CTF, or environment where you have clear permission. Do not test random public targets. Keep testing controlled and report real issues through the correct disclosure process.

Walkthrough

Step 1: Confirm normal behavior

Short context: first, we check the expected behavior with normal input.

Command/payload:

127.0.0.1
Enter fullscreen mode Exit fullscreen mode

This should only run the ping feature.

Result and analysis: the output shows a valid ping result for 127.0.0.1. You can see the app executes a system command using user input.

Step 2: Test command chaining

Short context: now we test if shell separators are accepted.

Command/payload:

& dir
Enter fullscreen mode Exit fullscreen mode

& asks the shell to run another command, and dir lists files.

Result and analysis: output shows css img index.php js test.php. This confirms injected commands are executed, and because dir works, the command context is Windows OS.

Step 3: Read source code via injection

Short context: after confirming execution, we read server-side code to find the root cause.

Command/payload:

& cat index.php
Enter fullscreen mode Exit fullscreen mode

This asks the server to print index.php.

Result and analysis: the output includes PHP code that appends user input to passthru("/bin/ping -c 4 ".$_GET["address"]);. This explains why command injection works.

Step 4: Check execution user

Short context: next, we identify which account executes the injected commands.

Command/payload:

& whoami
Enter fullscreen mode Exit fullscreen mode

whoami is used to verify runtime privileges.

Result and analysis: output is www-data, so commands run as the web server user.

Step 5: Verify impact by reading sensitive data

Short context: last, we validate impact with controlled file access in the lab target.

Command/payload:

& cat /home/tryhackme/flag.txt
Enter fullscreen mode Exit fullscreen mode

This checks if arbitrary file read is possible.

Result and analysis: output shows THM{COMMAND_INJECTION_COMPLETE}. This confirms full command injection impact in the target.

Remediation

Use layered fixes, not only one fix.

  1. Strict input validation and safe escaping:
<?php
$address = $_GET["address"];

if (!filter_var($address, FILTER_VALIDATE_IP)) {
    die("Invalid IP address");
}

$result = passthru("/bin/ping -c 4 " . escapeshellarg($address));
?>
Enter fullscreen mode Exit fullscreen mode
  1. Avoid shell calls when possible, use safer application logic or dedicated libraries.
  2. Reduce service privileges, run web processes with minimum permissions.
  3. Add detection controls, monitor payloads like & whoami or ; cat /etc/passwd.

Summary

You can see the chain clearly: normal input works, chained input runs extra commands, application code is exposed, runtime user is identified, and sensitive files are readable.

Main lesson: never place raw user input inside OS commands. Validate input, escape safely, avoid shell calls, and keep permissions low.

Top comments (0)