InCTF Internationals 2021 - MD-Notes Write-up
Table of Contents
tl;dr
- Leak admin’s hash using wildcard target origin in postMessage or by calculating
sha256('')
. - Create an XSS payload to read
/api/flag
and send it to attacker server.
Challenge Author: imp3ri0n
Challenge Points: 1000
#
Introduction
A brief write-up of MD-Notes, web exploitation challenge from InCTF Internationals 2021. The source code of the challenge can be downloaded from here.
We’re provided with a markdown editor and an admin bot. The admin bot visits any link that is provided to it.
#
Initial Analysis 🔎
When a note is previewed, a POST request is made to /api/filter
which returns a Hash, sanitized text and raw input. Preview is rendered inside an iframe using the following script.
|
|
The preview iframe sends back the filtered input (note that it contains Hash
).
To save the post, a request has to be made to /api/create
, which contains the hash and raw body. The created post is encoded if the hash does not belong to the admin.
|
|
There’s a /_debug
endpoint that returns the admin_bucket
. There is also /api/flag
endpoint which returns the flag if admin token (which is in turn the flag) matches the cookie value.
#
Exploit 💥
From the above observations, we can conclude that:
- We require XSS to read
/api/flag
. - XSS is possible only with the admin’s hash.
##
Retrieving the Hash
The admin’s hash can be retrieved in two ways:
- By sending the bot to an attacker controlled website that contains an iframe pointing to /demo and sending a postMessage to it.
|
|
- The value of
hash
is always equal tosha256('')
sinceCONFIG.admin_token
will be undefined. That means, the hash will bee3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
.
##
Creating an XSS payload
Once the hash is retrieved, it is trivial to create a post that contains an XSS payload.
|
|
Sending a request as above creates a post in admin’s bucket.
|
|
#
Final Payload
exploit.py
|
|
exploit.js
|
|
#
Flag ✨
|
|
Thanks for reading.
Cheers. 🍻