Wednesday, May 29, 2013

HackYou CTF 2012 : Binary - OpenSource

HackYou CTF 2012 : Binary - OpenSource

Hints given to us:


Choosing "Open-Source", we got a code.c file. Inside this .c file, we got the following source code.

#include <stdio.h>
#include <string.h>

int main(int argc, char *argv[]) {
    if (argc != 4) {
        printf("what?\n");
        exit(1);
    }

    unsigned int first = atoi(argv[1]);
    if (first != 0xcafe) {
        printf("you are wrong, sorry.\n");
        exit(2);
    }

    unsigned int second = atoi(argv[2]);
    if (second % 5 == 3 || second % 17 != 8) {
        printf("ha, you won't get it!\n");
        exit(3);
    }

    if (strcmp("h4cky0u", argv[3])) {
        printf("so close, dude!\n");
        exit(4);
    }

    printf("Brr wrrr grr\n");

    unsigned int hash = first * 31337 + (second % 17) * 11 + strlen(argv[3]) - 1615810207;

    printf("Get your key: ");
    printf("%x\n", hash);
    return 0;
}

Recommended Tools:
Brains
C Compiler

Solution to this challenge:
I've started solving this by analysing the source code.

...
if (argc != 4) {
...

Looking at the above code snippet, since "argc" must be 4. We know that it requires 3 arguments.


...
unsigned int first = atoi(argv[1]);
if (first != 0xcafe) {
    printf("you are wrong, sorry.\n");
    exit(2);
}
...

Now, the first argument is being converted to int and stored inside unsigned int, first.
Then the value of first is being compared to 0xcafe.
As 0xcafe is in hex, converting this to int means that argv[1] must be 51966.
In case you are wondering why did i confirm that, please read the documentation of atoi.

...
unsigned int second = atoi(argv[2]);
if (second % 5 == 3 || second % 17 != 8) {
    printf("ha, you won't get it!\n");
    exit(3);
}
...

Now, let's take a look at the 2nd argument.
It's being converted to int like the 1st argument and stored inside unsigned int, second.
The value that we want is that when divided by 5 must not have remainder 3 and when divided by 17 must have a remainder of 8.
Now's that's easy. Let's satisfy the 2nd condition. Since second divided by 17 must have a remainder of 8.
Thus, second must be 17+8 = 25
Ok, using 25 as the value of second. Let's check whether it satisfy the condition of the first one.
17%5=2
It satisfy the first condition as well as the remainder is 2.
Thus, we now know that argv[2] is 25

...
if (strcmp("h4cky0u", argv[3])) {
    printf("so close, dude!\n");
    exit(4);
}
....

Ok, looking at the documentation for strcmp.
We know that argv[3] must be h4cky0u

Now, you can either compile the above source code and feed in the arguments or you can manually calculate it.
I chose the latter option.

unsigned int hash = first * 31337 + (second % 17) * 11 + strlen(argv[3]) - 1615810207;
printf("Get your key: ");
printf("%x\n", hash);

Substituting all the arguments with the values that we have gotten. We got the following.
51966 * 31337 + (25%17)*11 + 7 - 1615810207
1628458542 + 88 - 7 - 1615810207
12648430

Since the final value of the hash is in hexadecimal, using calc to convert it.
The key is C0FFEE

cheers,
0x4a61636f62

No comments:

Post a Comment