[EN] YesWeHack DOJO#20

YesWeHack DOJO#20

Write-up of the YesWeHack DOJO Challenge #20.

Scenario

/dojo20/scenario.png

Code overview

Here is the JavaScript code used in the challenge :

/dojo20/js_code.png

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() !

/dojo20/xss_trigger.png

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 :

/dojo20/chall_solve.png

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