Monday, September 23, 2013

CSAW CTF 2013 :: RE: Crackme (300 points)

For this puzzle we are given a linux binary and nc 128.238.66.218 54321.


Upon connecting to the server, we are prompted for a registration code key. Obviously we need to RE the given binary and find the key...

Lets fire up IDA PRO!

First thing first! Lets see what String do we have.


Lets trace where the Thank you, valued customer is being referenced...


So we see a branch condition when the user enter a correct password... as shown below


What is this dword_804913C value?


That is a freaking large number... in fact it is a negative integer if you are considering it as a signed integer.

 Ok from here we can tell that a call is make to sub_8048EA0 where the user input is passed into it and eventually a DWORD value is passed out from the function call into EAX. The EAX is then matched with EDX which contains the large number. Question is what is the correct password that leads to a key match? If only this is a local binary, we can simply patch it lol!

Ok lets take a look at the function sub_8048EA0.

Not too complicated =)
some char* are passed in to this function. There is a variable that start at 1337 value. we loop through the given char* (user input) and do simple math as such

pseudo code:

variable1337 = 1337;
do{
   variable1 = 32 * variable1337 + (a char of the input string)
   get next char
   variable1337  = variable1337  + variable1
}loop all chars in the given char*

so what i do next is to write this in a script simple c program and brute force it. Remember that the calculation is a signed int.... therefore i converted the large value into a signed integer (-282184360) for comparison.

I guess that the password should be some common english letters/numbers/symbols therefore i brute force the chars that have the ascii between 65 and 123... and i brute force the password length from length 1 onwards...

and finally... after few minutes...

we got a match! 6 chars long `saV^W


Not too difficult =) Time to laze again...

Ok as requested... Here is my noob lazy program. Nothing too fancyful... =) but should be quite easy to understand

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

int generate(char *key)
{
  int temp = 0, start =1337; 
  char character; 

  if ( *key == NULL )
return 0;
  else{
character = key[0];
do{
      temp = (32 * start) + character;
 key++;
      character = key[0];
      start += temp;
    }
    while ( character != NULL );
  }

  return start;
}

int main(int argc, char* argv[])
{
char key[9]; // just in case shit happen we got to brute force more chars
int start = 65, end = 123;
memset(key,0,9);
for(int a= start; a < end; a++){
for(int b= start; b < end; b++){
for(int c = start; c < end; c++){
for(int d = start; d < end; d++){
for(int e = start; e < end; e++){
for(int f = start; f < end; f++)
{
key[0] = (char)a;
key[1] = (char)b;
key[2] = (char)c;
key[3] = (char)d;
key[4] = (char)e;
key[5] = (char)f;
int a = generate(key);
if(a == -282184360){
printf("found %s\n\r", key);
}
}
}
}
}
}
}
return 0;
}

Always Lazing
NoirD3vil

6 comments:

  1. Few minutes!?? I ran for ages on my system and I still did not get it. And yes my algo was correct, it does say the key you found is indeed right. Could you share the complete script?

    ReplyDelete
  2. This comment has been removed by the author.

    ReplyDelete
  3. These keys should be valid also:

    `s`w]x
    `s`w^W
    `saV]x
    `saV^W
    aR`w]x
    aR`w^W
    aRaV]x
    aRaV^W

    ReplyDelete