In this write-up, I document how I solved a file upload vulnerability labs, providing practical examples and evidence to explain how I conducted the penetration test and identified the vulnerabilities, step by step

None

A file upload vulnerability occurs when a web server allows users to upload files to its filesystem without sufficiently validating aspects such as the file's name, type, content, or size. When these restrictions are not properly enforced, attackers can upload malicious files, such as server-side scripts (e.g., PHP, JSP) or web shells, which can lead to complete server compromise

SOLVED LABS :

Lab-1: Remote code execution via web shell upload

This lab contains a vulnerable image upload function. It doesn't perform any validation on the files users upload before storing them on the server's filesystem.

To solve the lab, upload a basic PHP web shell and use it to exfiltrate the contents of the file /home/carlos/secret. Submit this secret using the button provided in the lab banner.

You can log in to your own account using the following credentials: wiener:peter

  • My goal was to read the content of /home/carlos/secret
  • Using the provided credentials wiener:peter , i logged into the account
  • First, i uploaded a normal image to understand how the upload functionality works and how the server handles uploaded files
None
  • At this point, I proceeded to exploit the vulnerability by creating a malicious PHP web shell:
None
<?php echo file_get_contents('/home/carlos/secret'); ?>
  • I uploaded it as my avatar by replacing the original image in the request
  • Since the server did not validate the file type, the upload was accepted successfully
None
None
None
  • I then accessed the uploaded file, retrieved the secret, and solved the lab

Why this works for more understanding :

  • After uploading a normal image successfully, I attempt to upload a PHP web shell file. The upload was accepted without any restrictions, this confirms that the application is vulnerable to a file upload vulnerability
  • To better understand this behavior, I illustrate it with a simple example, let's assume that the back-end PHP code of upload image functionality is like :
<?php
$target_dir = "files/avatars/";
$target_file = $target_dir . $_FILES["avatar"]["name"];

if (move_uploaded_file($_FILES["avatar"]["tmp_name"], $target_file)) 
    echo "file uploaded successfully";
else
    echo "upload failed";
?>
  • The PHP code directly saves the uploaded file without performing any security checks, it does not validate the file extension, verify the file type or restrict executable files, as a result of this, I was able to perform a RCE Remote Code Execution by uploading PHP file and executing it on server

Lab-2: Web shell upload via Content-Type restriction bypass

This lab contains a vulnerable image upload function. It attempts to prevent users from uploading unexpected file types, but relies on checking user-controllable input to verify this.

To solve the lab, upload a basic PHP web shell and use it to exfiltrate the contents of the file /home/carlos/secret. Submit this secret using the button provided in the lab banner.

You can log in to your own account using the following credentials: wiener:peter

  • In this lab the previous method did not work
  • However, I intercepted the POST request and changed the the Content-Type from application/x-phpto image/jpeg , then it worked successfully
None
None
Content-Type: application/x-php
None
changed the the Content-Type from application/x-php to image/jpeg
  • The malicious PHP file has been stored in the server
  • I then went back to account page to intercept the request to retrieve the uploaded file
None
None
  • Finally, I retrieved the content of target file, and solved the lab

Lab-3: Web shell upload via path traversal

This lab contains a vulnerable image upload function. The server is configured to prevent execution of user-supplied files, but this restriction can be bypassed by exploiting a secondary vulnerability (path traversal vulnerability).

To solve the lab, upload a basic PHP web shell and use it to exfiltrate the contents of the file /home/carlos/secret. Submit this secret using the button provided in the lab banner.

You can log in to your own account using the following credentials: wiener:peter

  • In this lab, the application prevents execution of uploaded files, this indicates that the server likely blocks execution in the upload directory
None
the file is uploaded, but it did not retrieve the content, this is due to execution restrictions on the server
  • After intercepting the POST request of upload function, I noticed that the file is uploaded with a filename parameter:
Content-Disposition: form-data; name="avatar"; filename="image.jpg"
  • This gave me an idea: if the application does not properly sanitize the filename, I may be able to perform a path traversal attack
  • Instead of uploading the file normally, I modified the filename to traverse directories :
filename="..%2fexploit_.php"
None
  • To move the uploaded file outside the images directory, and this allows placing the file in a directory where PHP execution is enabled
None
  • Then, I went back to my account page where I intercepted the GET request and noticed that the server executed the malicious file successfully to retrieve the content of target file

Lab-4: Web shell upload via extension blacklist bypass

This lab contains a vulnerable image upload function. Certain file extensions are blacklisted, but this defense can be bypassed due to a fundamental flaw in the configuration of this blacklist.

To solve the lab, upload a basic PHP web shell, then use it to exfiltrate the contents of the file /home/carlos/secret. Submit this secret using the button provided in the lab banner.

You can log in to your own account using the following credentials: wiener:peter

  • I first attempted to upload a malicious file containing a PHP web shell, but the upload was rejected and all previous methods failed, which indicated that the application uses an extension blacklist to block specific file extensions such as .php
