Obscurity is a Medium Linux box created by clubby789. It was released on November 30th, 2019 and retired on May 9th, 2020. The users rated the difficulty 4.8/10 and gave an overall score of 4/5 to the box.
TL;DR
We discover the Python source code of the custom web server in a hidden folder of the website it hosts. After analysis, we find out that the server is vulnerable to RCE through the URI. We exploit it to get a reverse shell as www-data
. We find another Python script in robert
home folder used to encrypt/decrypt files. As we have as well access to a pair of plain/cipher-text, we retrieve the key used with a dictionary attack by re-using the decryption function. We can use the key to decrypt another file that contains robert
password. We can then log in through SSH and get the user flag. robert
can run yet another Python script as root
. This time it is a custom SSH server that copies the hashes of /etc/shadow
in a temp file that is world-readable and deletes it after usage. A bash one-liner is used to monitor that and leak the root
hash that we crack to get the root
flag.
Reconnaissance & Enumeration
Open Ports
An NMAP scan shows the following (partial) output:
$ sudo nmap -sS -sV -p- 10.10.10.168
PORT | STATE | SERVICE | VERSION |
---|---|---|---|
22/tcp | open | ssh | OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0) |
8080/tcp | open | http-proxy | BadHTTPServer |
We discover:
- the usual OpenSSH v7.6p1 server,
- a BadHTTPServer on port 8080. This could be a custom web server or coming from some GitHub repo like this one.
Web discovery
We have access to a static website on port 8080 that seems to offer a “secure” hosting based on custom tools:
There is a message at the bottom that leaks the filename of the web server source code and that is apparently stored in a secret folder:
Knowing this, we can better target our folder discovery with wfuzz
:
And the folder found is develop
. We download the source code for analysis:
http://10.10.10.168:8080/FUZZ
always returns an error code 404 even if the folder exists. Error code 403 is not used.
Gaining Access
The source code is a little more than 150 lines long. We start by checking if some dangerous functions like eval
, exec
, os.system
, os.popen
or subprocess.call
are used.
We find an exec
call on line 139:
The URI is not sanitized before being used as part of the info
string and being executed afterward. This leads to Remote Code Execution (RCE). If we set a URI like ';os.system('ping -c3 10.10.14.94');x='
, the following will be executed:
Let’s try it out:
Good! Now let’s replace our ping
with a reverse shell. The URL becomes:
And we get a shell as www-data
.
Local Reconnaissance & Enumeration
We find some interesting files that we can read in robert
home folder. The SuperSecureCrypt.py
script is used to encrypt/decrypt files. We have as well a plaintext file check.txt
that contains:
And its encrypted version out.txt
. Another encrypted file passwordreminder.txt
may contain robert
password.
Moreover, a folder called BetterSSH
contains the source code of a custom SSH server.
We retrieve all those files locally for analysis.
Privilege Escalation
User pivoting
Let’s try to decrypt passwordreminder.txt
. The encryption algorithm is quite simple. It takes the encryption key and the plaintext as arguments, loops through the characters of the plaintext and adds the value of the key characters modulo 255 to obtain the ciphertext:
We can re-use the given encryption or decryption algorithm and brute-force the key, character by character, as we have the plaintext and ciphertext. The following script retrieves the encryption key and decrypts passwordreminder.txt
:
The key used is alexandrovich
and the decrypted content is: SecThruObsFTW
which is the password of robert
. We can now SSH in and get the user flag:
e449************************a2d7
Root escalation
robert
is a sudoer and can run a Python script as root
without password:
This is the custom SSH server that we saw previously. If we run it, we are asked for credentials and then it tries to open a random file in /tmp/SSH/
. It throws an error as this folder does not exist:
Let’s create this folder and try again:
Ok, we get a shell. The random folder was deleted. Let’s check in the source code what is really going behind the scene.
Once we enter our credentials, the script reads /etc/shadow
and copies the user hashes to a random file in /tmp/SSH
. Which means that theroot
hash is written in a file that is world-readable! Our password is then hashed and compared to the existing one…in memory! The random temporary file is not used for the verification and could be removed:
The goal is to read the content of the random temporary file to retrieve root
hash. This can be achieved with the following one-liner from a second shell:
It waits for the /tmp/SSH
folder to contain a file, outputs its content then quits the loop:
As expected, we get root
hash that we can crack with john
and the usual wordlist:
The password is: mercedes
. As root
login is not permitted, we can simply use su
:
Conclusion
We saw some good examples of security through obscurity and why this must be avoided, whatever brilliant idea one can have!
Here are some takeaways of this box:
- open-source your code,
- do not code your own tools when better open-source alternatives exist,
- do code QA and clean dead code.
Resources
[1] Bad-Http-Server
https://github.com/raintank/bad-http-server