RSS

Leetmore CTF 2012 : Reverse 100 (Open Source)

This entry was posted on Oct 18 2012

We were given the following C source code:

#include
#include

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;
}`

So lets compile it:

$ gcc -o rev100 code.c
code.c: In function ‘main’:
code.c:7:6: warning: incompatible implicit declaration of built-in
function ‘exit’ [enabled by default]
code.c:13:6: warning: incompatible implicit declaration of built-in
function ‘exit’ [enabled by default]
code.c:19:6: warning: incompatible implicit declaration of built-in
function ‘exit’ [enabled by default]
code.c:24:6: warning: incompatible implicit declaration of built-in
function ‘exit’ [enabled by default]

Below is the commented source code:

#include
#include

int main(int argc, char *argv[]) {
// We need to have 4 arguments passed to the program.
// In C, the program name is a parameter too (so 3 real parameters are needed).
if (argc != 4) {
printf("what?\n");
exit(1);
}

// Convert argument 1 from a string to an integer.
unsigned int first = atoi(argv[1]);
// This integer must match the value of 0xcafe (= 51966 in decimal),
// to fail the next check.
if (first != 0xcafe) {
printf("you are wrong, sorry.\n");
exit(2);
}

// Convert argument 1 from a string to an integer.
unsigned int second = atoi(argv[2]);
// The following check fails when the integer:
// - doesn't have a modulus of 3 when dividing by 5
// and when it:
// - has a modulus of 8 when dividing by 17
if (second % 5 == 3 || second % 17 != 8) {
printf("ha, you won't get it!\n");
exit(3);
}

// This check fails if the third argument is h4cky0u.
// strcmp returns 0 (false), when there is an exact match.
if (strcmp("h4cky0u", argv[3])) {
printf("so close, dude!\n");
exit(4);
}

printf("Brr wrrr grr\n");

// Calculate the key based on the input.
unsigned int hash = first * 31337 + (second % 17) * 11 + strlen(argv[3]) - 1615810207;

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

We can use bash to convert hex values automatically and to do some
basic calculations with the $(()) construct.
(Programmers are lazy, right?)

$ ./rev100 $((0xcafe)) $((17*1+8)) h4cky0u
Brr wrrr grr
Get your key: c0ffee

$ ./rev100 $((0xcafe)) $((17*2+8)) h4cky0u
Brr wrrr grr
Get your key: c0ffee

$ ./rev100 $((0xcafe)) $((17*3+8)) h4cky0u
Brr wrrr grr
Get your key: c0ffee

Solution: c0ffee

Post a Comment