# How I abused the file upload function to get a high severity vulnerability in Bug Bounty

> Hello everyone, one of the most interesting functions is file uploading, vulnerabilities in file uploads usually lead you to critical or high-severity, so let’s start with this…

Canonical: https://codelivly.com/how-i-abused-the-file-upload-function-to-get-a-high-severity-vulnerability-in-bu
Last updated: 2025-10-19

| | |
|---|---|
| Category | [Bug Bounty](https://codelivly.com/blog/category/bug-bounty) |
| Author | rocky |
| Published | 2023-02-16 |
| Reading time | 7 min |

Hello everyone, one of the most interesting functions is file uploading, vulnerabilities in file uploads usually lead you to critical or high-severity, so let’s start with this scenario that i faced while bug bunting

Let’s consider our target domain is target.com

While hunting on our target i came across the subdomain edu.target.com the service provided by the program is a teaching platform as there are different types of users like students and teachers who aim to help students to learn tech-related topics like software engineering robotics etc…

## Let’s start our story

I came across the upload function trying to upload an image to analyze how the function works

![Let’s start our story](https://miro.medium.com/max/875/1*h6ZNjZfNiIxE0Cq5w3QQbw.png)

let’s try to upload PHP script

![Let’s start our story](https://miro.medium.com/max/875/1*Hu0sDdOzuR8sCdNJ30XTBQ.png)

i found that server didn’t respond

after some analysis of the application behavior, i figured out that if the request didn’t pass the validation the connection will be closed and the server will not respond to the request

Now let’s try to bypass the validation on the php extension

let’s start by figuring if the application is doing white or black list validation by trying to upload a random extension if it is uploaded successfully that means the application doing a black list if not it means that application doing white list validation for specific extensions

i tried to upload image.omar

![Let’s start our story](https://miro.medium.com/max/875/1*XpjFmPDoI1LWOwoawyeCcw.png)

The file was uploaded successfully which means the application doing black list validation

So i tried to bypass the validation using rce.pHp

![I 6cR7D2Ks VGnb2xP8r g](https://miro.medium.com/max/875/1*I-6cR7D2Ks_VGnb2xP8r-g.png)

It uploaded successfully

https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fgiphy.com%2Fembed%2F3ohhweiVB36rAlqVCE%2Ftwitter%2Fiframe&display_name=Giphy&url=https%3A%2F%2Fmedia.giphy.com%2Fmedia%2F3ohhweiVB36rAlqVCE%2Fgiphy-downsized.gif&image=https%3A%2F%2Fi.giphy.com%2Fmedia%2F3ohhweiVB36rAlqVCE%2Fgiphy.gif&key=a19fcc184b9711e1b4764040d3dc5c07&type=text%2Fhtml&schema=giphy

At this time I was expecting a $5000 bounty to be in my bank account in a few days

https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fgiphy.com%2Fembed%2F9rwJNLBu8FMfixoIxL%2Ftwitter%2Fiframe&display_name=Giphy&url=https%3A%2F%2Fmedia.giphy.com%2Fmedia%2F9rwJNLBu8FMfixoIxL%2Fgiphy-downsized.gif&image=https%3A%2F%2Fi.giphy.com%2Fmedia%2F9rwJNLBu8FMfixoIxL%2Fgiphy.gif&key=a19fcc184b9711e1b4764040d3dc5c07&type=text%2Fhtml&schema=giphy

So let’s request our PHP script to execute phpinfo() function

![Let’s start our story](https://miro.medium.com/max/875/1*sHkaiCsDVuRw9ryhSuj6Yg.png)

The rce.pHp doesn’t executed

https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fgiphy.com%2Fembed%2Fj0qSbeNFuzjhXKFVSP%2Ftwitter%2Fiframe&display_name=Giphy&url=https%3A%2F%2Fmedia.giphy.com%2Fmedia%2Fj0qSbeNFuzjhXKFVSP%2Fgiphy.gif&image=https%3A%2F%2Fi.giphy.com%2Fmedia%2Fj0qSbeNFuzjhXKFVSP%2F200.gif&key=a19fcc184b9711e1b4764040d3dc5c07&type=text%2Fhtml&schema=giphy

so what came to my mind at that time was that it seems like we were able to bypass the black list validation but developers follow a secure design that prevents me from getting RCE

and this can happen in several ways one of them is by adding this flag to the.htaccess file which will make the server not execute PHP files on the image upload directory

> php_flag engine off

In case you don’t know what is.htaccess file

## Note:

> .htaccess file is distributed configuration files provide a way to make server configuration changes on a per-directory basis which i was expecting that developers uses it on image upload directory to prevent the RCE

So according to this, it came to my mind 2 scenarios

## Rewrite Configuration && Path Traversal:

## First Scenario:

**Note: let’s assume that the endpoint of my image is:**

 https://target-domain.com/edu/sub-dir-1/sub-dir-2/sub-dir-3/our-image-here

## 1.1

> Maybe developers uploaded their “.htaccess” file on **sub-dir-1** / directory so according to this the **sub-dir-1** / directory and subdirectories including the directory where i upload my php script can’t run php scripts so we can exploit this misconfiguration by uploading different “.htaccess” file on **sub-dir-1** / **sub-dir-2** / **sub-dir-3** /.htaccess with this configuration which will allow me to change the configuration on sub-dir-3/ which allow me to execute php script

The configuration that will allow running php script

> php_flag engine on

## 1.2

> Okay maybe developers doesn’t make this misconfiguration and already uploaded.htaccess file on my directory **sub-dir-1** / **sub-dir-2** / **sub-dir-3** /.htaccess at this case i will rewrite.htaccess file by uploading filename.htaccess with the previous configuration which will allow me to execute php script

But unfortunately, i remembered that the file name is rewritten so in case we uploaded the.htaccess will be rewritten to /sub-dir-1/sub-dir-2/sub-dir-3/32-random-characters.htaccess which will have no effect on the server configuration

## Second Scenario:

## 2.0

> In the second scenario, we will test it in case the first scenario failed by doing path traversal on filename parameter to get out from the directory that contains the.htaccess file that prevents my php script from executed so my file will be uploaded to another directory, not under the configuration that prevents php scripts from executed [https://target-domain.com/edu/edu/32-random-chars.pHp](https://target-domain.com/edu/edu/32-random-chars.pHp)

As you know that developers take an extension from the filename and put it in the endpoint extension so maybe developers use weak regular expressions that take whatever after the dot and put it in the endpoint extension so we can bypass it by adding a dot (.) then use path traversal payload to upload our script to another directory

![2.0](https://miro.medium.com/max/875/1*cNhL5FdFQ8vb8a9s7Qv5Jw.png)

Didn’t work because as you see it seems that developers implement regular expression validation in the right way (that in case they were using it and not using built-in function like php function pathinfo())

## SQL Injection:

Developers when uploading our images need to connect every image with its user

## So how they can do that?

Correct, using database

As you see the developers save our filename parameter somewhere too

![So how they can do that?](https://miro.medium.com/max/875/1*sRyhUpoBybpIVN6McKp-5w.png)

So the next step to test the filename parameter for SQLI, i used burp suite scanner for that

![So how they can do that?](https://miro.medium.com/max/875/1*vnhC9hIIadQLr8lFGuwDJw.png)

But got nothing

## Public Exploits:

But maybe the developers in the upload function use a library to handle the uploaded image which may be vulnerable

So i started testing some exploits for common libraries like ImageTragic which exploit the ImageMagick library

CVE-2016–3714, CVE-2016–3718, CVE-2016–3715, CVE-2016–3716, CVE-2016–3717

You can find the exploits here [**https://imagetragick.com/**](https://imagetragick.com/)

but didn’t work too so if i can’t get critical vulnerability so let’s try to get high severity vulnerability

## Stored-XSS:

## First Scenario:

Started to test stored XSS by uploading an SVG image containing our XSS payload

![First Scenario:](https://miro.medium.com/max/875/1*cBAnkvGykzlv6B9KSqV7pg.png)

Let’s request our svg XSS payload

![First Scenario:](https://miro.medium.com/max/875/1*sel7aSQexZG1TyT8eci2Iw.png)

But unfortunately the application response forces Content-Type: image/jpeg so we can’t achieve XSS in that way

## Second Scenario:

**in** [**https://edu.target.com/teacher/profile-id**](https://target.com/techer/profile-id)

![Second Scenario:](https://miro.medium.com/max/875/1*B1nzLZDVz3wJRWHsX46Zhw.png)

As i told you previously that the server-side put the extension in the image name

So it seems that the extension in the filename parameter is the best place to inject the XSS payload

`XSS.omar" onmouseover=alert(1)`

![Second Scenario:](https://miro.medium.com/max/875/1*F93gkITFTJuJaabJN6cQYQ.png)

but it seems they doing HTML entity encoding for our payload so we can’t escape the double quote

## Application Level DOS Attack:

The application validates on the client-side on image size and allows only to upload images less than 1 MB

So i tried to get DOS by uploading a large image so i just used an image that size is more than 1 MB for testing if there is a validation on the size on the server side but again the connection closed and the server doesn’t respond which means that there is a validation on image size to prevent such a type of attacks

![Application Level DOS Attack:](https://miro.medium.com/max/875/1*jC6XhDBk8GMDF8HluBY6jA.png)

## Information Disclosure:

but i have noticed that my payload was not changed which means that if i uploaded an image all the meta-data inside the image will not be changed

Okay it’s time to shoot the final bullet

So i uploaded the image which contains GPS location data

you can find it here [https://github.com/ianare/exif-samples/blob/master/jpg/tests/67-0_length_string.jpg](https://github.com/ianare/exif-samples/blob/master/jpg/tests/67-0_length_string.jpg)

After uploading the image to the web application i downloaded it again to check if the Geo-Location data is striped or not

We can do our check using ExifTool to extract the metadata

> ┌──(omar㉿kali)-[~/Downloads] └─$ exiftool /Downloads/exif-test.jpg

![Information Disclosure:](https://miro.medium.com/max/859/1*O6es4J9nit9qt70zWJ8Fpg.png)

As it seems that the web app not stripping the Geo-Location data from the image

https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fgiphy.com%2Fembed%2FckMky4UKiosJa%2Ftwitter%2Fiframe&display_name=Giphy&url=https%3A%2F%2Fmedia.giphy.com%2Fmedia%2FckMky4UKiosJa%2Fgiphy.gif&image=https%3A%2F%2Fi.giphy.com%2Fmedia%2FckMky4UKiosJa%2Fgiphy.gif&key=a19fcc184b9711e1b4764040d3dc5c07&type=text%2Fhtml&schema=giphy

After reporting this, the security team accepted it as P2 due to the fact that most users of the educational platform are underage students and this kind of information disclosure violates their privacy

## Suggested Fix:

1-download the latest version from ImageMagick

2-use stripImage() method to strip this metadata from images

> <?php $imageFilePath = ‘uploaded image’; $img = new imagick(); $img->readImage($imageFilePath); $img->stripImage(); $img->writeImage($imageFilePath); $img->destroy();?>

Hope you enjoyed with the write-up guys

For any questions just reach me on Linkedin or Twitter

Twitter: [@OmarHashem666](https://twitter.com/OmarHashem666)
