Yet another kaspersky crackme

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

SHADOW
В описании к заданию написано:

«Ollydbg не спасет Вас, исследователи! Игра будет вестись в темных уголках ядра операционной системы. Хватит ли Вам смелости узнать потаенные места виртуальной реальности? Shadow ждет вас, найдите его!»

Намек ясен. Делаем пару прогонов анализаторами нашего образца:

Убрано под спойлер
4-yqerw4ry4l2-oixzvzc8pcsak.png


Оке, все чисто. Cмотрим импорт:

Убрано под спойлер
cebquxqdnyvk6fmobbrxtcwek6w.png


На данном этапе, не копая дизасм листинг (он кст небольшой, см смещение 00402310), можно понять логику работы приложения:

  1. Подгружается драйвер (CreateService)
  2. Ему передаются некие параметры (DeviceIoControl)
  3. Драйвер что-то делает
  4. ???


Очевидно, нам необходимо выцепить драйвер. Загружаем r3 отладчик архетипа «Оля», ставим бряк на CreateServiceA, DeviceIoControl и клацаем F9 (антиотладка отсутствует). Сразу же срабатывает точка останова на CreateServiceA, вот так выглядит стек:

Убрано под спойлер
xe5pyqc5refrljbt8thzalstozw.png


Замечаем путь к нашему драйверу, копируем его куда-нибудь. Клацаем F9, ловим еще одну остановку на этой же функции:

Убрано под спойлер
ybblp_zl-fav6arsdgvb_lcifxu.png


Вам может показаться, что это один и тот же драйвер, однако присмотритесь внимательнее: названия чуть-чуть отличаются. Его тоже сохраним. Клацаем F9, перед нами появляется консолька с просьбой ввести некие данные:

Убрано под спойлер
tyqosxijzg5b2epqrwyjixjvb0g.png


Вводим рандом, отправляем. Сразу же срабатывает бряк на DeviceIoControl:

Убрано под спойлер
j97udfvra9m1usg7nzeq_6t7i2m.png


Здесь мы можем лицезреть нашу связку меил : сериал, которая передается третьим и пятым параметром соответственно. Четвертый и шестой аргумент — размер буферов (с учетом нуля). Трассируем в отладчике до ret, затем еще до одного. В результате увидим такую картину:

Убрано под спойлер
hxetndw__ygt3hbjev6jreuqxku.png


Иными словами, если DeviceIoControl вернул ненулевое значение — крякми решен. Что ж, перейдем к изучению первого драйвера. DriverEntry:

Убрано под спойлер
jzkg2typfi3advykllgxa4djqjo.png


Обработчик DeviceIoControl:

Убрано под спойлер
rjcan00xsc6k4jd8vjr5qaeqzb4.png


Заветная Validate:

Убрано под спойлер
sxualejtfl6a_j9gheivwk9vyck.png


Обратить эту функцию не составит труда. Однако давайте вспомним, что у нас существует и второй драйвер, про который мы пока ничего не знаем. Его DriverEntry:

Убрано под спойлер
gk5wi06unv4s5ocux0mckuvkz34.png


Интересное кино! Выглядит как самый настоящий драйвер-фильтр. Глянем обработчик:

Убрано под спойлер
myt3cu4ntgcslgk3mtxxlvdp_em.png


Что мы здесь видим:

  1. Функция ValidateStr отвечает за дополнительную валидацию наших первичных данных: допускаются только символы A…Z + a…z + 0…9 + '.' + '@'. Я бы оторвал руки человеку, который добавил такую проверку — лично мой меил не проходит ее, в нем содержится символ '-'
  2. Функция ModifyMail изменяет наш меил следующим образом:
    Убрано под спойлер
    hbg3npkzwqnvkt8yabimfsrw0em.png
  3. IofCallDriver передает управление основному драйверу с уже измененными данными


Таким образом, учтя все проверки, можно набросать что-то типа этого:

Убрано под спойлер
#include "main.h"

char mail[257];
char hashes[32][33];

void main()
{
	for (;;)
	{
		printf_s("Enter your name (1 chars min and 256 chars max, only A..Z + a..z + '.' + '@'):\n");
		fgets(mail, 257, stdin);

		int ln = strlen(mail) - 1;
		if (mail[ln] == '\n')
			mail[ln] = '\x00';
		else ln++;

		if (ln < 1)
			continue;

		for (int i = 0; i < ln; i++)
		{
			if ((mail[i] < '0' || mail[i] > '9') && mail[i] != '.' && mail[i] != '@')
			{
				if (i & 1)
					mail[i] &= 0xDF;
				else
					mail[i] |= 0x20;
			}
		} //change chars case

		GetMD5(mail, ln, mail);

		for (int i = 0; i < 32; i++)
		{
			if (mail[i] < '0' || mail[i] > '9')
			{
				mail[i] &= 0xDF;
				GetMD5(mail, 32, hashes[i]);
				mail[i] |= 0x20;
			}
			else
				GetMD5(mail, 32, hashes[i]);
		}

		for (int i = 0; i < 32; i++)
			mail[i] = hashes[i][i];

		printf("%s\n", mail);	
	}
}


Функция GetMD5 самая стандартная, взятая отсюда. Компилируем, запускаем:

Убрано под спойлер
urij1amuggj2vv4wnwby7jjhj7e.png


Solved. На этом прощаюсь.

© Habrahabr.ru