Starblind (Reverse Engineering, 200) hackerstan team
Link to the task page:
Link to CTF tasks: https://ctf.dragonsector.pl/?challenges
It is a task for reverse engineering of JavaScript piece code, inside of html page.
Let’s begin!
We are greeted by a beautiful page, with charming planets and star systems!
The page shows a cursor, in the form of a bird and when you press keys, this field displays the entered data. In this case, if you fill in the values of the field, you will see a message, indicating, that we entered incorrect data :). A total of 27 characters can be entered.
But in order to understand, how the verification mechanism works, you need to look into the contents of the page.
Into the eyes immediately rushes an inline JS, using a data url, such as text/javascript. Naturally, to see this code, you need to unpack it from base64 into a normal readable text. This can be done in several ways:
- Copy the entire text excluding the header “data: text/javascript; base64,”
- In the browser console, use the function atob($0.src.replace(‘data: text / javascript; base64,’, ‘’)) by first selecting the node of the script tag.
We get the unpacked code and of course it’s a huge code, but after analyzing the contents, the procedure for entering the password and checking, it is becomes clear. And also we find the hash of the original password, which is further compared with the hash of the entered password.
Looking at the code of the CalcSHA4 function and seeing, in its code, a large number of perm and xor functions, made the assumption that you can try to reverse the actions, to create a hash and try to convert the hash to the original value.
As a result, I wrote the following code, which worked as follows:
- First, we need a non-standard function:
Math.sgn = function(a) { return 1/a<0; };
- Convert HEX values of password hash, to numbers, using the following code:
let d = “983bb35ed0a800fcc85d12806df9225364713be578ba67f65bc508b77f0c54878eda18a5eed50bac705bdc7db205623221e8ffe330483955a22216960754a122”.match(/.{1,2}/g)
match(/.{1,2}/g — this regex allows you to divide string of hex numbers by pairs.
- Convert numbers from a 16-digit system to a 10-digit system
for (let i = 0; i < 64; i++) { let n = parseInt(d[i], 16); r[i] = n; }
Using parseInt (hex number, 16), conversion to decimal system takes place.
- Because of the reversibility of XOR operations, it is assumed that we need to do perm and xor operations, in the reverse order. To do this, I copied separately the code for all calls to the perm and xor functions and divided the string, using the split(‘;’) function. Then I got array of function calls and called the reverse() function, to change the call order. After that I merge lines of code, using a “semicolon”.
- Now, we need to divide everything, that will turn out on 48271, as in the original code, there was a multiplication by this number, thus we perform all operations in the reverse order.
for (let i = 32; i < 64; i++) { r[i] = i / 48271; }
- From the received codes, you need to get the characters:
for (let i = 0; i < r.length; i++) { password += String.fromCharCode(r[i]); }
- Of course, in a browser such a large piece of code is difficult to execute, therefore I used Node.js and putting this code in a separate file, then execute it.
I misinterpreted the function code and missed the moment with dst_byte, src_byte and dst_bit with src_bit. These indexes should also be swapped, in order to restore the original order of the bits.
And here is the source code of the original perm function:
All operations in this function are reversible, the main thing is not to forget about the key points. And of course, for hash functions it is better to choose implementations that can not be reversible.
In general, after all the permutations and manipulations, I got the following code in order to get the original text of the password.
As a result, after running this script, the command
node decode_starblind.js
We get the output of the flag!
This task I really enjoyed, since I love JS, but attention to detail is very important :). I wish everyone care and good luck in the passage of CTF!
P.S. Well, at the same time I remembered operations with bits, the post on StackOverflow helped me a lot, let me remember some moments.