Author Topic: Crackme 02  (Read 1167 times)

0 Members and 1 Guest are viewing this topic.

Offline daxda

  • Peasant
  • *
  • Posts: 114
  • Cookies: 112
  • Not the guy you're looking for
    • View Profile
    • Daxda on Github
Crackme 02
« on: 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
« Last Edit: December 23, 2013, 03:20:10 pm by daxda »

Offline s3my0n

  • Knight
  • **
  • Posts: 276
  • Cookies: 58
    • View Profile
    • ::1
Re: Crackme 02
« Reply #1 on: December 21, 2013, 08:30:53 pm »
Alright hold on to your hats folks.. ;)

First up:
Keygen
Code: (c) [Select]
#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 :)
Code: (c) [Select]
#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
Easter egg in all *nix systems: E(){ E|E& };E