Starblind (Reverse Engineering, 200) hackerstan team

Alexandr Vishniakov
Hackerstan CTF Team
5 min readApr 4, 2017

--

Html page of Starblind task
task description

Link to the task page:

https://s3.eu-central-1.amazonaws.com/dragonsector2-ctf-prod/starblind_96bbc884beb953bee0f120d0994d30d6073c53afd582f456586d7effa184dc25/starblind.html

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!

Html page of Starblind task

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.

Source code of HTML 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.

Original password hash with check password correctness function

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.

Correct version of the function with swapped dst_byte -> src_byte and dst_bit -> src_bit

And here is the source code of the original perm function:

Code of original 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!

Restored code of password from password hash

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.

--

--

«Переписывание с нуля гарантирует лишь одно — ноль!» — Мартин Фаулер