R0 CREW

Кейген: грубая сила или способность предугадать

Вот KeygenMe(ссылка) “Psychic powers or brute strength your choice”, в котором автор предлагает решить его либо с помощью брут-форса, либо раскусить алгоритм по которому автор генерирует ключи. С первым способом проблем нет. Ниже приведу описание работы кейгена и решение в лоб с помощью брута. Второй способ вызывает вопросы - надеюсь на вашу помощь в прояснении ситуации.

Описание работы КейгенМи:

программа сначала проверяет удовлетворяются ли условия:

5 <= len(NAME)< 256
16 <= len(KEY) < 256

Далее она переводит в нижний регистр все заглавные буквы имени(далее NAME). И удаляет все символы, которые не входят в диапазон ‘a’-‘z’. Затем удаляет с ключа(далее KEY) все, что не есть буквами base64-алфавита, и проверяет if len(KEY) == 16.
В дальнейшем будем рассматривать NAME как строку длиною в 5 или больше букв с диапазона ‘a’-‘z’. KEY, как строку длиной в 16 символов из base64-алфавита(’+’,’/’,‘0’-‘9’,‘A’-‘Z’,‘a’-‘z’).
Потом программа сравнивает или пара NAME:KEY не равняется:
“lostit”:“RY5obY7IduF4Se2T”
“tutsyou”:“RkIomczPYHNrJoCA”,
которые являются валидными парами, по каким-то причинам занесенными в блек-лист.

Теперь наша программа начинает считать разные хеши и делать разные проверки.

ПЕРВЫЙ_ХЕШ: 12-байтовый хеш, которые извлекается с KEY. Давайте назовем его K_hash_1. Каждые 4 байта 16-байтного ключа, конвертируются в 3 байта 12-байтного хеша. Смотри get_K_hash_1() функцию в коде ниже:

char base64alphabet_map[] = {
	/* 01*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	/* 10*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	/* 20*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	/* 30*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	/* 40*/ 0, 0, 0,62, 0, 0, 0,63,51,53,/*43:+,47:/,48:0*/
	/* 50*/54,55,56,57,58,59,60,61, 0, 0,
	/* 60*/ 0, 0, 0, 0, 0, 0, 1, 2, 3, 4,/*65:A*/
	/* 70*/ 5, 6, 7, 8, 9,10,11,12,13,14,
	/* 80*/15,16,17,18,19,20,21,22,23,24,
	/* 90*/25, 0, 0, 0, 0, 0, 0,26,27,28,/*90:Z,97:a*/
	/*100*/29,30,31,32,33,34,35,36,37,38,
	/*110*/39,40,41,42,43,44,45,46,47,48,
	/*120*/49,50,51, 0, 0, 0, 0, 0, 0, 0/*122:z*/
};


void get_K_hash_1_quarter(const char in[4], char out[3]) {
	unsigned int c0 = base64alphabet_map[in[0]];
	unsigned int c1 = base64alphabet_map[in[1]];
	unsigned int c2 = base64alphabet_map[in[2]];
	unsigned int c3 = base64alphabet_map[in[3]];

	unsigned int hash_chunk = (((((c0 << 6) + c1) << 6) + c2) << 6) + c3;

	unsigned int temp_hash;
	temp_hash = hash_chunk >> 16;
	out[0] = (char)temp_hash;
	temp_hash = hash_chunk >> 8;
	out[1] = (char)temp_hash;
	out[2] = (char)hash_chunk;
}

void get_K_hash_1(const char *key, char custom_hash[16]) {
#define KEY_LEN 16
#define HASH_LEN 12
	for (int i = 0, n = 0; i < KEY_LEN, n < HASH_LEN; i = i + 4, n = n + 3) {
		get_K_hash_1_quarter(key + i, custom_hash + n);
	}
}

ВТОРОЙ_ХЕШ: 16-байтный хеш, которые производится с K_hash_1, назовем его K_hash_2. K_hash_2 инициализируется с помощью функции приведенной ниже:

void init_K_hash_2(const char src_hash[16], char dest_hash[0x10]) {
	dest_hash[0x0] = src_hash[0];
	dest_hash[0x1] = src_hash[1];
	dest_hash[0x2] = src_hash[2];
	dest_hash[0x3] = src_hash[3];
	dest_hash[0x4] = src_hash[4];
	dest_hash[0x5] = src_hash[5];

	dest_hash[0x6] = src_hash[0];
	dest_hash[0x7] = src_hash[1];
	dest_hash[0x8] = src_hash[2];
	dest_hash[0x9] = src_hash[3];
	dest_hash[0xA] = src_hash[4];
	dest_hash[0xB] = src_hash[5];

	dest_hash[0xC] = src_hash[0];
	dest_hash[0xD] = src_hash[1];
	dest_hash[0xE] = src_hash[2];
	dest_hash[0xF] = src_hash[3];
}

Потом K_hash_2 используется как инпут, чтоб посчитать MD5. K_hash_2 ксорится с полученным 16-байтовым MD5-хешем. См. код ниже

#include <openssl/md5.h>

void MD5_and_XOR(char hash_buffer[16]) {
	char md5[MD5_DIGEST_LENGTH] = { 0 };
	MD5((const unsigned char *)hash_buffer, 16, (unsigned char *)md5);
	for (int i = 0; i < 16; i++)
		hash_buffer[i] ^= md5[i];
	return;
}

