Command Injection in DVWA

Introduction
Command Injection is a web vulnerability that occurs when an application passes user-controlled input directly to a system shell without proper validation. In such cases, an attacker can manipulate the input to execute arbitrary operating system commands on the server.
At first glance, this type of vulnerability may seem similar to other input-based issues, but the potential impact is often more severe. Instead of only affecting application behavior, Command Injection can provide direct interaction with the underlying system. This may allow an attacker to gather system information, interact with files, or execute commands with the same privileges as the web service.
This post examines how a Command Injection vulnerability can be identified and exploited in the Damn Vulnerable Web Application (DVWA). The behavior is analyzed across three different security levels (Low, Medium, and High), with the goal of determining the user under which the web service is running, as well as the hostname of the target machine.
A screencast demonstrating the attack process can be viewed below:
https://www.youtube.com/watch?v=2kST1MNOiqk
Attack Overview
| Parameter | Description | |
|---|---|---|
| Target application | DVWA | |
| Vulnerability class | Command Injection | |
| CWE | CWE-77: Improper Neutralization of Special Elements used in a Command | |
| OWASP Top 10 | A05:2025 Injection | |
| Attack vector | Network | |
| Security levels tested | Low, Medium, High | |
| Tools used | Browser, Kali Linux | |
| Impact | Identify the web service user and system hostname via RCE |
Lab Environment
| Component | Configuration |
|---|---|
| Virtualization platform | Oracle VirtualBox |
| Attacker system | Kali Linux |
| Target system | Ubuntu Server 24.04 LTS |
| Application stack | Apache2, PHP 8.3.x, MariaDB |
| Vulnerable application | Damn Vulnerable Web Application (DVWA) |
| Network configuration | Host-only isolated network |
Vulnerability description
The vulnerability exists because the application uses user-controlled input as part of a system command without properly sanitizing or restricting that input.
In the Command Injection module, the application expects the user to enter an IP address, which is then passed to a command such as ping. If the input is not handled securely, an attacker can append additional shell operators and inject unintended commands.
As a result, the attacker may execute arbitrary operating system commands with the same privileges as the web server process. In this lab, the objective is to use this behavior to identify the user of the web service and the hostname of the target machine.
At the Low security level, no effective filtering is applied, allowing direct command injection.
At the Medium security level, the application attempts to block certain command separators, but the protection can still be bypassed using alternative shell operators.
At the High security level, additional filtering is introduced. However, the blacklist remains flawed and can still be bypassed due to incomplete pattern matching.
Figure 1: Command Injection module interface in DVWA.
Low Security Level
At the Low security level, the application is vulnerable because user input is passed directly into a system command without any validation or sanitization.
In the source code, the value supplied in the ip parameter is assigned to $target and then concatenated directly into a shell_exec() call:
\(target = \)_REQUEST['ip'];
\(cmd = shell_exec('ping -c 4 ' . \)target);
Because the application does not validate or restrict the input, an attacker can append shell operators such as ; and inject additional commands.
Attack Steps
1. Test for command injection
Enter the following payload:
127.0.0.1; whoami
Figure 2: Injected payload (127.0.0.1; whoami) submitted in the DVWA input field.
2. Analyze the response
The response includes:
www-data
This confirms that the injected command was executed on the server.
Figure 3: Server response showing the output of the injected whoami command (www-data).
3. Extract system information
To achieve the objective, retrieve the hostname:
127.0.0.1; hostname
Figure 4: Injected payload (127.0.0.1; hostname) used to retrieve system information.
4. Analyze the response
The response returns the hostname of the system, confirming full command execution.
Figure 5: Server response displaying the hostname of the target system.
Result
The application is vulnerable to Command Injection, as user input is directly incorporated into a system command without validation. This allows arbitrary commands to be executed, enabling the attacker to identify both the web service user and the system hostname.
Medium Security Level
At the Medium security level, the application introduces basic input filtering in an attempt to prevent command injection.
In the source code, the user input is processed using a blacklist that removes specific command separators:
$substitutions = array(
'&&' => '',
';' => '',
);
\(target = str_replace(array_keys(\)substitutions), \(substitutions, \)target);
This means that common operators such as ; and && are removed from the input before it is passed to the system command. However, this approach is incomplete, as it only targets a limited set of patterns.
Since other shell operators are not filtered, it is still possible to inject commands using alternative syntax.
Attack Steps
1. Bypass the filter
Use an alternative operator that is not restricted by the blacklist:
127.0.0.1 | whoami
Figure 6: Injected payload (127.0.0.1 | whoami) used to bypass the blacklist filter.
2. Analyze the response
The response includes:
www-data
This confirms that command injection is still possible.
Figure 7: Server response showing the output of the injected whoami command (www-data).
3. Extract system information
127.0.0.1 | hostname
Figure 8: Injected payload (127.0.0.1 | hostname) used to retrieve system information.
4. Analyze the result
The hostname is returned, confirming successful command execution.
Figure 9: Server response displaying the hostname of the target system.
Result
The application remains vulnerable to Command Injection.
Although basic filtering is implemented, it relies on a blacklist that only removes specific patterns. This approach is insufficient, as attackers can use alternative shell operators to bypass the restriction.
High Security Level
At the High security level, the application attempts to apply stricter blacklist-based filtering to prevent command injection.
In the source code, multiple potentially dangerous characters and patterns are removed from the user input:
$substitutions = array(
'||' => '',
'&' => '',
';' => '',
'| ' => '',
'-' => '',
'$' => '',
'(' => '',
')' => '',
'`' => '',
);
The input is also trimmed before processing:
\(target = trim(\)_REQUEST['ip']);
While this appears to be a more comprehensive defense, the filtering logic contains a flaw. The application removes the pattern | (pipe followed by a space), but does not remove the pipe character | on its own.
As a result, it is still possible to inject commands by using the pipe operator without a trailing space.
Attack Steps
1. Bypass the filter
Use:
127.0.0.1|whoami
Figure 10: Injected payload (127.0.0.1|whoami) used to bypass the blacklist filter.
2. Analyze the response
The response includes:
www-data
This confirms that command injection is still possible.
Figure 11: Server response showing the output of the injected whoami command (www-data).
3. Extract system information
127.0.0.1|hostname
Figure 12: Injected payload (127.0.0.1|hostname) used to retrieve system information.
4. Analyze the result
The hostname is returned, confirming successful command execution.
Figure 13: Server response displaying the hostname of the target system.
Result
The application remains vulnerable to Command Injection.
Despite extensive filtering, the blacklist implementation is flawed due to incomplete pattern matching. In this case, a minor mistake in how the pipe operator is filtered allows the attacker to bypass the protection.
This demonstrates that blacklist-based filtering is inherently unreliable, as attackers can exploit small implementation errors.
Attack Methodology
This attack can be mapped to the Cyber Kill Chain model, although Command Injection in DVWA is a focused exploitation scenario rather than a full intrusion lifecycle.
Reconnaissance
The attacker identifies that the application accepts an IP address as input and uses it to perform a system-level operation (ping). This suggests that user input may be incorporated into a system command.
Weaponization
The attacker crafts payloads that include shell operators combined with additional commands, such as whoami and hostname, to test whether command execution is possible.
Delivery
The payloads are delivered through the application's input field, where the user is expected to provide an IP address.
Exploitation
The vulnerability is exploited when the application executes the supplied input as part of a system command. By including shell operators, the attacker is able to inject and execute additional commands on the underlying operating system.
Installation
This phase is not applicable in this scenario, as no persistence or malware is introduced.
Command and Control
Not applicable, as no remote communication channel is established.
Actions on Objectives
The attacker successfully retrieves the web service user and the system hostname, demonstrating remote command execution and confirming that the application is vulnerable.
Impact Analysis (CIA)
From a CIA perspective, Command Injection has a direct impact on the underlying operating system and can lead to serious security consequences.
The most immediate impact is on integrity. Since arbitrary commands can be executed, an attacker may modify files, alter application behavior, or perform unintended actions on the system. In the lab environment, this is demonstrated by executing commands such as whoami and hostname.
Confidentiality is also at risk, as command execution may allow an attacker to read sensitive files, retrieve configuration data, or gather system information that can be used to support further attacks.
Availability may be affected if the attacker executes resource-intensive or destructive commands. While the DVWA scenario is limited to information gathering, the same vulnerability could be used to disrupt system functionality in a real-world environment.
Overall, Command Injection represents a high-risk vulnerability, as it can lead to direct system-level compromise.
Severity Assessment (CVSS v3.1)
The severity of this vulnerability was assessed using the Common Vulnerability Scoring System (CVSS v3.1).
The vulnerability can be exploited remotely over the network and does not require prior authentication. Additionally, no user interaction is required, as the attacker can directly submit crafted input to the application.
Because the application allows execution of arbitrary operating system commands, the potential impact on confidentiality, integrity, and availability is considered high. An attacker could read sensitive files, modify system data, or disrupt system functionality.
Although the lab scenario is limited to retrieving basic system information such as the service user and hostname, the underlying vulnerability represents a far more severe risk in real-world environments.
| Metric | Value |
|---|---|
| CVSS Version | CVSS v3.1 |
| Base Score | 8.8 (High) |
| Attack Vector | Network |
| Attack Complexity | Low |
| Privileges Required | None |
| User Interaction | None |
| Scope | Unchanged |
| Confidentiality Impact | High |
| Integrity Impact | High |
| Availability Impact | High |
Mitigation strategies
The Command Injection vulnerabilities observed in DVWA are primarily caused by insufficient input validation and an overreliance on blacklist-based filtering.
At the lower security levels, user input is passed directly into a system command without any restrictions, making exploitation trivial. At the Medium and High levels, the application attempts to block specific characters, but these protections are ineffective because they rely on filtering known patterns rather than enforcing strict validation.
A more secure approach would be to validate input against a strict allowlist. In this scenario, the application expects an IP address, which means only numeric values and a specific format should be accepted. Any input that does not match this structure should be rejected before it reaches the command execution logic.
In addition, applications should avoid passing raw user input directly into system commands whenever possible. Safer alternatives, such as built-in functions or controlled execution methods, should be used instead.
Finally, even if command execution is required, the application should run with minimal privileges to reduce the potential impact of exploitation.
Overall, the key lesson is that blacklist-based filtering is not sufficient. Secure implementations must ensure that user input cannot alter the structure of system-level commands.
Secure Implementation Example
At the Impossible security level, the application applies a significantly stronger defense by validating the input before it is used in the system command.
Instead of relying on blacklist-based filtering, the application enforces a strict input format by requiring the value to match an IPv4 address. The input is split into four octets, and each octet must be numeric before the command is executed:
\(octet = explode( ".", \)target );
if( ( is_numeric( \(octet[0] ) ) && ( is_numeric( \)octet[1] ) ) && ( is_numeric( \(octet[2] ) ) && ( is_numeric( \)octet[3] ) ) && ( sizeof( $octet ) == 4 ) )
By enforcing this structure, the application ensures that only valid IP addresses are accepted. As a result, injected shell operators such as ;, &&, or | cannot be included in the final command.
The Impossible level also introduces anti-CSRF protection:
checkToken( \(_REQUEST[ 'user_token' ], \)_SESSION[ 'session_token' ], 'index.php' );
While this does not directly prevent command injection, it adds an additional layer of protection by requiring a valid session-bound token.
This implementation demonstrates that strict allowlist validation is more effective than blacklist-based filtering when handling security-sensitive input.





