Всем привет. Название говорит само за себя. Эвент был мало освещен и я лишь каким-то чудом сумел в нем поучаствовать. В результате, успел выхватить одиннадцатое место и получить право на обещанные дивиденды. Перейдем к делу.
Крякми. Или тут (привет из 2к17 если ссылка затерлась)
Инструменты: IDA, HxD, CFF Explorer, DbgView, PEChecksum, KmdManager
Последние три инструмента довольно специфичны, многие крекеры уже поняли в чем вся соль крякми.
После скачивания файла оказалось, что он не имеет расширения. В мою голову начали лезть пакостные мысли про то, что это очередная ctf чушь а-ля найди как меня использовать. Хекс листинг вернул меня в состояние атараксии:
Заветные сигнатуры Марка Збиковски оказались на месте, продолжаем анализ:
Вот это поворот — перед нами драйвер. Смело переименовываем крякми в
Вот так выглядит в драйвере ImageBase:
А вот так и настоящий DriverEntry:
Здесь стоит запомнить имя девайса и обратить внимание на то, что наш драйвер любезно обрабатывает юзермодный
Вот так обработчик выглядит до ручной корректировки:
А вот так после сопоставления с асм листингом:
Что здесь происходит? Функция получает на вход некий буфер (я кст так и не разобрался, как его передать средством
Бывалый крякер пропатчил бы это дело и запустил в релиз, да только нам необходимо найти серийник к нашему мейлу. Готовимся к самому худшему и переходим к заветной функции
Асм листинг ее самого интимного момента:
После валидации полученных параметров она высчитывает хеш от некой строки-константы, хеш от входного
Как выглядит функция(на самом деле не очень). Внутри нее находится еще функции 4, которые что-то делают со входящей строкой: заполняют, копируют, модифицируют и тд.
Стоит вспомнить, что в
Конечно! Онлетит как кама пуля идет ставить бряк после вызова этой функции, тк возвращаемая строка и есть наш серийник (самая большая проблема любого крякми — банальный strcmp). Но тут есть пару но:
Как бы я ни старался, но мой VirtualBox с накатанной сверху xp sp3 отказался принимать Syser/SoftICE/WinDbg. Появилась идея: почему бы не заставить драйвер любезно сообщать нам серийник? Как это можно сделать?
Для начала патчим проверки на валидность входящих данных внутри
Просто затираем их nop`ами.
Затем необходимо вручную заполнить буфер с мылом (он выделяется динамически), делаем это, скажем, в самом начале функции
Стало так:
Те был выпилен динамический подсчет длины мейла и все, что связано с
Теперь пропатчим самый конец функции и вместо исполнения
После патчинга необходимо пересчитать поле CheckSum драйвера — для этого используем утилиту PEChecksum. Затем загружаем драйвер с помощью KmdManager (для загрузки x32 драйвера вы обязаны иметь x32 систему, желательно, xp), открываем DebugView. Далее осталось написать небольшую программу для вызова драйвера:
Компилируем, запускаем:
Первая строка является искомым серийником. На этом прощаюсь.
Крякми. Или тут (привет из 2к17 если ссылка затерлась)
Инструменты: IDA, HxD, CFF Explorer, DbgView, PEChecksum, KmdManager
Последние три инструмента довольно специфичны, многие крекеры уже поняли в чем вся соль крякми.
После скачивания файла оказалось, что он не имеет расширения. В мою голову начали лезть пакостные мысли про то, что это очередная ctf чушь а-ля найди как меня использовать. Хекс листинг вернул меня в состояние атараксии:
Убрано под спойлер![image](https://habrastorage.org/webt/59/dd/06/59dd061b47615723607508.png)
![image](https://habrastorage.org/webt/59/dd/06/59dd061b47615723607508.png)
Заветные сигнатуры Марка Збиковски оказались на месте, продолжаем анализ:
Убрано под спойлер![image](https://habrastorage.org/webt/59/dd/0b/59dd0b89d00c5475178970.png)
![image](https://habrastorage.org/webt/59/dd/0b/59dd0b89d00c5475178970.png)
Вот это поворот — перед нами драйвер. Смело переименовываем крякми в
crackme.sys
. На сей раз в голову пришел вполне обоснованный вопрос: а где лоадер? Где гуй(graphical user interface, не подумайте ничего плохого)? Их нет. Буквально. Считаю это второй по значимости (хе-хе, до первой доберемся еще) нелогичностью крякми: так не бывает. Продолжаем анализ.Вот так выглядит в драйвере ImageBase:
Убрано под спойлер![image](https://habrastorage.org/webt/59/dd/10/59dd1026aadce230842653.png)
![image](https://habrastorage.org/webt/59/dd/10/59dd1026aadce230842653.png)
А вот так и настоящий DriverEntry:
Убрано под спойлер![image](https://habrastorage.org/webt/59/dd/12/59dd12dd2bf8d306613069.png)
![image](https://habrastorage.org/webt/59/dd/12/59dd12dd2bf8d306613069.png)
Здесь стоит запомнить имя девайса и обратить внимание на то, что наш драйвер любезно обрабатывает юзермодный
DeviceIoControl
. Вот так обработчик выглядит до ручной корректировки:
Убрано под спойлер![image](https://habrastorage.org/webt/59/dd/15/59dd159a7e263809259086.png)
![image](https://habrastorage.org/webt/59/dd/15/59dd159a7e263809259086.png)
А вот так после сопоставления с асм листингом:
Убрано под спойлер![image](https://habrastorage.org/webt/59/dd/17/59dd176d52bef045115758.png)
![image](https://habrastorage.org/webt/59/dd/17/59dd176d52bef045115758.png)
Что здесь происходит? Функция получает на вход некий буфер (я кст так и не разобрался, как его передать средством
DeviceIoControl
, пишите в комментарии) и некий контрольный код. Буфер, в зависимости от ControlCode
, копируется в поле мейла или серийника (классная эмуляция гуя, че сказать). После заполнения этих полей мы в третий раз должны послать ControlCode
и в результате запустится некая функция Validate
, на основании которой выведется то или иное сообщение.Бывалый крякер пропатчил бы это дело и запустил в релиз, да только нам необходимо найти серийник к нашему мейлу. Готовимся к самому худшему и переходим к заветной функции
Validate
:Убрано под спойлер![image](https://habrastorage.org/webt/59/dd/20/59dd206252391365832696.png)
![image](https://habrastorage.org/webt/59/dd/20/59dd206252391365832696.png)
Асм листинг ее самого интимного момента:
Убрано под спойлер![image](https://habrastorage.org/webt/59/dd/26/59dd26f369a25547188800.png)
![image](https://habrastorage.org/webt/59/dd/26/59dd26f369a25547188800.png)
После валидации полученных параметров она высчитывает хеш от некой строки-константы, хеш от входного
buf1
(нашего мейла, это очевидно) и общий хеш от этих двух строк.Как выглядит функция
func1
? Страшно и ужасно Стоит вспомнить, что в
func1
мы не передаем ничего, что было бы связано с buf2
(очевидно, это наш серийник). А что делает крякер, когда видит некую хеш функцию от мейла, в которую не передается ничего связанного с серийником, а прямо после этого прелестное сочетание:xor eax, eax
repe cmpsb
setz al
ret
Конечно! Он
- Нам необходимо правильно инициализировать вызов функции
Validate
через серию обращений к драйверу (ну или ручками вызвать + пропатчить память) - Обычный отладчик архетипа «Оля» для ring0 не подходит — необходимо использовать инструменты помощнее
Как бы я ни старался, но мой VirtualBox с накатанной сверху xp sp3 отказался принимать Syser/SoftICE/WinDbg. Появилась идея: почему бы не заставить драйвер любезно сообщать нам серийник? Как это можно сделать?
Для начала патчим проверки на валидность входящих данных внутри
Validate
:Убрано под спойлер![image](https://habrastorage.org/webt/59/de/50/59de508ddca8b166539644.png)
![image](https://habrastorage.org/webt/59/de/50/59de508ddca8b166539644.png)
Просто затираем их nop`ами.
Затем необходимо вручную заполнить буфер с мылом (он выделяется динамически), делаем это, скажем, в самом начале функции
Validate
. Было так:Убрано под спойлер![image](https://habrastorage.org/webt/59/de/53/59de535a35d39719494233.png)
![image](https://habrastorage.org/webt/59/de/53/59de535a35d39719494233.png)
Стало так:
Убрано под спойлер![image](https://habrastorage.org/webt/59/de/55/59de551feb29c814918402.png)
![image](https://habrastorage.org/webt/59/de/55/59de551feb29c814918402.png)
Те был выпилен динамический подсчет длины мейла и все, что связано с
buf2
. Теперь пропатчим самый конец функции и вместо исполнения
repe cmpsb
впихнем вызов DbgPrint
:Убрано под спойлер![image](https://habrastorage.org/webt/59/df/88/59df88af7b945511220895.png)
![image](https://habrastorage.org/webt/59/df/88/59df88af7b945511220895.png)
После патчинга необходимо пересчитать поле CheckSum драйвера — для этого используем утилиту PEChecksum. Затем загружаем драйвер с помощью KmdManager (для загрузки x32 драйвера вы обязаны иметь x32 систему, желательно, xp), открываем DebugView. Далее осталось написать небольшую программу для вызова драйвера:
char tmp[0x100];
HANDLE handle = CreateFile(L"\\\\.\\crackme", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
DeviceIoControl(handle, 0x222408, 0, 0, &tmp, 0x100, &tmp, 0);
CloseHandle(handle);
Компилируем, запускаем:
Убрано под спойлер![image](https://habrastorage.org/webt/59/de/5e/59de5e486baed602792597.png)
![image](https://habrastorage.org/webt/59/de/5e/59de5e486baed602792597.png)
Первая строка является искомым серийником. На этом прощаюсь.
NOTE: Решение опубликовал сразу после того, как задание выполнили первые пятнадцать участников конкурса. Необходимо уважать честную конкуренцию.
Комментарии (5)
fryday
14.10.2017 16:53Очень сложно =)
Как решал я:
1) Находим в хэш функции константы
2) Гуглим. Узнаем, что это md5
3)Заголовок спойлераserial = md5(md5(email) || md5(const_str))
REPISOT
Что такое врайтап? Имелось в виду write-up? там нет буквы «В» (Write брит. |r??t|)
Тут недавно была статья с подборкой ресурсов для изучения английского. Вам бы не помешало.
unc1e Автор
Наверняка вы правы, спасибо