Obscurity just retired today. I had lots of fun solving it, especially because I got to pwn so many custom applications. Its IP address is ‘10.10.10.168’ and I added it to ‘/etc/hosts’ as ‘obscurity.htb’. Without further ado, let’s jump right in!
Scanning & SuperSecureServer.py
A light nmap scan was enough to get me started:
Port 80 was closed, but port 8080 was opened and hosted something that identified itself as BadHTTPServer. I opened it in a browser and got the following page:
The motto (“Security Through Obscurity”) only made me more curious. I began reading the content of the page and stumbled upon the following entry:
After seeing the words ‘secret development directory’, I let dirb run with a lot of wordlists, but I got no results. Then, I remembered that the site uses a custom server. I tried accessing the /css direcotry, which I knew existed because I inspected the source of the front page, and got a 404 error. This made me believe that the server will return a 404 error unless the requested URI is a FILE. Luckily for me, I knew the ‘SuperSecureServer.py’ would be located in that direcotry, so I used wfuzz to find it:
The server source code was located at /develop/SuperSecureServer.py. You can find its source code below:
Exploiting SuperSecureServer.py
If you didn’t already spot the vulnerability, it’s probably because the source is a little long. Let me help you:
The server is running exec() on a string containing the ‘path’ variable, which we control. As the variable is not sanitized at all, I used shellgenerator.github.io and crafted the following payload:
In order to get my reverse shell, I urlencoded that payload using an online tool and then appended it to ‘obscurity.htb:8080/’ (I accessed the resulting URL in a browser). This got me a reverse shell:
One interesting thing that I discovered during enumeration was that there was a user named robert and I was allowed to read his home directory:
passwordreminder.txt looked promising, but when I transferred it to my home machine I discovered it only contained non-printable ASCII characters. This made me believe it was encrypted using SuperSecureCrypt.py, which I transferred along all the other files in that directory. The source of SuperSecureCrypt.py is a little bit long, so I’ll only paste the ‘encrypt’ function below, which was presumably used to encrypt the password:
Exploiting SuperSecureCrypt.py
You don’t need to be a cryptography expert in order to see that the key could be calclated given we have a sample input and output. Luckily for us, the contents of check.txt give us that two files:
I made the following python script to calculate the key used to encrypt check.txt:
The output is the key repeated some times:
The key used to encrypt the file was ‘alexandrovich’. I used it to decrypt passwordreminder.txt:
The password for robert was ‘SecThruObsFTW’. I used ssh to connect to robert’s account and get the user proof. It starts with ‘e4’ 😉
Exloiting BetterSSH
After I submitted the user proof, I started enumersting the machine again. One directory in particular caught my attention: BetterSSH. However, I knew it wouldn’t help me achieve root if it runs with the same permission as robert, so I started searching for ways I could make it run as root. Fortunately, the user robert can run BetterSSH with sudo without providing a password:
The sourcecode of BetterSSH.py can be found below:
For some reason, the binary created a file in the /tmp/SSH/ directory and printed all the password hashes and salts to that file. However, the file would get deleted in a little over 0.1s, so I couldn’t read it manually. However, I was able to read it with a little bash witchery and some creativity:
Have two SSH sessions as robert
In one session, have a bash one-liner that tries to read all the files in /tmp/SSH/ continously. It will only print the file’s contents; all errors should be redirected to /dev/null
In the other session, try to log in as a valid user, say robert. Enter a wrong password only after you started the first session.
My bash one-liner looked like this:
On the other terminal, I ran the following commands:
The following output was printed a lot of times in the first terminal:
Root’s /etc/shadow entry can be obtained by joining the lines below root (until ‘robert’) with ‘:’. The /etc/passwd file is readable by everyone, so I used john to crack root’s password:
The password for root was ‘mercedes’. Root SSH login was disabled for obvious reasons (we don’t want people to suceed in bruteforcing root’s SSH password and get all the proofs without them solving the box), so I used ‘su’ while logged in as robert to get root: