[Misc] StrangerStrings
This site uses not working authorization code. Can you make it run?
For this challenge we’re just given a URL to a website.
We’re greeted by a form requesting two secrets from us.
If we take a peek at the source code we can see that the form is handled by a javascript function.
1
2
3
4
5
<form method="post">
<input id="secret1" type="text" class="form-control" placeholder="secret1" aria-label="login" aria-describedby="submit-button">
<input id="secret2" type="text" class="form-control" placeholder="secret2" aria-label="password" aria-describedby="submit-button">
<button class="btn btn-secondary" type="button" id="submit-button" onclick="javascript:secret_message()"> Login! </button>
</form>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var secret_message_encrypted = "133,188,162,169,175,186,13,143,139,186,137,181,179,136,234,169,136,181,162,160".split(",");
var secret1, secret2;
function secret_message() {
secret1 = document.getElementById("secret1").value.split("ie").join(",");
secret2 = document.getElementById("secret2").value;
var reveal_secret_message = new Function(
secret1,
"var i;\
var secret_message='';\
for(i=0;i<r.length;i++)\
secret_message += string.fromCharCode(\
((secret1.charCodeAt(i%secret1.length) + secret2.charCodeAt(i%secret2.length)) ^ parseInt(r[i])) % 256\
);\
alert(secret_message)");
eval("reveal_secret_message("+secret2+",secret_message_encrypted)");
}
We can see that the function fetches the values of the two text inputs, manipulates the first one, generates a function and calls it afterwards.
When generating the function the code passes secret1 as the argument list, hence the split("ie").join(",")
that allows us to “specify” more than one argument that’d be passed to it when calling.
After that the function is called with eval with secret2
and secret_message_encrypted
being passed as parameters (though param2 isn’t passed directly, it’s value will be the parameter that eventually lands as the argument).
Let’s take a look at the reveal_secret_message
function closer.
1
2
3
4
5
6
7
8
9
10
11
var i;
var secret_message = "";
for (i = 0; i < r.length; i++) {
secret_message += string.fromCharCode(
((secret1.charCodeAt(i % secret1.length) +
secret2.charCodeAt(i % secret2.length)) ^
parseInt(r[i])) %
256
);
}
alert(secret_message);
We see that there are 4 variables being used here:
- secret1 (defined in the parent scope)
- secret2 (also defined in the parent scope)
- r (presumably the secret_message_encrypted since it calls
parseInt
on a element of an array) - string (It’s easy to mistake this one as a typo but it isn’t)
From this we can take a fair guess that the arguments passed to the function would be the “string” and “r” variables. That takes care of the input we have to provide to “secret1”.
If we pass “stringier” as secret1, it will be derived as “string,r”.
Now to make the code run we have to set secret2 to a value that has the “fromCharCode” function defined. That’s pretty easy since that function is defined in the “String” object.
If we now use the two values in the form and submit them we will get an alert with the flag.
Flag: CTF{stringierString}