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.
- 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.

2. download.php


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.


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

Аfter that I ran IExplorer on the virtual machine.

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

Here is the binary file on the server

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


Oh, again IE :(((

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


Conclusion
For browsers, ; chars in a filename in content-disposition header is splitting char. To fix it of course
- in the upload time you need to check the file content
- 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