Чтобы испытать новое средство для реверса, созданное в стенах АНБ США, я решил поломать замечательную и несложную крэкми MalwareTech. Выбрал ее неслучайно. В одной из своих статей я рассказывал о том, как устроена виртуализация кода, и мы даже написали простенькую виртуалку. А теперь давай посмотрим, как ломать такую защиту.

Скачать крэкми можно с сайта MalwareTech, пароль к архиву — тоже MalwareTech.

Итак, для начала посмотрим, что в архиве. Видим исполняемый файл vm1.exe и файл дампа ram.bin. В пояснении на сайте написано, что мы имеем дело с восьмибитной виртуальной машиной. Файл дампа — не что иное, как кусок памяти, в котором вперемешку расположены рандомные данные и флаг, который мы должны найти. Оставим пока в покое файл дампа и посмотрим на vm1.exe через программу DiE.

Крэкми в анализаторе Detect It Easy
Крэкми в анализаторе Detect It Easy

DiE не показывает ничего интересного, с энтропией все в порядке. Значит, никакой навесной защиты нет, но проверить все равно стоило. Давай загрузим этот файл в Ghidra и посмотрим, что она выдаст. Я приведу полный листинг приложения без функций (он совсем небольшой) — чтобы ты понял, с чем мы имеем дело.

PUSH   EBP
MOV    EBP ,ESP
SUB    ESP ,0x94
LEA    ECX =>local_94 ,[0xffffff70  + EBP ]
CALL   MD5::MD5
PUSH   0x1fb
PUSH   0x0
CALL   dword ptr [->KERNEL32.DLL::GetProcessHeap ]
PUSH   EAX
CALL   dword ptr [->KERNEL32.DLL::HeapAlloc ]
MOV    [DAT_0040423c ],EAX
PUSH   0x1fb
PUSH   DAT_00404040
MOV    EAX ,[DAT_0040423c ]
PUSH   EAX
CALL   memcpy
ADD    ESP ,0xc
CALL   FUN_004022e0
MOV    ECX ,dword ptr [DAT_0040423c ]
PUSH   ECX
LEA    ECX =>local_94 ,[0xffffff70  + EBP ]
CALL   MD5::digestString
MOV    dword ptr [local_98  + EBP ],EAX
PUSH   0x30
PUSH   s_We've_been_compromised!_0040302c
MOV    EDX ,dword ptr [local_98  + EBP ]
PUSH   EDX
PUSH   0x0
CALL   dword ptr [->USER32.DLL::MessageBoxA ]
PUSH   0x0
CALL   dword ptr [->KERNEL32.DLL::ExitProcess ]
XOR    EAX ,EAX
MOV    ESP ,EBP
POP    EBP
RET

Как видишь, код простой и легко читается. Давай воспользуемся декомпилятором Ghidra и посмотрим, что он выдаст.

undefined4 entry(void)
{
HANDLE hHeap;
char *lpText;
DWORD dwFlags;
SIZE_T dwBytes;
MD5 local_94 [144];

MD5(local_94);

dwBytes = 0x1fb;
dwFlags = 0;

hHeap = GetProcessHeap();
DAT_0040423c = (char *)HeapAlloc(hHeap,dwFlags,dwBytes);
memcpy(DAT_0040423c,&DAT_00404040,0x1fb);

FUN_004022e0();

lpText = digestString(local_94,DAT_0040423c);
MessageBoxA((HWND)0x0,lpText,"We\'ve been compromised!",0x30);

ExitProcess(0);
return 0;
}

Я добавил отступы для удобочитаемости — отделил объявления переменных от остального кода. Код весьма простой: сначала выделяется память в куче (GetProcessHeapHeapAlloc), далее в нее копируется 0x1fb(507) байт из DAT_00404040. Но у нас нет ничего интересного в 00404040! Вспоминаем, что в инструкции к крэкми говорилось, что ram.bin — это кусок памяти. Разумеется, если посмотреть размер файла, он оказывается равным 507 байт.

Загружаем ram.bin в HxD или любой другой шестнадцатеричный редактор и смотрим.

Файл ram.bin в HxD Hex Editor
Файл ram.bin в HxD Hex Editor

Увы, ничего внятного там не обнаруживаем. Но логика работы немного проясняется: DAT_0040423c — это ram.bin (наши выделенные 507 байт в куче). Давай переименуем DAT_0040423c в RAM, чтобы было удобнее ориентироваться в коде. Далее заходим в функцию FUN_004022e0.

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

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

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

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

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


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

  1. Аватар

    0ri0n

    22.03.2019 at 10:21

    Хорошо но мало!

    Вопрос к Экспертам. У гидры есть скрипты встроенные скрипты, каковых их задачи что они решают?

    • Аватар

      s00mbre

      03.04.2019 at 00:38

      Похоже, что скриптами (Java) можно делать все, что и вручную, это макросы для Гидры. Для написания скрипта необходимо унаследовать свой класс от GhidraScript, пример (пишет строку «Hello world» в консоли Гидры):
      public class HelloWorldScript extends GhidraScript {
      public void run() throws Exception {
      println(«Hello World!»);
      }
      }
      Подробнее тут: http://ghidra.re/ghidra_docs/api/ghidra/app/script/GhidraScript.html
      А вот полный онлайн курс по скриптингу в Гидре: http://ghidra.re/courses/GhidraClass/Intermediate/Scripting_withNotes.html#Scripting.html

    • Аватар

      s00mbre

      03.04.2019 at 00:45

      Еще лучше просто открыть Script Manager в Гидре и посмотреть коллекцию скриптов. По двойному клику скрипт выполняется (как в MS Office), а в контекстном меню можно выбрать |Edit with basic editor, и код откроется во встроенном редакторе тут же.

  2. Аватар

    s00mbre

    05.04.2019 at 05:46

    Мое первое видео — пример crackme в Гидре:
    https://www.youtube.com/watch?v=Lu3O6ikXMm4

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

Check Also

Миллионы серверов Exim находятся под атаками из-за свежей уязвимости

Более половины всех почтовых серверов в интернете находятся под угрозой: злоумышленники уж…