---
description: PRACTICE ! PRACTICE ! PRACTICE !
---

# File Upload Attacks

### Remote code exec via web shell upload

> Upload an image and proxy it through burpsuite, Note if the image's preview is shown on the page. Go to the HTTP history, under MIME type checkbox images so that it will show all the images returned in the history tab.

> Notice that the image which we uploaded was fetched by a GET request, send that request to repeater. Meanwhile, create a `exploit.php` file which will basically fetch the contents of the target file.

> Now upload this `exploit.php` file, and it returns a status code 200 which means our file was uploaded successfully uploaded. Now how do we access our `exploit.php` ?

> Simply, go the repeater tab and tamper the header by inserting our `exploit.php` and send the request and the target's content will be displayed in the response tab.

### Obfuscating file extensions

#### 1

To bypass `.php`, we'll have to use lesser known extensions which resemble the same such as

1. .php5
2. .shtml
3. .pHp

#### 2

For a medium level secured application, we must try tampering the extensions from `.php` to `.jpg | .jpeg | .png` and upload it.

Keep your burp ready, intercept the request and change it to `.php` and forward the request, your backdoor will be uploaded.

Interact with your backdoor by triggering it in the location where it is uploaded in the web page.

#### 3

For an advanced level secured application, repeat the same but while modifying it in the burp proxy add `.jpeg` to it in the end. Example => `filename: shell.php.jpeg`

We can even try by URL encoding the dots => `exploit%2Ephp`.

URL-encoded null byte characters before the file extension. If validation is written in a high-level language like PHP or Java, but the server processes the file using lower-level functions in C/C++, for example, this can cause discrepancies in what is treated as the end of the filename: `exploit.asp;.jpg` or `exploit.asp%00.jpg` or `exploit.php#.jpg`

### Web shell upload via path traversal

> Asusual upload an image and proxy it through burpsuite, observe the image which we uploaded was fetched by a GET request. Send that request to the repeater tab. Meanwhile create a `exploit.php` file which fetches the target's contents.

> Now when we try to upload the `exploit.php` file, it'll not restrict us from uploading the file. So now it's easy we got a RCE, our exploit.php file is uploaded and now we can trigger it by changing the GET request in the repeater tab.

> But when we do that, we notice our `exploit.php` code is returned as plain text in the response tab, Why is this happening ?

> Let's investigate it using our POST form {exploit.php's}, Everything is set so it should work fine but it's not. So if we take a closer look at the `Content-Dispostion` header, our filename is `exploit.php`, when we try to tamper the file name to a directory-traversal sequence : `Content-Disposition: form-data; name="avatar"; filename="../exploit.php`

> Now sending this request we recieve a response saying the file has been uploaded, which suggests that the server is `stripping` the directory traversal sequence from the `filename`.

> Now a bit more advanced way is to encode characters in our payload that is, instead of `/` we can use `%2f`. Now if we send the request, we can notice the response `/files/avatars/../exploit.php has been uploaded`, which means the server decoded our `%2f`.

> Now that we know our payload worked and there is a directory traversal method to access the target's content, let's trigger but before doing that. Observe the GET request of our `%2fexploit.php` in the HTTP history.

> So what is happening in the backend ? This indicates that the file was uploaded to a higher directory in the filesystem hierarchy (`/files`), and subsequently executed by the server. Note that this means you can also request this file using `GET /files/exploit.php`.

### Web shell via Content-Type restriction bypass

Modern server config => compares it with a pre-configured mapping between extensions and MIME type.

NOTE ==> Burpsuite's Content-Type response header may provide some clues.

`<?php echo system($_GET['whoami']);?>`

While submitting HTML forms, the request goes and hits the server in a POST form with the `Content-Type : application/x-www-form-url-encoded`.

The same way while submitting or uploading an image, the request goes and hit the server in a POST form with the `Content-Type : image/jpeg`. So, it's very much important to observe the Content-Type, while intercepting the requests.

> Upload an image and proxy it through burpsuite, Notice the image was fetched using a GET request. Send it to the repeater, Meanwhile upload the `exploit.php` file which will return our target's contents.

> But here when we try to upload our `.php` file, the response indicates that we aren't allowed to upload the file and hence the server is configured to the MIME type `image/jpeg` or `image/png`. So whenever we encounter an error where it says us to not upload some particular file, it's something wrong with the `Content-Type`.

> To investigate that, we'll have to go to the HTTP history and find the POST request which has our `exploit.php` because our uploaded image or file will go and hit the server in a POST form. Send it to the repeater tab.

> In the repeater tab, change the specified `Content-Type` to `image/jpeg`. Send the request and observe our exploit.php was uploaded successfully, we just tampered the Content-type according to the MIME type which was configured by the server.

> Now that we know our `exploit.php` has been uploaded, to retrieve the contents of the target. Switch to the other repeater tab {which was GET request}, and tamper the header by inserting our `exploit.php`.

### Over-riding Apache's Configuration

For an example, before an apache server will execute PHP files requested by a client. Dev's should add the following directives to thier `/etc/apache2/apache2.conf` file.

> LoadModule php\_module /usr/lib/apache2/modules/libphp.so AddType application/x-httpd-php .php

Apache servers generally have `.htaccess` file, which will load directory-specific configurations.

Even when our file extension is `blacklisted`, we can still manage to bypass the server by mapping an arbitrary custom file extension to an executable MIME type.

> Upload an image and proxy it through burpsuite, notice our image was fetched using a GET request. Send it to the repeater tab.

> Meanwhile create `exploit.php` which extracts the contents of the target, upload that as your image and we'll get an error saying we can't upload `.php` files onto the server.

> Let's investigate it using our POST form in the HTTP history, In the response we can observe the headers revealing it's an `apache server`. Send it to the repeater tab.

> Modifying the POST form : `filename` parameter to `.htaccess` `Content-Type` header to `text/plain` Our `php` payload to `AddType application/x-httpd-php .133t`

> `.133t` is an arbitrary extension to the executable MIME type `application/x-httpd-php`. As the server uses the `mod_php` module, it knows how to handle this.

> Send the request and we get a `200` status code, Going back to our `.php` exploit which din't work. Change the value of the filename parameter from `exploit.php` to `exploit.133t`, Send the request and we get a response saying it has been uploaded.

> The final step is to trigger our `.php` exploit, which can be done by changing our `image's` filename into `exploit.133t`. Thanks to the  `.htaccess` file, the `.133t` file was executed as if it was a `.php` file.

### Exiftool - Polygot shell

Nowadays modern servers doesn't check for the `extensions` and the `Content-Type` specified in the request.

In the case of image upload functionality, the server may check certain intrinsic properties of an image such as dimensions, where our `exploit.php` is just a file and files don't have any dimensions.

#### So now do we have to insert our payload inside an image ? How do we do that ?

This can be achieved by using the `exiftool`.

```
exiftool -Comment="<?php echo 'START ' . <PAYLOAD> . ' END'; ?>" jason.jpg -o polyglot.php
```

Upload the polygot file, and backend approves our `php` file. Now tamper the GET request and we'll trigger our payload
