EvilZone

Hacking and Security => Reverse Engineering => : daxda December 20, 2013, 01:00:29 PM

: Crackme 02
: daxda December 20, 2013, 01:00:29 PM
Welcome to crackme number two!
This time you are supposed to write a keygen, no patching allowed!
Please write a short description on how you solved it and include the keygen if you're able to do so.
Good luck.

Edit: I found that I released this crackme to early. I forgot to fully test and implement the logic completely.
You'll find the new version below! Thanks to s3my0n who made me curious on why his solution even worked!

Download Crackme02 (http://upload.evilzone.org/download.php?id=4704568&type=rar)
: Re: Crackme 02
: s3my0n December 21, 2013, 08:30:53 PM
Alright hold on to your hats folks.. ;)

First up:
Keygen
: (c)
#include <stdio.h>
#include <string.h>

/* Author: s3my0n
 * Date:   Dec 2013
 * Desc:   Keygen for Daxda's crackme02 challenge
 */

const int NUM_SEEDS = 49;

const int START = 1003;
const int END = 1983;

char KEY[] = "S3M....Y..X..0000N-da";

int pepper(int num)
{
   int res = ( (num / 3) + 16) * 2;

   if (res <= 999)
      res = (num / 3) * 7 + 42;
   
    return res;
}

int main(int argc, char *argv[])
{
    int start_seed = 0;
    if (argc > 1) {
        start_seed = atoi(argv[1]);
        if (start_seed <= 0 || start_seed > NUM_SEEDS) {
            fprintf(stderr, "Error: the start seed should be between 1 and %d inclusive!\n", NUM_SEEDS);
            return 1;
        }
    }

    char secret[5];

    register int i, j;
    register char a, b, c, d;

    for (i = start_seed*20+START; i <= END; i += 20) {
        snprintf(secret, 5, "%d", i);
        memcpy(&KEY[3], secret, 4);

        snprintf(secret, 5, "%d", pepper(i));
        KEY[12] = secret[0];
        KEY[11] = secret[1];
        KEY[9]  = secret[2];
        KEY[8]  = secret[3];

        for (a = '0'; a <= '9'; a++) {
            for (b = '0'; b <= '9'; b++) {
                for (c = a; c <= '9'; c++) {
                    for (d = b; d <= '9'; d++) {
                        KEY[13] = a;
                        KEY[14] = b;
                        KEY[15] = c;
                        KEY[16] = d;
                        printf("[%s]", KEY);
                        getchar();
                    }
                }
            }
        }
    }

    return 0;
}

And now for the desert, reversed crackme in C :)
: (c)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/* Author: s3my0n
 * Date:   Dec 2013
 * Desc:   RE'd Daxda's crackme02 binary
 */

const char *THOR_MAGIC_1 = "odjbyumd t";
const char *THOR_MAGIC_2 = "Go o o aei!";

const int START = 1003;
const int NUM_SECRET = 49;
int SECRET[49];

void hades(void)
{
   puts("Your serial is invalid.");
   exit(1);
}

void salt(void)
{
   SECRET[0] = START;
   for (int i = 1; i < NUM_SECRET; i++)
      SECRET[i] = SECRET[i-1] + 20;
}

void Thor(char *user_input)
{
   if (user_input[18] != '-')
      hades();
   if (user_input[19] != 'd')
      hades();
   if (user_input[20] != 'a')
      hades();

   for (int i = 0; i <= 10; i++)
      printf("%c%c", THOR_MAGIC_2[i], THOR_MAGIC_1[i]);
   putchar('\n');
}

void gaia(char *user_input)
{
   char buffer[5];
   buffer[4] = '\0';

   buffer[0] = user_input[13];
   buffer[1] = user_input[14];
   buffer[2] = user_input[15];
   buffer[3] = user_input[16];

   if (buffer[0] > buffer[2])
      hades();
   if (buffer[3] < buffer[1])
      hades();

   Thor(user_input);
}

void pepper(int num, char *user_input)
{
   if (user_input[10] != 'X')
      hades();

   int res = ( (num / 3) + 16) * 2;

   if (res <= 999)
      res = (num / 3) * 7 + 42;

   char string[5];
   string[4] = '\0';
   sprintf(string, "%d", res);

   char buffer1[6];
   buffer1[5] = '\0';

   buffer1[0] = string[3];
   buffer1[1] = string[2];
   buffer1[2] = 'X';
   buffer1[3] = string[1];
   buffer1[4] = string[0];

   char buffer2[6];
   buffer2[5] = '\0';

   buffer2[0] = user_input[8];
   buffer2[1] = user_input[9];
   buffer2[2] = user_input[10];
   buffer2[3] = user_input[11];
   buffer2[4] = user_input[12];

   if (strcmp(buffer1, buffer2) != 0)
      hades();

   gaia(user_input);
}

int main(void)
{
   salt();

   char user_input[22];
   user_input[21] = '\0';

   printf("Please enter your serial: ");
   if (scanf("%21s", &user_input) == 0)
      hades();

   if (strlen(user_input) != 21)
      hades();

   char buffer[5];
   buffer[4] = '\0';

   buffer[0] = user_input[3];
   buffer[1] = user_input[4];
   buffer[2] = user_input[5];
   buffer[3] = user_input[6];

   int number = atoi(buffer);

    int i;
   for (i = 0; i < NUM_SECRET; i++)
      if (number == SECRET[i]) {
         pepper(number, user_input);
            break;
        }

    if (i == NUM_SECRET)
       hades();

   return 0;
}

Yes, the salt is simplified, but produces the same result :P

Thanks for the challenge, it was fun cracking it :D