9 min read
January 18, 2020

HackTheBox Writeup: Player

Player was a hard rated machine and is probably my favorite machine thus far. This box was all about enumeration. Other than one thing that was a bit of a reach and kinda CTF-y, it was a very realistic scenario. JWT tokens, an ffmpeg exploit that made me feel like Mr.Robot, an OpenSSH vulnerability, and an exploit in Codiad were needed to get a shell then finally exploiting a lazily written script to gain root. It was a long journey with many steps but was a ton of fun and very satisfying.

Enumeration

nmap scan:

As with all HTB machines with web services, I added player.htb to my /etc/hosts file and checked out the web page:

Okay, time to fire up Gobuster:

http://player.htb/launcher shows a countdown:

Submitting an email didn't appear to do anything but Burp caught a cookie that appears to be a JWT as well as a mysterious PHP file:

I copied the cookie and pasted it in at jwt.io:

Let's take a look at the access code. It is recognized as a SHA-1 hash:

Running it through John and rockyou.txt reveals the code is 'welcome':

This ended up not coming into play but not everything you enumerate does.

At any rate, I got stuck here for a bit. I continued trying to enumerate by running Gobuster on player.htb/launcher and looking at javascript files loaded by the page but came up with nothing. I went to the forums and saw the creator mentioned vhosts so I grabbed a tool to enumerate vhosts and ran it:

So now we've got 2 additional vhosts to check out: dev.player.htb and staging.player.htb.

I checked out Dev first because you can often find goodies left by developers. Dev gives a login page which we have no creds for:

Gobuster shows some interesting things:

LICENSE.txt shows they are running something called Codiad:

A quick google search and I find out it's a web based IDE:

Searchsploit shows some vulnerabilities but they need creds:

Google also came up with an exploit that needs creds so I bookmarked that and kept enumerating with a Nikto scan:

There wasn't anything interesting in composer.json but let's look at .gitignore:

I couldn't view config.php and the README files were useless. The *.swp raised a minor eyebrow so I filed that away in the back of my head and moved on to Staging.

'Product Updates' had a static picture that refreshed every 5 seconds:

The 'Contact Core Team' link is where something interesting happened:

Submitting an email and message flashed an error message on the screen for a fraction of a second before redirecting to 501.php:

I turned on the intercept in Burp to 'freeze' the error message and saw this:

Someone is a Family Guy fan!

A closer look at the error

With the folder structure of /var/www/backup/service_config and /var/www/staging/fix.php I thought maybe I missed a vhost so I added backup.player.htb to /etc/hosts but that was a rabbithole. player.htb/backup also didn't work. I got stuck here for quite a while before checking the forums for a hint. It seems a lot of folks got stuck here and hints involved backup files and someone mentioned vim. Since I'm a heathen who prefers nano, a googling I went and learned that vim stores backup files as *.ext~. A vim backup file of readme.txt would be readme.txt~. I've seen those files around a ton but just never thought about it. I also learned that vim creates swap files with a .swp extension. Remember the .swp from the .gitignore file? I believe that and the /var/www/backup folder were the small CTF-y hints for the next step.

I started trying to hit up various files with a ~ tacked on and struck gold with that mysterious php file found early on:

I'm not a developer but the code is easily readable enough to see that it's looking for a cookie named 'access' with an access code of 0E76658526655756207688271159624026011393 to forward the user to this 7F2xxxxxxxxxxxxx location.

At first I tried to take the key and create my own JWT at jwt.io but I couldn't get that to work so I put on my big boy pants and bumbled my way through editing the php file to spit out a JWT:

Running this gave me a JWT:

I went to player.htb/launcher/dee8dc8a47256c64630d803a4c40786c.php, intercepted with Burp and replaced the JWT with the one I generated. I did something right as I was presented with an upload page:

Initial Shell

Naturally the first thing I tried do upload was a php reverse shell. I got this screen when it completed:

However, clicking on the 'Buffed Media' link gave me this:

I tried uploading various things and kept getting the 'not found' error. I spent some time trying to see if there was a link between the token in the upload complete url and the filename for the avi file - nope. Finally I googled 'image upload php exploit kali' and the very first result has a section saying:

Scenario 7 Allowing video uploads?Due to a SSRF vulnerability in ffmpeg library, it is possible to create a video file that when uploaded to any application that supports video files (i.e Youtube, vk, Flicker etc) you will be able to read files from that server when you try to watch the video!Command: ffmpeg -i video.avi{m3u} video.mp4 - https://github.com/neex/ffmpeg-avi-m3u-xbin/

So I googled for 'ffmpeg ssrf exploit' and found this. About halfway down is a post from 'neex' with a script 'gen_avi.py' which I downloaded and ran:

I uploaded output.avi and this time the link to 'buffed media' worked and let me download the file:

I played the file in VLC and my jaw dropped when I saw this:

How freaking cool is that?!?!?! This is one of those vulnerabilities you read about and are like 'hmm, interesting' but then your mind is blown when you actually see it.

After I picked my jaw off the ground, I continued enumerating. I ran into a lot of useless files as well as blank videos because the video converter didn't have permissions to view certain files.

Remember that error message from the 'contact' page on staging.player.htb? Here's where it became important:

I uploaded the resulting file and got some creds for telegen:

These creds worked for the ssh server on port 6686 but was severely limited:

I didn't spend too much time trying to escape the limited shell because I knew from a previous pentest engagement that this version of OpenSSH has multiple vulnerabilities. After looking over possible exploits, this one stood out. A lot of organizations leave X11 forwarding on in their ssh configs even when it's not being used. At any rate, I copied the PoC code from that exploit, pasted it into xauth on my machine and tried it out:

Let's see if it works:

Looks like it works so I grabbed the user flag:

I then spent time trying to view various files before finding creds in /var/www/staging/fix.php which was referenced in that error message caught by Burp:

The creds for peter let me login to dev.player.htb:

Remember the exploit for Codiad that I found via googling that needed creds? I immediately got it from here and tried it out:

With 2 netcat listeners running per the exploit, a reverse shell was gained:

Privilege Escalation

Looking around the system didn't immediately show anything that interesting so I uploaded pspy64 and ran it to see what was happening on the system. A few things jumped out to me:

I looked around for 'CRON' and 'cron' but came up with nothing so checked out buff.php next:

My PHP knowledge is pretty much nil but the 'include' statement pointing to a file in /var/www/html caught my eye. Let's check it out:

It looks like buff.php includes dee8dc8a47256c64630d803a4c40786g.php so it can make use of the $conn function. Let's double check permissions:

A process being run as root which includes a php file with weak permissions? Shame on the admin. Since www-data has write access on /var/www/html/launcher and this dee8dc8a47256c64630d803a4c40786g.php file, I renamed dee8dc8a47256c64630d803a4c40786g.php to dee8dc8a47256c64630d803a4c40786g.php.bak, copied its contents to dee8dc8a47256c64630d803a4c40786g.php on my machine and changed the $conn function as below:

I then started a Python simple http server and used wget on Player to download my edited file to /var/www/html/launcher. With a netcat listener, a root shell was gained in short order:

Finally, the root flag: