crackmes.one — find a real key

Уже давно не было постов так что стоит попробовать вернуться с решением простого таска на Crackmes.one)

Источник: https://crackmes.one/crackme/629e1e5833c5d4251e72375f

Задание от : f0rizen
Сложность: Легкий.

Первым делом всегда проверяю через DIE(Detect-It-Easy) есть ли какие подлянки или какие обертки. (Уже вошло в привычку….)
Источник: https://github.com/horsicq/Detect-It-Easy


Далее бежим в иду смотреть что интересного нам приготовил данный файл!

Ну начнем разбор псевдокода.
Всего 1 главная функция Main которая использует один параметр при запуске.
Далее выделяется массив v6 где [0-20] жестко залочены переменные в hex.
Так же можно заметить на строчках (16-17) что v6[24+] используется для сохранения преобразования каждого значения переменной aSup3rS3cr3tK3y. (Каждое значени — 0x22)

В конце же видим конструкцию:
Каждый символ нашего параметра с которым мы запускали программу прогоняется через XOR обработанной переменной aSup3rS3cr3tK3y и сравнивается с запрограммированным значением v6[0-20].

Как говорилось ранее это задание легкое и не требует большого опыта за плечами)

На скорую руку был написан такой python код.

v6 = [0]*21
v6[0] = 0x37
v6[1] = 0x3F
v6[2] = 0x2F
v6[3] = 0x76
v6[4] = 0x2B
v6[5] = 0x62
v6[6] = 0x28
v6[7] = 0x21
v6[8] = 0x34
v6[9] = 0xF
v6[10] = 0x77
v6[11] = 0x62
v6[12] = 0x48
v6[13] = 0x27
v6[14] = 0x75
v6[15] = 0x8
v6[16] = 0x56
v6[17] = 0x6A
v6[18] = 0x68
v6[19] = 0x4E
v6[20] = 0x68

secretkey_out = ""
super_key = 'sup3r_s3cr3t_k3y_1337'

for i in range(0,len(super_key)):
    soks = ord(super_key[i]) - 0x22
    secretkey_out += str(chr(soks ^ v6[i]))

print(secretkey_out)

#Output:
#flag{_y0u_f0und_key_}

В коде мы взяли жестко запрограммированные значения v6 и sup3r_s3cr3t_k3y_1337. Последний мы обработали так как и в программе с минус 0x22.

Так как у нас идет сравнение v6[0-20] с ксореным вводом то делаем обратное и получаем флаг)

Осталось самое сладкое — Восстановить исходник в C код (Большое спасибо @ROP за основу реверса 😀 )

Буду использовать CodeBlocks, а псевдокод как начальные данные.

#include <stdio.h>

int main(int argc, char* argv[])
{
    char aSup3rS3cr3tK3y[] = "sup3r_s3cr3t_k3y_1337";

    int i;
    int j;
    int v6[50];
    if (argc == 1)
    {
        puts("Usage: ./crackme FLAG");
        return 1;
    }
    else if ( strlen(argv[1]) == 21 )
    {
        for ( i = 0; i <= 20; ++i ){
            v6[24+i] = aSup3rS3cr3tK3y[i] - 0x22;
        }
        v6[0] = 0x37;
        v6[1] = 0x3F;
        v6[2] = 0x2F;
        v6[3] = 0x76;
        v6[4] = 0x2B;
        v6[5] = 0x62;
        v6[6] = 0x28;
        v6[7] = 0x21;
        v6[8] = 0x34;
        v6[9] = 0xF;
        v6[10] = 0x77;
        v6[11] = 0x62;
        v6[12] = 0x48;
        v6[13] = 0x27;
        v6[14] = 0x75;
        v6[15] = 8;
        v6[16] = 0x56;
        v6[17] = 0x6A;
        v6[18] = 0x68;
        v6[19] = 0x4E;
        v6[20] = 0x68;
        for ( j = 0; j <= 20; ++j )
        {
            if (((argv[1][j]) ^ (v6[24+ j] )) != v6[j])
            {
                puts("Wrong flag");
                return 1;
            }
        }

        printf("You found a flag! %s\n", argv[1]);
        return 0;
    }
    else
    {
        puts("Wrong flag");
        return 1;
    }
}

Используя код CodeBlocks мы получаем рабочий EXE файл для Windows. (P.S. изначальный файл был ELF64 если кто не заметил)

Постараюсь не терять сайт и потихоньку углубляться в реверс, но особенно в восстановление кода)
Спасибо большое тем кто дочитал до конца)