И это в цикле повторяется 1000 раз.

ТРЕТИЙ_ХЕШ: 16-байтовый хеш извлекаемый с NAME, назовем его N_hash. N_hash инициализируется используя нижеизложенную функцию:

void init_N_hash(const char * name, unsigned char name_len, char dest_hash[0x10]) {
	if (name_len <= 0x10) {
		for (int i = 0; i < 0x10; i++) {
			dest_hash[i] = name[i % name_len];
		}
	}
	if (name_len > 0x10) {
		memcpy(dest_hash, name, 0x10);
		for (int i = 0; i < name_len - 0x10; i++)
			dest_hash[i % 0x10] ^= name[i + 0x10];
	}
}

Потом в цикле 1000 раз N_hash хешируется с помощью MD5 и ксорится с полученным хешем подобным образом как и K_hash_2 с помощью функции MD5_and_XOR() (описано выше).

1ая_ПРОВЕРКА:
Примечание: далее питоно-подобный псевдокод

N_hash[0:6] == K_hash_1[6:12]

2ая_ПРОВЕРКА:

K_hash_2[0:6] == [0xE9, 0x85, 0x5D, 0x5B, 0x2F, 0x41]

Обход проверок:

1ая_ПРОВЕРКА:
С NAME извлекаем N_hash. N_hash[0:6] согласно 1ой проверки должен равняться K_hash_1[6:12]. Из K_hash_1[6:12] мы легко можем извлечь KEY[8:16]. Код ниже извлечет для нас KEY[8:12] с N_hash[0:3] и KEY[12:16] с N_hash[3:6].

void brute_key_quarter(const char * in_3chars, char * out_4chars) {
	/*Brute-force init*/
	char input[4] = { '.','/' ,'/' ,'/' }; 	// '/'-'9', 'A'-'Z', 'a'-'z'
	unsigned int* p2input_as_dw = (unsigned int*)input;
	char output[3] = { 0 };
	/*Brute-force loop*/
	do {
	START:
		(*p2input_as_dw)++;
		for (int i = 0; i < 4; i++) {
			if (
				!(input[i] >= '/' && input[i] <= '9') &&
				!(input[i] >= 'A' && input[i] <= 'Z') &&
				!(input[i] >= 'a' && input[i] <= 'z')
				) {
				goto START;
			}
		}
		get_K_hash_1st_quarter(input, output);
	} while (
		!(output[0] == in_3chars[0] && output[1] == in_3chars[1] && output[2] == in_3chars[2])
		);
	/*Brute-force end*/
	out_4chars[0] = input[0];
	out_4chars[1] = input[1];
	out_4chars[2] = input[2];
	out_4chars[3] = input[3];
};

2ая_ПРОВЕРКА:
1ый способ с помощью БрутФорса.
Имея 2ую часть ключа(KEY[8:16]) извлеченую с NAMEможем брут форсить KEY[0:8].
Вот ссылка на кейген основанный на бруте, который брутит в количество потоков равное количеству ядер на компьютере. Решение не элегантное, требующие мощную многоядерную машину и вагон времени.
2ой способ. Автор назвал его “Psychic powers”, осмелюсь перевести как "экстрасенсорная сила"1.
Вот тут я не понял как это работает.
Единственное, что уловил с постов раз, два, что используются 2е валидные пары KEY:NAME запрещенный и захардкоженые, какая-то система ключей и последовательность 4056 байт.
Разъясните, пожалуйста как работает 2ой способ обхода 2ой проверки, повторюсь, описанный в постах раз, два ?

Данных для понимания 2го способа в вашем описании вообще нет.
Вы даете вторую проверку в виде

K_hash_2[0:6] == [0xE9, 0x85, 0x5D, 0x5B, 0x2F, 0x41]

на самом деле она выглядит как

idx = 6 * ((ord(name[0]) - 0x60) * (ord(name[1]) - 0x60) - 1)
K_hash_2[0:6] == master_table[idx:idx+6]

Во 2м способе речь идет как раз об этой master_table, с помощью которой идет проверка. Размер этой таблицы, глядя на способ адресации данных в ней - 2626 записей (626*26 байт). Что намного меньше массива возможных входных значений при расчете hash2 - 256**6. Это свидетельствует о большом количестве коллизий. На использовании коллизий и должен быть построен 2й метод. Для его реализации нам нужна таблица размером аналогичным master_table. Ее нужно сгенерировать. Трудно оценить необходимое время, потому, что не понятно как распределены коллизии, да и расчет одного варианта с учетом 1000 кратного MD5 затратный. Общая схема этой таблицы

idx = 6 * ((ord(name[0]) - 0x60) * (ord(name[1]) - 0x60) - 1)
master_table[idx:idx+6] == get_K_hash_2(need_table[idx:idx+6])[0:6]

При наличии такой таблицы, вся генерация может быть такой

name = 'qwerty'
idx = 6 * ((ord(name[0]) - 0x60) * (ord(name[1]) - 0x60) - 1)
rez_hash = need_table[idx:idx+6] + get_N_hash(name)[:6]
print 'NAME:', name
print 'KEY:', base64.b64encode(''.join(map(chr, rez_hash)))

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

#include "stdafx.h"
#include "md5.h"
#include <stdlib.h>
#include <stdio.h>
#include <memory.h>

typedef unsigned char byte;

static byte rez[6*26*26];
static byte check[26*26];
static byte in[6];

static byte table[] = {
233,133, 93, 91, 47, 65,185,222,119,168, 17, 43, 48,248,104, 98,
212, 62,176, 88, 53, 60,167, 98,247, 53, 97, 52, 46, 63,  4,  4,
250,116, 43,112,142, 20,110,215, 84, 90,203,199, 27, 47,245,213,
 52,  6, 18,154,213,165, 99, 69, 76, 24, 98, 99,231,127,139, 60,
199, 41,202,152, 73,  0,219, 84,140,135,189,167, 30, 70, 49, 29,
157,252,157,119,179,239,232,107, 59,236, 67,191, 12,213, 40,146,
124, 73,253,134,163,210,224, 41, 89,209,155,238,201, 44,127,234,
203, 54,133,199, 37,103, 64, 34,164,  7,113,207,101,177, 24,  7,
169, 46, 68,102,218, 40,184,231,219,178,140, 26,248,217,205,143,
 67, 23,166,128, 90,165,191,188,171,104,229,100,158,212,192,163,
106,252,234,110,  8,157,223,181,165, 18,180,193,139, 72, 47, 73,
184,134,157,236,168,239,152, 77,164,193,222,229,104,184,194,111,
112, 52,122,202,201,171,185,209, 12, 27,  3,119, 38,120,175,143,
  8,119,132, 13, 50, 94,195,155,225,137,251,103,110,233, 40,226,
173,128,241,141,164,  9, 43,117,165,128,218, 24, 35,130,251,136,
114,101,175, 74, 56,165, 97, 80,185,142, 81,192,171,243, 63, 24,
175,224,111, 10,114, 28,139,114,119,136, 44,220,126,154,  6, 62,
 10,123, 53,150, 12,148,167, 93,227, 28, 86, 77,150, 24,231, 81,
201,182, 73,118,  2,172,233, 32,146,134,145, 41,175, 41,130,219,
141,127,220, 15, 59, 22,126,193,232, 34, 65, 14, 72,139, 73,237,
  6, 12,153, 10,158, 55,125, 53,156,169, 49,156,165, 92,152, 60,
 74,243,133, 83, 72,102,  9,107,118, 37, 53,155,  7,251, 23,140,
136,253, 74,185,120, 77,238, 70,188,133,200,219, 12,129, 91, 44,
158, 36, 87, 69,252, 25,178,130,243,194, 90,107,126,219,236,155,
125, 80,112,108, 12,180,  8,251,139, 43, 50, 85,179,109,182,231,
223, 64,187, 41, 38,  5, 92,158,109,203,209,236, 69, 38,140, 57,
199, 58,186,163,138,108,194,207,100, 84, 56, 51,  0, 40,172,156,
115, 68, 85,219,113,236, 99,251, 35,203,105, 22,137, 47,185,106,
 20,184,134,120, 69,233, 22,199, 27,235,116,107,237,  8, 14,223,
 59,157,142,214,196,153,139,168,197,110,  9, 80,198,171, 29,244,
 32,221,166,214, 13,125, 10, 90, 63,178,157, 90,180, 86,238, 24,
 35,114,136,170,199,160,244,131, 69, 11, 87,148,214, 21, 14,  6,
  8,130, 19, 54,118,189,123,123, 74, 16,170,141, 88,  0,135,129,
131,225,137,231,192,205,131,250, 85,120,228,175,239, 14, 69,164,
 56,119,210,222, 96, 52,255, 46,185,217,232,218,104,149,226, 74,
224, 10,247,186,140,225,  3, 56,  8,176,  3,237, 11,206, 79,238,
188, 18, 70, 82,114, 82,249, 28,148,162,250,109,191,144,206,117,
 43,185,191,192, 28,204,109,252,140, 98,213, 23, 74,  5, 40,111,
  6,163,201,106, 58, 93,136, 82,202,251,159,192,240,149, 11,205,
252,178, 64, 75,131,240,219,151, 41,240,254,162, 21,108,174, 25,
 46, 88,197,139,  0,111, 92, 94, 73,108, 36,175, 66, 84,130,147,
  7,147,163, 80,251, 77,124,170,221,161,231, 22,158,122, 48, 63,
 56,254, 52,182, 98, 72,161, 18,188,116,134,240,  3,196, 38, 49,
168,223,172,112,108, 33, 33,108, 75,188,241,187,194,161,143,147,
233,237, 57,163,210,174,254, 52,110,140, 27,255,131,146, 86,148,
 16,141, 99, 50, 11,187,114, 32, 35,165,240,243,161,129, 15, 31,
 67, 39,160,173,128, 31,115,255,124, 44,191, 26, 54,152,185,230,
  5, 46,223, 41,164,  7, 42,229,245, 13, 54,241, 22, 81, 33, 85,
209,113,215,242, 65, 37,120, 20, 49,154, 29, 24,245, 90,116, 48,
140, 51, 15,134, 73,150,134,112,189,  8,199,112, 71,104,135,210,
 86,230,192, 85,104,235, 30, 12, 50,182,254,196, 24,245,225,153,
117,247,140, 27,166,197,137, 31, 21, 84, 21,188, 53, 33,253, 61,
 24, 43,160, 12, 89, 94, 68, 85,214,251,156,105,253, 62,250,229,
105, 97,223,240,153, 80,122,  7, 84,179,204,129,177,181,104,134,
249,161,227,213,  6,124, 46, 83,223,163,180,151, 90,197, 16, 20,
204, 44,128,127, 51,188,158, 86, 93,228, 51,169, 84,207,209, 50,
103,139,240,216, 34,  2,  3,195, 74, 32,103,230,137, 36,235,239,
 50, 48, 44,239, 79,199,125, 21,152, 71, 87,153,147, 60, 99, 76,
 77, 13,203,225,227,185,210, 51,246, 72, 94,133,  8,195, 68,141,
 87,102,230, 62, 43,118, 71,246,233,107,134,133,148, 60,254,244,
208,211, 18,125,219,105, 82,191,209,107,130, 26,151,239,250,175,
102, 39,133,133,100,116,186,155, 73,126,190,  9,120,122, 29, 10,
251,239, 47, 38,126, 84, 96,171, 96, 39,243, 12, 76, 95,247, 65,
 51, 11,178,141, 83,169, 62, 74,138,149,202,133, 31,133,245, 66,
165,185,175,173, 12,101,120,  3, 81, 75,100, 23,175,219,116,182,
210,205, 50,219,139,229,112,243, 99,212, 70, 70,154,171, 60,159,
 96,190,179,233,162,105,167, 21,123, 19, 86,226,117,219,241, 85,
 86, 20, 80,182, 88,247,  4,136,243,144, 50,139,132,105,121, 65,
218, 13,144, 64,182,173,166,252,  1, 85,129,  1, 19,105,231,147,
 53,229, 67,151, 37,  5,117,128, 21,152, 75,226,156,194, 99, 18,
 99,195,153, 79, 51,236,195,217,106,243, 98,249,185,100,155,139,
166,101, 55, 38,102,236,214,251,150, 47,180, 75, 26, 67,120, 32,
 53,211,203,187, 92,170, 20,111,230,205,100,140,174, 44, 58,163,
 79,139,198, 22, 84,170, 30, 31,251,253, 87,105, 27,210, 27,158,
 12, 90, 38, 42,127,195, 58, 60,194, 24, 57,191, 84,122,237,157,
109,203, 16, 67,198, 37,249, 78,154, 60,203,181,227, 60, 49,233,
 32,244,190,152,232, 66,176, 95,115, 55,176,122,178, 44,108,133,
168,127,223, 53,165,160,179, 36,223,203, 70,183,210,239,111,169,
167,136, 99, 55,120, 56,201,250,141, 94,246, 66, 79, 66, 21,116,
125, 69,104, 34,244, 82, 65,176,232, 42,210, 63,  5,250,182, 95,
204,255, 77,129, 81,118, 14,205,228, 20,147,246, 67,159, 35,224,
 87,153,206, 46,104,225, 67,164, 48,100, 17,237,104, 80,189,207,
 16,226,  0,193, 42, 70,250,195,196, 32, 17,223, 77, 68,105, 99,
139, 18,158,249,155,192,113,125, 98,255,  9,105,122,220,143,122,
 32, 47,199, 51,173,238, 87, 93,113,233,124, 33,244, 45,223, 26,
 40, 53, 57, 35,156,177,238,161, 66, 34,220,157, 78,187, 39,228,
114, 41,115, 46,198, 19,  8,212,148,126,131, 33,216, 88,254, 33,
169,172,117,194,216,195, 68, 61,  2,201,103,  3,112,167, 36, 30,
164,129,112,208,127, 17,234, 88, 64,187, 16,131,233,152, 21,123,
254,193,168,244,195,105, 57,119,  3, 77,203, 46,101,100, 84,106,
 98,241,238,  9,187,123,184,252, 23,187,255, 11, 43,244, 78,122,
123,231, 94, 73,158, 43,163, 56,163, 75, 53,149, 92,156,118,138,
241,  4,115,163, 84,112,103,  5,130,113,155,181,160, 29, 98, 13,
130,  6,236, 84, 40,  9,127,206, 81,167, 74,167, 14,  8, 47,205,
 93, 99, 14,249,136,200, 98,  7, 83,169,255,223, 26,141,170, 82,
 62,102,159, 55,120, 40,243,233,232,147,158, 52,202, 47,197,227,
124,142, 50,230, 59,182,205, 63,  7, 11,232,182,108,  2, 83,108,
245, 35, 28,212,  8,  1,  5,146, 22, 13,102, 32, 26, 71,247,162,
230,248, 41, 47,166,223,107,  9,194,100,175,249,110, 26, 77, 89,
161,193,248,140, 12, 40, 85,165, 86,247,211, 62,199, 60,175,185,
120,119,100,136,102,  9,101,181,226,128,107,169, 77,189,100, 33,
214, 58,144, 36, 21,104,237, 22, 21,234, 74,117, 55, 76,  6,124,
252, 99,224,118,177,170,238,230,198,116,151,255, 97,119, 40,111,
127, 70,227,187,105, 18, 64, 14,130,162,167, 97, 44,131, 48,232,
104, 43,253,125,248,221,192, 11,105,112,  9,216,244, 54, 67,245,
126, 99, 88, 22,215,104, 24,117,215, 97,208,156, 78,181,  6, 16,
218, 32, 60,195,168, 39, 51, 74,197,210, 34, 46,  9,161, 45,248,
214,  6,164,123, 45, 99,238, 75, 31,126,  6,213,105,196, 37,182,
157,129, 12,202, 19,  2,117,143, 90,186, 79,187, 55, 99,139,236,
 56,182,119, 38,239,152,179,215,114, 85,174, 92,236,127,  4,186,
241,111, 93,238,154,206,  3, 70, 74, 45, 94, 71, 73,234, 30,184,
105,159,198, 65,155, 65, 40, 77, 98,251,186,254, 37,111,132,249,
194,238,226,220, 42,238,148,159,162, 62,165,205,133,111,214,240,
 46, 50,215,184, 38,215, 35,170,110,191, 55,108, 21, 18, 69,151,
198,131,194, 30,235, 59,249, 29, 68,218,228, 29,172,209,191,159,
 62, 23,170,247, 99, 85,105,242, 54, 99,133,  4,148, 73, 15,162,
144,100, 98, 90,202, 81,119,188,116,153, 59,135,253,167, 54, 52,
235,141,181, 65,156, 14,113,240,160, 22,  8,209,200, 79,167,185,
 56, 65,110, 59,166,163, 10,175,245,203,110,134, 38,174,111,245,
 54,143, 69,100, 42,139, 25, 93,252, 19,232, 79, 92, 60,146,123,
 50, 72,  8,223,179, 34,159,114,182,252, 31,210,216,161,221,148,
 76, 86,  8,134, 80, 70,212,247, 18, 24,221,172,125,246,211,159,
215,188,151, 34, 93, 93,200,  3,240, 25,  4, 53, 99,225, 34,251,
152,158, 63, 14, 56, 36,212,113,  7, 63, 22,241, 79, 35,205,106,
154,201, 91,133,115,207, 69, 82,  0,101, 52,250, 20,167,241, 16,
240,150,166, 42,241,  9,150,151,207,119, 39, 49,147, 50, 17, 57,
221,177,255,159,152, 71, 37,246,150,123,  2,226,177,  3,255, 56,
176,145,116, 94, 56, 60,199,187,178,215,187,221,110,  6, 70, 74,
235,232,200, 86,203,170, 67,236,220, 95,128, 31,204, 52,240, 69,
184, 24, 12, 33,117,124, 94, 46, 67, 82, 70,178,223,247, 83,160,
  3, 27, 21,127,243,181,132,165,244, 30,179,205,203,239, 94,176,
182, 57,233, 60, 35,146, 29, 94,163,159,190,189, 47,191,110,184,
103,174,193,105,185, 22,212,211,193, 76,161,115,147, 81,196,221,
220, 96,196,248,  7, 81,156, 75, 52, 98, 59, 58,194,165, 30,130,
245,123,255, 33,107, 89, 53, 13,221,195,202,102,159, 97,117, 81,
131,225, 89,196,200,199, 31, 31,225, 18, 23,175,222,  9,155,136,
 93,100,123, 55,162,203,  2,167,112,194,168,124,113, 40,145, 86,
220, 59,176,204,198,243,236,216,184,197,117,188,167,129, 17, 83,
124,244, 89,214,159,193,229,204,153, 54,221,208,220, 66,206,208,
176, 20, 25,183, 26,142,152,200, 81, 23, 16,  7, 35, 72, 28,102,
245, 19,  3, 13,121,120, 14,  2,144,227,211,175,205, 77,135, 27,
155,152,157, 18,188,219, 64,251,245, 69, 36,148,156,192,126,208,
 52,140, 23,252,162,208,208,  6, 96,115, 22,224, 13,205, 24, 45,
174,155,108,213,210,203,131,234,240,153,203, 67, 33,165, 29, 27,
239,109, 50, 76, 33,203,143, 29,  3,132,255,253, 51,247, 51,130,
231,150,178, 74, 72,197, 74,144, 36,192,215,150,105, 49,165,150,
 86, 26,145,201,171, 69,235, 55,141,168,243,  7,245, 29, 49, 47,
 96,208,249,  4, 10,172, 25, 38,234,251,107,228, 35,211, 39, 46,
 22, 27,225, 40,135,148,208,  5,211,127, 15,222, 87, 97,146, 56,
 81,154, 76, 22, 65,244,191,162, 34, 28,201, 16, 29,112,134,113,
246,  5,189,188,248,125,180, 10,221,186, 64, 21, 42,163,187, 38,
216,217,212,239, 98, 97,206,  6,116,242, 22, 53, 80, 96,137,159,
229,227,245, 71, 37, 76, 48,129, 50,160,220,196,194,103, 65,151,
213, 64,162,233,254,  8, 33,203,161, 49, 28,203,187, 72,206,125,
139,174,158,157,231,109,207, 46,177, 57, 77,  7,206, 69,105,174,
219, 66,151,193,185, 29,197,  7,113,144,146, 85, 19,122, 50, 15,
210, 24, 67, 47,234,239,179,221, 72,  3, 45,241,208, 94,169,152,
229,230, 80,183,132,185,117,254,224,133, 70, 69, 82,113, 44,168,
212, 34, 23, 43,  3,116, 75, 83,157, 15,224,129,246, 95,172,173,
250,177,157,129,176, 75,103,184,250,185,106,222,  4,210, 22,111,
  4,143,225,147,208, 45,182,255,251,  6, 62,118,  8,217,128,197,
 97, 28,176,120, 69, 44, 70,232, 96,184, 94,183,  0,173,115,192,
 85,255, 22,206, 46, 47, 35, 26,216,230,  7,193, 33,216,234,119,
174,206,203, 91, 76, 48,135,250,209, 61, 47,113,241, 22,  5,154,
121, 90,174,168,116,146, 18,123,236,107,120,217, 90, 45,222, 74,
185, 67, 24, 41,108,178,102,117, 84,124,106,103,230,254,186,169,
209, 48,  7,113, 83,136,117,243,140, 73,214, 84,106, 39, 61,104,
171,  0, 82,  2, 42,131, 53, 80,189,242, 46, 62,  8,252, 93, 19,
220, 95,221, 57,105,227, 11,154,152,105, 87, 61,248,144, 40,123,
201,162,129,223,130,143,130, 68,178,250,195,243,213,229,142,169,
  1,181,165,237,111,  2,171,142, 21,219, 11, 35,207,151,215, 30,
121, 38, 30,223, 91, 46,188, 75,155,180,  7,134, 30, 18,120,244,
 48,179,211,102, 72,223, 25, 81,111,189, 47, 80,174,185,170,160,
204,218, 65,  2, 24,201,221, 17,113,235,177, 91, 29,138, 73,147,
189,238,200,250,150,106,120,189,229, 49,207, 68,100,201, 73, 90,
129,248,165,119,236,180,180,187,244, 73,203,  5,170,181,251, 60,
253,114,133,197, 58,125, 55, 84,230,154,245,184,230,130, 59,136,
244,155, 34,  2,124,168, 69, 45,243,115,115,108,  7, 85,112,177,
 37,120, 15,244, 69,  0,174,195,117,234,174,226, 31,157,121,159,
125,250,190, 79, 52,181,194,135,129,105, 15,169,168,106,142,139,
 61, 97,  8,212,160,197,197,216,246,156,150, 21,209,205, 79, 93,
 83,116,  9, 36, 65, 12,223,128,133, 33, 88,245, 82, 99,218,221,
  9, 71,204, 17,  9, 81,216, 89,120, 65,142, 21, 54,149, 96, 68,
199, 54,168,146,130,140,  5,218, 13,243,174,157, 51,234, 86,238,
239,113,106,187,207, 31, 81, 29,251,130,213,212, 30, 43, 36, 26,
212,137,232,119,211,180, 14,190,220,227,161,210,106,191,246, 63,
121,238,145,244,  9, 56,172,223,160, 59,167, 57,242,140, 28, 75,
207,150,158, 65, 60, 14,255,118, 67,114,  1,243, 37,153, 68, 81,
 68,114,141, 91,165,243, 37,183,122, 79, 12,  7, 36,176,  5,160,
 58,135, 52,114,192, 30, 37, 69, 66, 13,231,209,  5,247,123,150,
237,210,123, 98, 67,136, 93, 40,219,141,141, 38,232,247,170,224,
204, 53, 87,129,226,215, 58,182,175,106,225, 46,133,188,222,255,
201, 13, 15,164, 14,176,130,154,132,114, 51, 31,156,251,180, 67,
 52,133, 66,165,174, 18, 78, 46, 36,249,245,216,163,130,126,218,
 87, 10,163,  1, 85, 10, 87, 30,144,201,170, 68,232,159, 51,200,
163, 16,222,103,  1, 80, 84,192, 38, 37, 53, 54, 82, 93, 39,156,
163,197,204,235,123, 42,112,174, 63, 42,207,193, 20,177, 14,174,
181,196,199, 89, 47,128,156,120, 66, 10,190,206,192,251,146,155,
130,212, 75, 77, 60, 29,156, 22, 64, 32, 41,  3, 30,225,218, 18,
150,159,135, 89,108, 15,196,166,115, 92, 83, 46,191,  9, 14,160,
111,136,128, 76, 60,240,234, 32,235,123,195,152,210,131, 53, 49,
 68,213,246,175, 92,229, 65,  5,165,220,244,214,  1,222,117,189,
 30,215,202,104,189, 99,136,132,246, 32,183,167, 12,122,251,243,
223,173,125,156, 43, 24,186,140,251, 34, 11,109, 86,135, 22, 58,
 63, 75,163,239,231, 35,115,145,217, 32, 16, 39,115, 50,233, 94,
167, 60,216,162, 32,125,164,  0,230,244,  3,  1,185, 31,160, 18,
 23, 93, 64,210,169,206,128,106, 31, 58, 73,104,114,139, 53,119,
126, 61,133,184, 56, 24, 97,187,236,133, 46, 82,  9,229, 80, 57,
189,120,251, 44,144, 79,248, 11,146, 71, 71,139, 21,140,122,114,
 93, 22, 89, 83,155,106,130,  8,218,226,253,100,250, 60,153,108,
 39,118,149,111, 74, 45, 20,180,249,  7,182,124,  3, 55,244,122,
187, 42, 75, 66, 11,170,233,151, 99,234,  1,116,  9,187,167,115,
 27, 44,184,157,153, 15,110, 57,  4,137,157,172,  8,205, 17,131,
234, 19,185, 66,164,213,201,186,100, 51,203, 11, 93,247,244, 52,
 70,227, 99,213, 94, 58,209, 97, 29, 50, 98, 91, 58,171,164, 17,
210,181, 35,239,161,  3,148,241,  7, 65,206,109, 89, 95,245, 25,
224, 81,193, 73,150, 65,245,178,145,  3,195,202,170, 89,155,173,
227,126,129,236,229,205,198,224,221,252,204,214,254, 42, 23, 49,
 56,210, 54,164,187, 56,149, 15,  8,124, 76, 14,  7, 43, 14, 26,
191, 59, 85, 21,148, 58,187,154,126, 20,243, 96, 46, 62, 66,163,
156,111,104,192, 81,230,184,154,111, 17,211, 58,129,153,127,249,
169, 74,111,165,116,216,107,233,254,115,149,143, 16,117,231,184,
216, 77,172, 27,178, 48,197, 59,124,174,229,102, 59, 11, 37, 95,
220,193,149,223, 27,114, 26, 46, 68,208,230, 76, 33, 80,175,217,
 23,159,230,216,205,131, 84, 73, 96,120,210, 42, 76,185,179,194,
232, 38, 23,176,219,126,252, 56, 25, 96,180,186,  7,221, 54,252,
198,239,103, 76,120, 68,236,252,115, 74, 22,248,240,168,146,134,
 65, 76, 58,208, 50,245,246,190,169, 71,178,253, 90,189, 42,154,
131, 43,203, 26,150, 68,110, 84,213,133,128,184, 97,148,177, 21,
215,124, 19, 87, 32,216, 73,180,228, 71,219,  4,113, 64, 85,111,
189,175,231,155,186, 89,226,219,201, 97, 79, 99,175, 89,137,108,
180,233,236,  6,200,243,122, 10, 72,115,129,185, 26,179,  4, 34,
 50, 13,172, 42, 43,128,184,161, 23,124,161,229, 51, 91, 78, 22,
102, 35, 38, 84, 29,210,144, 23,241,204, 31, 62,133, 62,199, 64,
 72,161, 90, 60,118,158,145,192, 24, 77,  0,203,192,139, 56,121,
214,212,199,117, 22,234,250, 38,164, 27,174,197, 21, 87, 50, 22,
251,127,150,114, 11, 20,195,145,105, 37,206, 18,101,  6,142, 47,
222,121,247, 61,101,230, 59,232, 91,219,201,105,231,136,234, 15,
 18, 22,160, 16,173, 47,163,  8,169,240,221,166,128,135,182,112,
 90,158,216, 26, 96, 87,  9, 72, 82,156,196,126,186,148, 91,255,
114,244, 69,158,186, 70,217, 62, 21,247, 12, 49, 59,220,189, 75,
235,194, 51,110, 85,153,227, 45,189,145,168,166, 94,107,202,232,
216, 63, 31, 56, 18,  7, 35,141,140,232,224,177,111,170,251,167,
207, 32, 82,175,190,104, 89, 57,226,133,169,121, 99, 56,171,192,
  0,212, 20,122, 64, 80, 24, 53, 34, 78,143, 71,180,  5, 52, 91,
192,210, 93,229, 76,242, 52,207,185,212, 19, 82,220,155,221,230,
255,107, 89,206,153, 72, 60,187, 84, 42,187, 69,171,173,208, 26,
217, 63,115,215, 63,116, 43,243,183,  3,226,244,129,199, 14,194,
 53,104,153,  8, 29,169,  8,176,208,202, 75,126, 13, 28, 30,139,
 35, 72,150,104,241, 23,148, 40, 67,101, 85, 49, 36,158,104, 59,
216,215, 30,212,134,178, 68, 86,171,223,200,142,240,  2,180,168,
176,248, 23,111, 30,244, 40,117,162,  4,123,212,247, 78,126,222,
165,153,  8, 45,223,248,163, 85, 97,215,151, 19,222, 85,181, 85,
109,238,205,213, 87, 17, 14, 25
};

int main(int argc, char *argv[])
{
   md5_state_t md5_ctx;
   md5_byte_t digest[16];
   byte tmp[16];
   int i, j;

   memset(rez, 0, 6*26*26);
   memset(check, 0, 26*26);
   for(in[0] = 0; in[0] < 256; in[0]++) {
   for(in[1] = 0; in[1] < 256; in[1]++) {
   for(in[2] = 0; in[2] < 256; in[2]++) {
   for(in[3] = 0; in[3] < 256; in[3]++) {
   for(in[4] = 0; in[4] < 256; in[4]++) {
   for(in[5] = 0; in[5] < 256; in[5]++) {
      memcpy(&tmp[0], in, 6);
      memcpy(&tmp[6], in, 6);
      memcpy(&tmp[12], in, 4);
      for(i = 0; i < 1000; i++) {
         md5_init(&md5_ctx);
         md5_append(&md5_ctx, (const md5_byte_t *)tmp, 16);
         md5_finish(&md5_ctx, digest);
         tmp[0] ^= digest[0];
         tmp[1] ^= digest[1];
         tmp[2] ^= digest[2];
         tmp[3] ^= digest[3];
         tmp[4] ^= digest[4];
         tmp[5] ^= digest[5];
         tmp[6] ^= digest[6];
         tmp[7] ^= digest[7];
         tmp[8] ^= digest[8];
         tmp[9] ^= digest[9];
         tmp[10] ^= digest[10];
         tmp[11] ^= digest[11];
         tmp[12] ^= digest[12];
         tmp[13] ^= digest[13];
         tmp[14] ^= digest[14];
         tmp[15] ^= digest[15];
      }
      for(i = 0; i < 26*26; i++) {
         if(memcmp(&table[i*6], tmp, 6) == 0) {
            if(check[i] == 0) {
               printf(".");
               check[i] = 1;
               memcpy(&rez[i*6], in, 6);
               bool fl = true;
               for(j = 0; j < 26*26; j++) {
                  if(check[j] == 0) {
                     fl = false;
                     break;
                  }
               }
               if(fl) {
                  for(j = 0; j < 6*26*26; j++)
                     printf("%d, ", rez[j]);
                   return 0;
		
               }
            }
         }
	  }
   }}}}}}
   return 0;
}

В подтверждение этой идеи, можно нагенерить валидных пар на основе блэклиста
loqwerty:RY5obY7IwwZaie4S
loasdfg:RY5obY7IdCAOwyLi
lozxcvb:RY5obY7IFOvJr/K/

tuqwerty:RkIomczP8gb638lU
tuasdfg:RkIomczP0VC23ApK
tuzxcvb:RkIomczPlx8yjR0L

Благодарности:

OKOB, Вы помогли мне понять, С П А С И Б О.

Визуализация зависимостей NAME,KEY и хешей. Что из чего извлекается:

Альтернативный вариант генерации таблицы исходной для master_table (не брут-форс):

Попробуем вариант полегче для процессора, без тяжелого брутфорса таблицы исходной для master_table.
Попытаемся угадать, как автор генерирует [I]<B>char needed_table[6*26*26]</B>[/I], ведь он нам дал подсказку, что это возможно назвав кейгенМи “Psychic powers or brute strength your choice”.
Предположим, что он не заморачивался и использовал MSVS CRT ‘rand()’ следующим образом:

srand(unknown_seed);
char  needed_table[6*676];
for (int i = 0; i < 6 * 676; i++) {
  needed_table[i] = rand() & 0xFF;
}

Итак, у нас есть [I]<B>char master_table[6*676]</B>[/I], две валидные пары [I]<B>NAME:KEY</B>[/I] - попробуем перебрать, то что генерирует MSVS CRT ‘rand()’ при разном seed и возможно мы будем счастливчиками. Ниже код перебора:

