Недавно мне на глаза попался один довольно интересный crackme. В нем нет антиотладочных приемов или обфускации кода, тем не менее решать его очень интересно: тут и дешифровка строк, и финты с картинками. В этой статье я по шагам покажу, что бы я делал, чтобы найти разгадку.

INFO

Автор статьи выражает благодарность hasherezade, автору crackme (пароль crackme).

По правилам нам нужно найти ключи и секретный флаг, а не просто поломать механизмы валидации, чтобы crackme думал, что он решен. Из инструментария нам понадобится: IDA, DiE и PuTTY. Начнем с DiE.

Crackme в DiE
Crackme в DiE

Энтропия в норме, файл ничем не упакован. Это вполне ожидаемо: накрывать кракми известными навесными упаковщиками — признак плохого тона. Поставить такую защиту может кто угодно, а ее снятие — это рутина, а не решение загадки. Давай запустим кракми и посмотрим, как он работает, что выводит на экран, как реагирует на ввод неправильного пароля.

Crackme
Crackme

При загрузке мы видим цветные строчки и забавного кролика. На ввод неправильного пароля программа пишет строчку «Nope!» и закрывается. Загрузим крякмис в дизассемблер IDA и посмотрим на начало программы, строки и структуру кода.

White Rabbit в IDA
White Rabbit в IDA

Начальный код очень прост, и у нас есть два пути его анализа: поискать перекрестные ссылки на сообщения о вводе пароля (по-крякерски!) или начать его исследовать с самого начала. Давай пойдем по второму пути — в этом конкретном случае так будет интереснее. Кроме того, обратим внимание на структуру кода: распознанных исполняемых инструкций не так много. И нельзя не заметить размер файла — больше шести мегабайт!

Запомним это все и начинаем исследовать код. Видим несколько вызовов и подпрограмму loc_403CDE.

loc_403CDE:
  push    offset aNope    ; "Nope!\n"
  push    0C0h            ; wAttributes
  call    sub_403990
  add     esp, 8
  push    3E8h            ; dwMilliseconds
  call    ds:Sleep
  or      eax, 0FFFFFFFFh
  retn

Судя по всему, этот код выполняется при неверном вводе пароля: выводится сообщение «Nope!» и программа завершается. Давай переименуем эту подпрограмму в exit_err, чтобы было понятнее, что это завершение программы после некорректного ввода данных.

Итак, первый вызов — это call sub_402CC0. Заходим в него и разбираемся.

Отрисовка строк в консоли
Отрисовка строк в консоли

Вызываются функции работы с атрибутами текста в консоли, кроме того, мы видим буфер текста «Wake up, Neo… I have a challenge for…». Очевидно, этот call отвечает за начальный баннер кракми. Переименуем call sub_402CC0 в call banner, чтобы нам было легче читать код в дальнейшем.

Движемся дальше по коду. После вызова загрузочного баннера у нас идет call sub_4034D0. Заходим в него — беглый осмотр показывает, что это один из уровней крякмиса. Об этом нам говорят следующие строки кода:

push    offset aPassword1 ; "Password#1:\n"
...
push    offset aSoFarSoGood ; "So far, so good!\n"

Это данные, которые передаются функции вывода на экран. С уверенностью переименовываем call sub_4034D0 в call level_1 и начинаем исследовать уровень более детально. После стандартного пролога и механизма защиты от переполнения буфера стека мы видим интересный код:

lea     eax, [ebp+nNumberOfBytesToWrite]
push    65h             ; hResData (101)
push    eax             ; int
mov     [ebp+nNumberOfBytesToWrite], 0
call    sub_403D90

Давай перейдем в call sub_403D90 и посмотрим, что там. А там находится несложный код работы с ресурсами. Наблюдается обилие вызовов FindResourceA, LoadResource, LockResource, SizeofResource. Дальше все это завершается кодом выделения памяти и копирования данных:

mov     esi, [ebp+arg_0]
push    4               ; flProtect
push    3000h           ; flAllocationType
push    eax             ; dwSize
push    0               ; lpAddress
mov     [esi], eax
call    ds:VirtualAlloc
push    dword ptr [esi] ; size_t
mov     edi, eax
push    ebx             ; void *
push    edi             ; void *
call    _memmove_0

Становится понятно, что sub_403D90 читает ресурс нашего кракми и копирует его в выделенный буфер в памяти. Переименуем sub_403D90 в load_res_in_buf и остановимся на этом подробнее.

Код push 65h говорит нам о ресурсе 101. Давай вернемся в DiE и посмотрим на ресурсы. Для этого жмем кнопочку Resource и в открывшемся окне раскроем список под названием RT_RCDATA. Видим два ресурса, из которых нас интересует 101.

Продолжение доступно только подписчикам

Вариант 1. Оформи подписку на «Хакер», чтобы читать все материалы на сайте

Подписка позволит тебе в течение указанного срока читать ВСЕ платные материалы сайта. Мы принимаем оплату банковскими картами, электронными деньгами и переводами со счетов мобильных операторов. Подробнее о подписке

Вариант 2. Купи один материал

Заинтересовала информация, но нет возможности оплатить подписку? Тогда этот вариант для тебя! Обрати внимание: этот способ покупки доступен только для материалов, опубликованных более двух месяцев назад.


2 комментария

  1. robotobor

    28.09.2018 at 10:26

  2. keeper-volok

    28.09.2018 at 12:57

    Занимательный крякми, спасибо )

Оставить мнение

Check Also

Энкодеры msfvenom. Разбираемся с кодированием боевой нагрузки при бинарной эксплуатации

Генерация полезной нагрузки — неотъемлемая часть эксплуатации. При использовании модулей M…