Level 1
This was a web hacking challenge with some client-side JavaScript code to evaluate the key.
Looking at the underlying JavaScript we can see this obfuscated code:
After beautifying the code, this is what we can see:
var _0x52ae = [...];The easiest way to deobfuscate this is to change "eval" to "console.log" (in chrome). This will print all of the unpacked JS source. Here is an interesting function:
eval(function (_0x7038x1, _0x7038x2, _0x7038x3, _0x7038x4, _0x7038x5, _0x7038x6) {
...
}(_0x52ae[0], 46, 46, _0x52ae[3][_0x52ae[2]](_0x52ae[1]), 0, {}));
function encrypt(form) {
var res;
res = numerical_value(form.password.value);
res = res * (3 + 1 + 3 + 3 + 7);
res = res >>> 6;
res = res / 4;
res = res ^ 4153;
if (res != 0) {
alert('Invalid password!')
} else {
alert('Correct password :)')
}
}
Any string that produces a numerical value between 62540 and 62544 will be accepted. Finally, this is how the numerical_value is computed:
function numerical_value(str) {
var i, a = 0,
b;
for (i = 0; i < str.length; ++i) {
b = ascii_one(str.charAt(i));
a += b * (i + 1)
}
return a
}
It is pretty straightforward to forge a key by hand now. This was one that worked for me: "}}zzzzzzzzzzzzzzzzzzzzzzzzzzzyyA". I started adding new letters until I was close to the target value. Then I changed the values that are close to the beginning to fine-tune it. It was a pretty bad idea to start with "z" characters, since there are very few characters with larger ASCII codes. Here is the flag as the result:
Level 2
The task here was to reverse-engineer an Android application package (apk) file. I cheated here and instead of looking at the source I looked at the resource files. There were 16 images that looked like parts of a QR code. It took me roughly 3 minutes to puzzle them together and after reading the QR code I got a flag:
788f5ff85d370646d4caa9af0a103b338dbe4c4bb9ccbd816b585c69de96d9da
Level 3
Level 3 was a 64-bit ELF executable. This is what happens when we launch the application:
I started reversing the ELF binary, but I'm terribly lazy and I wanted to do this as fast as I can, because if I were trying to get into the final with a team time would have mattered. I decided to write a script that tries every character until it is accepted and then continue with the next one. I figured out the first character by hand (it was a space, for some reason this was my third try) and then I knew what to look for in the output. Here is the script, it's pretty short:
And here is the flag after trying the password:
Interesting challenge. I really should have reversed it instead. I will never be a better reverse engineer if I keep cheating. Next time!
I started reversing the ELF binary, but I'm terribly lazy and I wanted to do this as fast as I can, because if I were trying to get into the final with a team time would have mattered. I decided to write a script that tries every character until it is accepted and then continue with the next one. I figured out the first character by hand (it was a space, for some reason this was my third try) and then I knew what to look for in the output. Here is the script, it's pretty short:
from subprocess import Popen, PIPE, STDOUTThis is what we get when we run the script:
flag = ""
while True:
for x in range(32, 128):
p = Popen(['./level.elf'], stdout=PIPE, stdin=PIPE, stderr=PIPE)
stdout_data = p.communicate(input=(flag+chr(x)))[0]
if stdout_data.count("*") > len(flag):
flag += chr(x)
print flag
break
Interesting challenge. I really should have reversed it instead. I will never be a better reverse engineer if I keep cheating. Next time!