#include <Windows.h>
#include <stdio.h>
#include <limits.h>

#include "master_table.h"
#include "hashes.h"

UINT32 unknown_seed = -1;
BYTE needed_table[4056];  // table of K_hash_1[0:6] chunks
BYTE lo_K_hash_2[16];
BYTE tu_K_hash_2[16];


int main() {
	UINT16 lo_idx = 6 * (('l' - 0x60) * ('o' - 0x60) - 1);
	UINT16 tu_idx = 6 * (('t' - 0x60) * ('u' - 0x60) - 1);

	UINT16 max_idx = tu_idx + 5;
	do {
		unknown_seed++;    //0x00007a69

		// generate table
		srand(unknown_seed);
		for (SIZE_T i = 0; i <= max_idx; i++)
			needed_table[i] = rand() & 0xFF;

		// calc K_hash_2 of "lo"
		init_K_hash_2(needed_table + lo_idx, lo_K_hash_2);
		for (SIZE_T i = 0; i < 1000; i++)
			MD5_and_XOR(lo_K_hash_2);

		// calc K_hash_2 of "tu"
		init_K_hash_2(needed_table + tu_idx, tu_K_hash_2);
		for (SIZE_T i = 0; i < 1000; i++)
			MD5_and_XOR(tu_K_hash_2);
	} while (
			unknown_seed < UINT_MAX &&
			//master_table[lo_idx:lo_idx+6] ==  lo_K_hash_2[0:6]
			memcmp(master_table + lo_idx, lo_K_hash_2, 6) != 0  && 
			//master_table[tu_idx:tu_idx+6] ==  tu_K_hash_2[0:6]
			memcmp(master_table + tu_idx, tu_K_hash_2, 6) != 0
		);
	if (unknown_seed == UINT_MAX) {
		printf("Your assumption is wrong. Try `rand()` from another library.");
        return 1;
	} else {
		printf("Searched seed: 0x%08x\n", unknown_seed);
	}
	
	return 0;
}

Нам повезло. Соответствующий seed равняется 0x00007a69. Теперь мы можем генерировать ключ для любого имени. Исходники и бинарник кейгена, а также write-up на английском [B]тут[/B]

Примеры валидных [I]<B>NAME:KEY</B>[/I] пар:
bigben:4aWfjhuWTgv6NSM2
impossible:tbxCCxODKA5M7XWB