Tuesday, June 11, 2013

Boston Key Party CTF 2013 - Reverse 100 - Randy - [Team xbios]

Randy is a ELF 64-bit LSB executable. We have to figure out the valid key
[ctf@renorobert BKPCTF]$ ./randy 
Password: qwerty
:(
Analysing the binary, we notice the following

[*] Key is 28 characters long
[*] Each 4 bytes from key is used as seed argument for srandom() function ie. we have 7 blocks of 4 characters each
[*] Then random() function is called 4 times, on each block of 4 characters and generated numbers are compared to validate the key
[*] So the idea is to figure out the seed value used for srandom() function

We can bruteforce the seed value to figure out the key. Here is the C code to do this
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv) {

    unsigned int seed;
    long int rand;
    unsigned int de;
    unsigned int ad;
    unsigned int be;
    unsigned int ef;
 
    for(de = 0x20; de <= 0x7e; de++) {
        for(ad = 0x20; ad <= 0x7e; ad++) {
            for(be = 0x20; be <= 0x7e; be++) {
                for(ef = 0x20; ef <= 0x7e; ef++) {
                    seed = (de << 24 | ad << 16 | be << 8 | ef << 0 );
                    srandom(seed);
                    rand = random();
                    if(rand == 0x7358837a)
                        printf("Possible seed for 00-03 bytes: 0x%x\n", seed);
                    else if(rand == 0x34d8c3b5)
                        printf("Possible seed for 04-07 bytes: 0x%x\n", seed);
                    else if(rand == 0x1f49456c)
                        printf("Possible seed for 08-11 bytes: 0x%x\n", seed);
                    else if(rand == 0x1fea6614)
                        printf("Possible seed for 12-15 bytes: 0x%x\n", seed);
                    else if(rand == 0x4e81abc7)
                        printf("Possible seed for 16-19 bytes: 0x%x\n", seed);
                    else if(rand == 0x683d3f5d)
                        printf("Possible seed for 20-23 bytes: 0x%x\n", seed);
                    else if(rand == 0x28c9a8fe)
                        printf("Possible seed for 24-27 bytes: 0x%x\n", seed);
                }
            }
        }
    }
}
Running the code, we got the seeds in sometime
[ctf@renorobert BKPCTF]$ ./brute_randy 
Possible seed for 00-03 bytes: 0x2074306e
Possible seed for 24-27 bytes: 0x21212121
Possible seed for 08-11 bytes: 0x30646e34
Possible seed for 20-23 bytes: 0x31316120
Possible seed for 12-15 bytes: 0x3420306d
Possible seed for 04-07 bytes: 0x72203073
Possible seed for 16-19 bytes: 0x72337466
Now converting this to text gives us the valid key
>>> from struct import pack
>>> pack("<I",0x2074306e)+pack("<I",0x72203073)+pack("<I",0x30646e34)+pack("<I",0x3420306d)+pack("<I",0x72337466)+pack("<I",0x31316120)+pack("<I",0x21212121)
'n0t s0 r4nd0m0 4ft3r a11!!!!'
[ctf@renorobert BKPCTF]$ ./randy 
Password: n0t s0 r4nd0m0 4ft3r a11!!!!
:)
Flag for the challenge is n0t s0 r4nd0m0 4ft3r a11!!!!

No comments :

Post a Comment