Всем привет. Название говорит само за себя. Эвент был мало освещен и я лишь каким-то чудом сумел в нем поучаствовать. В результате, успел выхватить одиннадцатое место и получить право на обещанные дивиденды. Перейдем к делу.
Крякми. Или тут (привет из 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 чушь а-ля найди как меня использовать. Хекс листинг вернул меня в состояние атараксии:
Убрано под спойлер
Заветные сигнатуры Марка Збиковски оказались на месте, продолжаем анализ:
Убрано под спойлер
Вот это поворот — перед нами драйвер. Смело переименовываем крякми в
crackme.sys
. На сей раз в голову пришел вполне обоснованный вопрос: а где лоадер? Где гуй(graphical user interface, не подумайте ничего плохого)? Их нет. Буквально. Считаю это второй по значимости (хе-хе, до первой доберемся еще) нелогичностью крякми: так не бывает. Продолжаем анализ.Вот так выглядит в драйвере ImageBase:
Убрано под спойлер
А вот так и настоящий DriverEntry:
Убрано под спойлер
Здесь стоит запомнить имя девайса и обратить внимание на то, что наш драйвер любезно обрабатывает юзермодный
DeviceIoControl
. Вот так обработчик выглядит до ручной корректировки:
Убрано под спойлер
А вот так после сопоставления с асм листингом:
Убрано под спойлер
Что здесь происходит? Функция получает на вход некий буфер (я кст так и не разобрался, как его передать средством
DeviceIoControl
, пишите в комментарии) и некий контрольный код. Буфер, в зависимости от ControlCode
, копируется в поле мейла или серийника (классная эмуляция гуя, че сказать). После заполнения этих полей мы в третий раз должны послать ControlCode
и в результате запустится некая функция Validate
, на основании которой выведется то или иное сообщение.Бывалый крякер пропатчил бы это дело и запустил в релиз, да только нам необходимо найти серийник к нашему мейлу. Готовимся к самому худшему и переходим к заветной функции
Validate
:Убрано под спойлер
Асм листинг ее самого интимного момента:
Убрано под спойлер
После валидации полученных параметров она высчитывает хеш от некой строки-константы, хеш от входного
buf1
(нашего мейла, это очевидно) и общий хеш от этих двух строк.Как выглядит функция
func1
? Страшно и ужасно Стоит вспомнить, что в
func1
мы не передаем ничего, что было бы связано с buf2
(очевидно, это наш серийник). А что делает крякер, когда видит некую хеш функцию от мейла, в которую не передается ничего связанного с серийником, а прямо после этого прелестное сочетание:xor eax, eax
repe cmpsb
setz al
ret
Конечно! Он
- Нам необходимо правильно инициализировать вызов функции
Validate
через серию обращений к драйверу (ну или ручками вызвать + пропатчить память) - Обычный отладчик архетипа «Оля» для ring0 не подходит — необходимо использовать инструменты помощнее
Как бы я ни старался, но мой VirtualBox с накатанной сверху xp sp3 отказался принимать Syser/SoftICE/WinDbg. Появилась идея: почему бы не заставить драйвер любезно сообщать нам серийник? Как это можно сделать?
Для начала патчим проверки на валидность входящих данных внутри
Validate
:Убрано под спойлер
Просто затираем их nop`ами.
Затем необходимо вручную заполнить буфер с мылом (он выделяется динамически), делаем это, скажем, в самом начале функции
Validate
. Было так:Убрано под спойлер
Стало так:
Убрано под спойлер
Те был выпилен динамический подсчет длины мейла и все, что связано с
buf2
. Теперь пропатчим самый конец функции и вместо исполнения
repe cmpsb
впихнем вызов DbgPrint
:Убрано под спойлер
После патчинга необходимо пересчитать поле 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);
Компилируем, запускаем:
Убрано под спойлер
Первая строка является искомым серийником. На этом прощаюсь.
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 Автор
Наверняка вы правы, спасибо