8 min read
June 27, 2020

HackTheBox Writeup: PlayerTwo

HackTheBox Writeup: PlayerTwo

PlayerTwo was an insane rated Linux box that was a hell of a journey. I debated about doing this writeup because I got the root flag in an unintended way but hey, it's still a win! First you had to get the correct vhost name in order to find a Twirp installation. Interacting with that yielded some creds for a login page which promptly stopped you with a 2FA prompt. A bit of guesswork with an API got some backup codes that gave access to a website. A PDF file was hosted on the site that detailed firmware architecture with a download link to the firmware, along with a link to upload and verify firmware. The firmware was downloaded, edited and exploited to gain a shell. Once on the system, Mosquitto was used to read a SSH private key and a stable SSH shell was gained. From here, the intended route was binary exploitation but I'm horrible at that. I added playertwo.htb to my /etc/hosts file and started scoping things out.


nmap scan:

Port 80 showed an error message:

Port 8545 wasn't much help either:

I started enumerating more and got nowhere fast, getting stuck for a little while. Finally while looking through notes, I looked closer at the error message on port 80 and saw that it said 'Please contact MrR3boot@player2.htb'. I added player2.htb to /etc/hosts and got a better result:

The rest of the page talks about how Player was compromised without much else. Time to start gobusting:

I proceeded to gobust each of those directories searching for the same extensions and got nowhere. After quite some time, I got a nudge to look for .proto files:

I downloaded the file and checked it out:

I never heard of Twirp or .proto files and had to do a lot of googling. It turns out that Twirp is "a framework for service-to-service communication emphasizing simplicity and minimalism." The proto file is written in Go which I know next to nothing about - yay. Port 8545 had given the Twirp error so I started there. It took a lot of time, experimentation and reading two articles on Twirp's docs over and over again but I finally got a curl command working that gave me creds of some kind:

I played around with this for a while getting ever changing creds for 0xdf, mprox and jkr. At some point I noticed that sending the number 0 resulted in the password staying the same while the name changed:

Ok, where do these creds go?? A short while later, I checked the source code of player2.htb and saw this:

Let's check it out:

I used the generated creds above then got hit with 2FA:

Time for more enumeration. Gobuster turned up some things:

I was stuck here for a long time, gobusting everything, fuzzing for potential php parameters and all kinds of failure. I don't even remember how I came across it but while flailing at the API, I got an error message:

I threw the request to Burp and changed it to a POST request:

Ok, a change in error messages is good - that means something is right. The error message is in JSON format so I tried POSTing the cookie as the session value and got a different error message, "Missing parameters". Cue all kinds of flailing on my end before I took a breath and thought about TOTP and what it stood for - Time-based One Time Password. If you've ever used Google Authenticator, they give you backup codes to use so I started playing around looking for that:

Some more flailing and I eventually got the syntax right:

Entering that finally let me in to the website whose animations promptly bogged down my VM:

Initial Foothold

I browsed around the site and found a link to a PDF about their firmware:

I downloaded the tar file and extracted it:

strings is a handy command to run on binaries to show what may be stored as plain text inside:

I don't know much about bin ex and needed a nudge that the 'stty raw -echo min 0 time 0' was the thing to focus on. I did know that the 'system' call is important and googling around taught me that stty line reads user input so that started making some sense. Bin ex is not my strength but I do know how to use a hexeditor so gave that a try. The idea was to replace the 'stty' line called by system with my own command. In order to not completely throw off the binary, the length of my command needs to be the same. Let's count the characters in the 'stty' line:

So we need to match the length of 28 characters. I decided to start with ping and came up with a padded command that matched the length:

I opened up Protobs.in in hexedit and found the 'stty' line:

Then I headed to CyberChef to convert my ping command to hex:

I changed the hex and saved:

I tarred up the edited firmware and uploaded:

I had tcpdump listening for icmp requests and got a ping:


So the next step was going for a shell. I created a short reverse shell script:

I was able to get PlayerTwo to download a shell script from me pretty easily but it took a little while for me to realize that just because it grabbed the file from me successfully didn't mean it was able to write to whatever location it was trying by default. Here's the hex to download my script and write it to /tmp/e:

Hex to make the script executable and run it:

With a netcat listener, I finally got a shell:

User Pivot

I went down a lot of rabbitholes looking at mysql and whatnot before running linpeas. It flagged mosquitto.conf:

ps -aux shows that it is running:

I had never heard of Mosquitto and only vaguely heard of MQTT. A bit of googling and I found an excellent article describing it and how to hack it. I copied his script from section 6:

I proceeded to run it on PlayerTwo and got a ton of stuff flying by before I spied a private key:

Linpeas also flagged a couple of users from /etc/passwd:

I copied the key, saved it and now had SSH access as observer:

User flag:

Privilege Escalation

There's a PDF in observer's home dir:

I downloaded and viewed it:

I poked around the system some more and found the binary for the configuration utility mentioned in the PDF:

Seeing the libc included with the binary gave me a sinking feeling - binary exploitation that I don't really know how to do.

The Unintended Win

I thought I might have to be satisfied with just the user flag when a HTB buddy gave me a cryptic clue to use what I had already done. I had to think it over for a bit before settling on the MQTT thing. What if I could use that to read a file other than observer's id_rsa? I backed up the private key and was surprised I was able to create a symlink to the root flag:

I re-ran the MQTT script and where I saw the id_rsa file earlier, now sat the root flag:

I look forward to watching how Ippsec does the intended route :D.