/var/log $ cat "Hack The Box - Fortune Walkthrough"
2019-08-03 | hackthebox ctf
Machine Info
tl;dr
- Find and use RCE on port 80 website.
- Get the Intermediate CA private key and create a client certificate for accessing HTTPS.
- Get a SSH key from the HTTPS website.
- SSH into box and re-scan the box to discover a NFS share.
- Mount the share to get user flag and hint for root password.
- Reverse engineer how pgAdmin 4 v3.4 decrypts passwords.
- Decrypt the database password to gain root access.
Tools used: nmap
, burp
, python
, openssl
, mount
, pgadmin4
, sqlite
Initial Recon
|
|
From the nmap
scan report we can see three TCP services running: SSH, HTTP and HTTPS. From the HTTP header we can see that the box is presumably running OpenBSD where httpd
is the OpenBSD web server.
Initial Enumeration
SSH and HTTPS
As normally SSH is not the way forward in the first place I skipped having a look at it.
When trying to access https://10.10.10.127
after accepting the self-signed certificate we get a SSL_ERROR_HANDSHAKE_FAILURE_ALERT
:
Accessing the URL with curl
gives us some more details what happened:
Checking against the TLSv1.2 specification in The Transport Layer Security (TLS) Protocol Version 1.2 - 7.4 Handshake Protocol wee see that the server requests a client certificate from us. As we do not have one we cannot access HTTPS for now.
HTTP
Browsing to http://10.10.127
we get a very simple site where we can select a fortune database and when hitting submit outputs a random fortune for us:
From the code of the page or using burp
we can see what is posted to the /select
endpoint:
Using burp
’s intruder module in sniper mode with the All-attack.txt word-list from wfuzz
outputs something quite useful:
Using the repeater function to confirm that we do have RCE here:
Own User
Getting a Shell (sort of)
Despite the box having a few tools which would allow a reverse shell I could not get one working. So I wrote a little Python script which uses the RCE to have a pseudo shell:
|
|
Accessing HTTPS
Checking httpd.conf found in /etc/httpd.conf
we see which CA certificate is used for the client authentication:
Searching through the box we also can find a private key in /home/bob/ca/intermediate/private/intermediate.key.pem
:
Judging based on the file path this seems to be an intermediate CA private key. After copying both the private key and the CA certificate from /etc/ssl/ca-chain.crt
over to our own machine and using this guide we can confirm that the key we found was used so sign the CA certificate used for the TLS client authentication:
Now we create our own client certificate and convert it:
After importing our newly created PKCS12 certificate into our browser we are now able to access HTTPS:
Hitting ‘generate’ we are presented with a SSH key pair:
SSH and more Services
After copy-pasting the private key from the website we try to ssh into the box. As the page does not give us any clue which username to use we have to figure it out. From /etc/passwd
we know the users ‘bob’, ‘charlie’ and ’nfsuser’. Trying them we find that ’nfsuser’ works but the shell is not working in any way:
Running nmap
again while connected to SSH we find some more services now:
|
|
Having a look what NFS shares are available and mounting it we can grab the user flag found in /home/charlie
:
Own root
Full SSH Access
To get a fully interactive SSH session we add ourself to /home/charlie/.ssh/authorized_keys
using either the key pair which was generated on the website or with a new pair. Now we have SSH access as ‘charlie’:
In /home/charlie
we find the file mbox
which gives us a very helpful hint:
Obtaining the ‘dba’ Password
From the pgAdmin 4 3.4 documentation we can see that the configuration parameters are stored in a file named config_local.py
. Searching for it and having a look in its contents we can determine the path to the SQLite database where pgAdmin stores credentials:
Using the SQLite client installed on the box we can get the encrypted password from the table ‘server’:
Decrypting the Password and getting the Flag
After installing and running pgAdmin 4 version 3.4 in a local test environment we find that the password crypto part is handled in the module crypto.py
. As it turns out all we need to decrypt the ‘dba’ password is the hashed user password (no need to know it what it is) from the user who did the database setup.
Again we use the SQLite to get the user password hashes from the table ‘user’:
Next step is to modify crypto.py
so that it decrypts the password for us:
|
|
The decryption using the hash of ‘charlie’ does not look promising whereas the version with bob’s hash does:
Trying to su
with ‘R3us3-0f-a-P4ssw0rdl1k3th1s?_B4D.ID3A!’ as root password works and we can grab the flag: