Web shell upload via Content-Type restriction bypass
Overview of the Lab
This lab demonstrates a classic file upload vulnerability where Content-Type validation is improperly implemented, allowing an attacker to bypass restrictions and upload a malicious web shell. The application attempts to enforce security by only allowing files with a specific MIME type (image/jpeg), but fails to properly validate the actual file content.
The objective of the lab is to exploit this weakness and achieve remote command execution by uploading a PHP web shell disguised as an image.
Information Disclosure and Initial Clue
During testing, the application revealed an important piece of information through an error message. When attempting to upload a PHP file, the server responded with an error indicating that the file type application/x-php was not allowed, and that only image/jpeg files were accepted.
This behavior is a form of information disclosure, as it exposes the exact validation mechanism used by the server. Instead of performing deep inspection of the file content, the server is relying on the Content-Type header provided in the HTTP request.
This immediately suggests that the validation is client-controlled and therefore bypassable.
Understanding the Content-Type Bypass
When uploading files through HTTP, the request includes a Content-Type header that indicates the type of file being uploaded. However, this header is not inherently trustworthy because it can be modified by the client.
In this lab, the application checks whether the uploaded file has a Content-Type of image/jpeg, but does not verify whether the file is actually a valid image. This creates an opportunity to upload arbitrary files by simply changing the header.
The attack works by taking a malicious PHP file and modifying the request so that:
-
The filename remains
shell.php -
The Content-Type is changed to
image/jpeg
Because the server only checks the header, the upload is accepted even though the file is not an image.
The Web Shell Payload
The uploaded file contains a simple PHP web shell:
<?php
system($_GET['cmd']);
?>
This payload allows the attacker to execute system commands by passing them as a parameter in the URL. For example:
shell.php?cmd=whoami
When accessed, the server executes the system() function, which runs the provided command on the underlying operating system and returns the output.
Achieving Remote Command Execution
Once the file is successfully uploaded, it is placed in a web-accessible directory. When the attacker navigates to the uploaded file via the browser, the server interprets it as PHP code rather than treating it as a static file.
At this point, the attacker has achieved remote code execution, as they can now send arbitrary commands to the server through HTTP requests.
This confirms that:
- The file upload restriction was bypassed
- The server executes uploaded PHP files
- Arbitrary OS-level commands can be executed
Even though the application attempted to enforce file type restrictions, the reliance on the Content-Type header made the defense ineffective.
Example image of how i pulled the content of a file called "secret" within the carlos user directory. (Lab Objective)
Why This Vulnerability Exists
The root cause of this vulnerability is improper validation of uploaded files. The application trusts a client-supplied header instead of verifying the actual content of the file.
This leads to multiple weaknesses:
- Content-Type headers can be easily spoofed
- File extensions are not enforced or validated
- File contents are not inspected
- Uploaded files are stored in executable locations
Because of these issues, the server cannot distinguish between a legitimate image and a malicious script.
Security Impact
This vulnerability is critical because it allows attackers to gain full control over the server. With a web shell in place, an attacker can:
- Execute system commands
- Read and modify files
- Access sensitive configuration data
- Establish persistence
- Pivot to other systems
In real-world scenarios, this type of vulnerability is often used as an initial foothold in larger attacks.
Mitigation Strategies
To prevent this type of attack, multiple layers of validation must be implemented:
- Validate file types using server-side checks, not client headers
- Inspect file contents (magic bytes) to confirm format
- Restrict allowed file extensions strictly
- Store uploaded files outside the web root
- Disable script execution in upload directories
- Rename uploaded files to random, non-executable names
Relying solely on Content-Type headers is insufficient and should never be used as a security control.

Comments