Wednesday 5 April 2017

Starblind - Teaser CONFidence CTF 2017

This was a 200 points reverse engineering challenge.
Challenge Description:

The light of the star is blinding.

Clicking on the above link, it redirects to another website. It was actually very surprising to get a link to a website as a reversing challenge. When we view the source code, we can find a javascript link which is base64 encoded. After decoding, we get the following file Starblind.html.

The input to be supplied is 27 characters long. After encoding it using  CalcSHA4, it is compared with the following string:
983bb35ed0a800fcc85d12806df9225364713be578ba67f65bc508b77f0c54878eda18a5eed50bac705bdc7db205623221e8ffe330483955a22216960754a122

I guessed that the correct input must be the flag. Actually, some junk values were being added to our input to make its length 64. Then is was encoded by two functions xor and perm. Each function was being called alternatively. The xor function had an array of length 64 as argument and perm had an array of length 512 as argument. Then many operations were being carried out on our input with the help of those arguments. In total both of those functions were being called alternatively for a total of 512 times.

The functions were being called in the following order:
perm()
xor()
perm()
xor()

What we have to do is this:
reverse_perm()
xor()
reverse_perm()
xor()

Now lets see what the perm function actually does:
        let perm = function(imm) {
            let n = new Uint8Array(64);
            for (let i = 0; i < 512; i++) {
                const dst_bit = i % 8;
                const dst_byte = i / 8 | 0;
                const sign = Math.sgn(imm[i]);
                const idx = sign ? -imm[i] : imm[i];
                const src_bit = idx % 8;
                const src_byte = idx / 8 | 0;
                let b = (r[src_byte] >> src_bit) & 1;
                if (sign) {
                    b ^= 1;
                }
                n[dst_byte] |= b << dst_bit;
            }
            r = n;
        };
What this function is actually doing is,
n[dst_byte][dst_bit]=r[src_byte][src_bit]
The function does this for each bit. So the total no. of iterations will be 64 X 8 times i.e 512.
Finally the value of n is saved to r. Then xor function is called with the integer array of length 64 as argument. Then r is xor ' ed with that array and result is stored in r. The same things are repeated again and again for a total of 512 times.

Now what I did is decode the encoded string given in the program to find out the flag. For that I wrote the following script:

Finally the script prints out the following flag:

DrgnS{Humank1ndEmpire0fAbh}