XSS challenges are a great way to learn cool tricks on how to exploit client side and circumvent browser’s security measures. This months Intigriti XSS challenge was made by @aszx87410. The requirements for the solution were simple:
- It should work on the latest version of Chrome and FireFox.
- It should execute alert(document.domain).
- It should leverage a cross site scripting vulnerability on this domain.
- It shouldn’t be self-XSS or related to MiTM attacks.
- It should not require any kind of user interaction. There should be a URL that when visited will present the victim with a popup
As we open the link with the challenge we are immediately stroke by a nostalgia wave of the Windows XP CSS styling.
On the webpage we can see a “Window Maker” program, and when we enter some dummy data a custom “window” in generated.
When we open the request in the Burp Suite we can see the following request:
GET /challenge/Window Maker.html?config[window-name]=testname&config[window-content]=testcontent&config[window-toolbar]=min&config[window-toolbar]=max&config[window-toolbar]=close&config[window-statusbar]=true HTTP/2 Host: challenge-0422.intigriti.io
The culprit of this encoding is the
The function replaces every occurence og the
<>%& characters and replaces it with
_. Every occurance of word
script is replaced too. However if the
typeof data !== 'string' condition is not met, the function will not sanitize the user input and simply return the data. To bypass this we can add square brackets
 to the URL parameter, so the function will treat the input as an array. With the following payload, we can bypass sanitization, but still no XSS as the tags are not rendered into DOM tree.
The URL passed to the application is parsed using the
parseQueryString(location.search) function. Later we can see, that if the
checkHost() function will be bypassed, we will be able to overwrite the
By exploiting a prototype pollution in the
merge() function we are able to overwrite the prototype of the
Array and change the value of
temp to 8080. This can be done by appending the following parameter to the URL:
The above exploit works as there is no
prototype string in the
So now we can overwrite the
devSettings object by simply passing the parameter
settings in the URL:
The final goal is to alter the DOM content, which is generated from the
It took me a while to search for the right parameter to overwrite but finally I found that the
innerHTML of the
settings[root][ownerDocument][all] object can be overwritten and results in HTML code injection into the webpage. The last thing to do, was to add the bypass we found in the first place, to omit the sanitization and inject a malicious script to the webpage. The final payload looked like this:
When we open the above URL we could see that an
alert() function was triggered thus completing the challenge.