This month intigriti was developed by **@LooseSecurity and the goal was to achieve an xss.**

Let’s take a look at the code of the challenge.
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="./xss_files/bootstrap.min.css">
<title>Contact Info</title>
</head>
<body>
<div class="container mt-4">
<h1>Set Contact Info</h1>
<div class="form-group">
<label for="inpName">Name</label>
<input type="text" class="form-control" id="inpName">
</div>
<div class="form-group">
<label for="inpContact">Contact</label>
<input type="text" class="form-control" id="inpContact">
</div>
<div class="form-group">
<label for="inpValue">Value</label>
<input type="text" class="form-control" id="inpValue">
</div>
<button class="btn btn-primary"
onclick="handleInputName(document.getElementById('inpName').value, document.getElementById('inpContact').value, document.getElementById('inpValue').value);">Input</button>
<button class="btn btn-secondary" onclick="runCmdName('alert');">Info</button>
<h1 class="mt-4">Set Token</h1>
<div class="form-group">
<label for="inpToken">Token</label>
<input type="text" class="form-control" id="inpToken">
</div>
<button class="btn btn-primary"
onclick="handleInputToken(document.getElementById('inpToken').value);">Input</button>
<button class="btn btn-secondary" onclick="runCmdToken('alert');">Info</button>
</div>
<script src="./xss_files/core.js"></script>
<script src="./xss_files/md5.js"></script>
<script>
var user = {};
function runCmdToken(cmd) {
if (!user['token'] || user['token'].length != 32) {
return;
}
var str = `${user['token']}${cmd}(hash)`.toLowerCase();
var hash = str.slice(0, 32);
var cmd = str.slice(32);
eval(cmd);
}
function handleInputToken(inp) {
var hash = CryptoJS.MD5(inp).toString();
user['token'] = `${hash}`;
}
function runCmdName(cmd) {
var name = Object.keys(user).find(key => key != "token");
if (!name) {
return;
}
var contact = Object.keys(user[name]);
if (!contact) {
return;
}
var value = user[name][contact];
if (!value) {
return;
}
eval(`${cmd}('Name: ' + name + '\\\\nContact: ' + contact + '\\\\nValue: ' + value)`);
}
function handleInputName(name, contact, value) {
user[name] = { [contact]: value };
}
const urlParams = new URLSearchParams(window.location.search);
const nameParam = urlParams.get("setName");
const contactParam = urlParams.get("setContact");
const valueParam = urlParams.get("setValue");
const tokenParam = urlParams.get("setToken");
const runContactInfo = urlParams.get("runContactInfo");
const runTokenInfo = urlParams.get("runTokenInfo");
if (nameParam && contactParam && valueParam) {
handleInputName(nameParam, contactParam, valueParam);
}
if (tokenParam) {
handleInputToken(tokenParam);
}
if (runContactInfo) {
runCmdName('alert');
}
if (runTokenInfo) {
runCmdToken('alert');
}
</script>
</body>
</html>
Here’s a breakdown of the code
The code imports two JavaScript files: core.js and md5.js.
Initializes an empty object called user which will store user data.
Then there are the main functions of the code
runCmdToken(cmd):
cmd) based on a token.user object and if it is of the correct length (32 characters).str) by concatenating the token with the command and appending "(hash)" to it.eval() to execute the command.handleInputToken(inp):
inp) using MD5 hashing algorithm.CryptoJS.MD5() function and converts it to a string.user object.runCmdName(cmd):
cmd) based on user's name, contact, and value.user object (excluding the token).eval().handleInputName(name, contact, value):
user object.user object where the name serves as the key, and the contact and value are stored as properties of this nested object.setName, setContact, and setValue parameters are provided, it calls handleInputName to store the data. If setToken parameter is provided, it calls handleInputToken to generate a token.runContactInfo is set, it calls runCmdName to execute a command based on user's name, contact, and value. If runTokenInfo is set, it calls runCmdToken to execute a command based on the token.The code is not that long but we need to delve and analyze it properly.
So the first thing that we notice is the use of eval that would make a light tick.
However it is used into two different functions. The first function deal with the token and it is moreover alerted the value of the hash of the token and for this reason i decided to leave it for later and put my attention on the second eval.
However the syntax used is the following eval(${cmd}('Name: ' + name + '\\nContact: ' + contact + '\\nValue: ' + value))
I tried in different way to achieve an xss but i came to the conclusion that is not possible to break out of the quotes and perform an xss, so a new way needed to be found.
Leaving apart the runCmdName function we are left with 3 others functions, let’s analyze them more in depth