None
None
  • When I intercepted the POST request of upload function, I noticed that the server was running apache service, which gave me an idea to bypass the restriction by modify the filename parameter to .htaccess file
  • I modified Content-Type value to text/plain to avoid triggering the file checks
  • Inside the .htaccess file, I added the following directive :
AddType application/x-httpd-php .anrxsec
  • This instructs the server to treat files with .anrxsec extension as PHP files
None
  • Next, I uploaded malicious PHP web file but changed its filename to exploit_.anrxsec , since this extension was not blacklisted, the server was accepted the upload file successfully
None
  • Then, i refreshed the account page and intercepted the GET request to verify that the file had been uploaded
None
  • This trick was successful in this lab. I started by adding a new directive in the .htaccess file to allow the .anrxsec extension. Then, I modified the Content-Type value to text/plain to bypass the restriction. Next, I uploaded the malicious file. This file was executed on the server, and I retrieved the content of the target file

Lab-5: Web shell upload via obfuscated file extension

This lab contains a vulnerable image upload function. Certain file extensions are blacklisted, but this defense can be bypassed using a classic obfuscation technique.

To solve the lab, upload a basic PHP web shell, then use it to exfiltrate the contents of the file /home/carlos/secret. Submit this secret using the button provided in the lab banner.

You can log in to your own account using the following credentials: wiener:peter

  • Like the previous labs , I started with intercepting the POST request of avatar upload functionality
  • When attempted to upload a PHP web shell malicious file, I observed that the server rejected the request and only accepted .jpg and .png extensions
None
  • Usually, this behavior indicates that the application performs validation the file extension, however this validation is insufficient and can be bypassed using an obfuscation technique
  • To exploit this, I modified the filename parameter to :
filename="exploit.php%00.jpg" 
  • %00 : represents a null byte, the server processes the filename as: exploit.php and the .jpg part is ignored after the null byte
  • Let's assume the back-end implementation looks like this:
<?php
$upload_dir = "files/avatars/";
$filename = $_FILES['avatar']['name'];

if (preg_match('/\.php$/i', $filename))
    die("invalid file type");

if (!preg_match('/\.(jpg|png)$/i', $filename))
    die("only JPG and PNG allowed");

move_uploaded_file($_FILES['avatar']['tmp_name'], $upload_dir . $filename);

echo "upload successfull";
?>
  • When I sent:
filename="exploit.php%00.jpg"
None
  • The server handled the filename as:
exploit.php\0.jpg
  • During the validation phase, the application treats the filename as a normal string, since it ends with .jpg, it successfully passes the list check:
preg_match('/\.(jpg|png)$/i', $filename)
  • At the same time, the blacklist check:
preg_match('/\.php$/i', $filename)
  • Does not match, because .php is not at the end of the string due to the appended .jpg
  • However, when the file is passed to the underlying file system through move_uploaded_file(), the null byte \0 acts as a string terminator
  • As a result, the blacklist check is bypassed and the file is treated as a php file, after i sent the modified request, the server accepted the upload, I then intercepted the GET request to the account page to determine where the uploaded avatar was being served from
None
None
None
None
None
  • By navigating to the uploaded file and appending a parameter to execute the web shell, I was able to retrieve the contents of the target file and solved this advanced lab

Lab-6 Remote code execution via polyglot web shell upload

This lab contains a vulnerable image upload function. Although it checks the contents of the file to verify that it is a genuine image, it is still possible to upload and execute server-side code.

To solve the lab, upload a basic PHP web shell, then use it to exfiltrate the contents of the file /home/carlos/secret. Submit this secret using the button provided in the lab banner.

You can log in to your own account using the following credentials: wiener:peter

  • To bypass this, I created a polyglot file by embedding PHP web shell script into image comment field, then exported the file as parrot.phpusing exiftooltool
None
None
  • The file still looked like an image but contained malicious script
None
  • I uploaded it successfully as my avatar
None
  • Then, I intercepted the GET request of account page where the file was loaded and get the content of target file
None

This was an advanced technique exploiting a file upload vulnerability

Attack Techniques Covered

  • Direct upload of PHP web shells leading to Remote Code Execution
  • Manipulation of the Content-Type header to bypass validation controls
  • Path traversal via filename injection
  • Extension blacklist bypass using .htaccess misconfiguration
  • Null byte injection to bypass file extension filtering
  • Polyglot file creation (image files containing embedded server-side code)

Security Mitigations

  • Perform strict server-side validation of file type, not client-side checks
  • Implement a whitelist approach for allowed file extensions
  • Store uploaded files outside the web root directory
  • Disable execution permissions in upload directories
  • Rename uploaded files with random or unique identifiers
  • Perform content inspection and malware scanning before storing files

These labs improved my understanding of how insecure misconfigurations in file handling can lead to full system compromise. They also demonstrated how attackers can chain multiple simple weaknesses together to achieve high-impact exploits such as Remote Code Execution