Game with content-disposition

Hi there,

I’d like to show you a trick with Content-disposition that you can use to change the file name. The main reason for the mini-research was — “is it possible to upload exe or bat or some other executable file on the server, and download them as .exe, .bat extension when server always print as content-type image/jpeg”. And the answer is — yes :)

Of course, sometimes we can use CRLF charsets to change filename from the response, but I have found another way to do it.

Server configuration

I used on server-side Ubuntu (http://192.168.204.136), Apache 2.4.18 and PHP 7.0.32, on client-side Firefox 63.0.3, Chrome 71.0.3578 and IE 11.875.

On the server, I create 2 files,the first file is to upload and save file on the disk, the second file is to download the file from the server.

  1. upload.phtml

As you can see, in PHP code I used pathinfo($file) function to get an extension of a file which needs to upload, and if a file doesn’t have a ‘jpg’ extension it will not be uploaded.

upload image to the server

2. download.php

avatar.jpg on the server

So, using “upload.phtml” web page you can upload images to the server and using download.php you can easily download a file from the server (first 2 php code lines in “download.php” file may be other, the main idea is to find and read an image file from a directory and send it to a client).

Game with content-disposition

Some may already have noticed, that file was saved with a name which we assigned during uploading.

Main

I tried to upload many files to the server with different chars that are not usually used in filenames.

And some interesting thing I have found when I uploaded a file with ; char in the name.

The file was successfully uploaded and saved and we could get it using “download.php” page.

Here is a file download request in Burp

Nothing unusual, but, if we will try to download the file by browser we will see next beautiful things.

Filename in Firefox
Google Chrome

Oh, shit, on my laptop I got this with IE explorer

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

Аfter that I ran IExplorer on the virtual machine.

IE

Let’s upload exe file content with “evil.exe;avatar.jpg” file name and see what will happen.

upload binary data to the server

Here is the binary file on the server

So, let’s try to download “evil.exe;avatar.jpg” file from the server.

Click save

Oh, again IE :(((

And only Firefox prevented and inserted .jpg extension after file saving.

FF
Click save.

Conclusion

For browsers, ; chars in a filename in content-disposition header is splitting char. To fix it of course

  1. in the upload time you need to check the file content
  2. from server-side, you must write filename in quotation marks.

For example, instead of

header(“Content-disposition: attachment; filename=$fname”);

must to write

header(“Content-disposition: attachment; filename=\”$fname\””);

— — — — — — — — — — — — — — — — -

Vahagn Vardanyan https://twitter.com/vah_13