Следующая новость
Предыдущая новость

Потрошим Carbanak. Как изнутри устроен известный банковский троян

06.08.2019 16:03
Потрошим Carbanak. Как изнутри устроен известный банковский троян

Банковские трояны, ворующие деньги со счетов компаний и простых пользователей, ежегодно наносят ущерб на миллионы долларов. Естественно, вирмейкеры стараются держать все, что связано с внутренней кухней банкеров, в глубочайшей тайне. Именно поэтому мы никак не могли упустить уникальное событие — попадание исходников банковского троя Carbanak в паблик — и принялись исследовать его устройство изнутри. Результатами этих изысканий мы сегодня щедро поделимся с тобой.

Хакер уже писал об утечке в публичный доступ исходных кодов банковской малвари Carbanak. Надо сказать, что эта малварь сейчас все еще активна и развивается, несмотря на аресты, а украденные суммы давно перевалили за миллиард долларов. Все любопытствующие могут ознакомиться с исходным кодом этого творения на GitHub. Лично я рекомендую сохранить этот код (для академических исследований, естественно), а то всякое может случиться. Итак, давай заглянем внутрь Carbanak.

Структура проекта Carbanak

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

Для начала мне стало интересно, как Carbanak общается с WinAPI и каким образом вызывает нужные ему функции. Чтобы увидеть этот механизм, необходимо заглянуть в следующие файлы:

coresourcewinapi.cpp coreincludecorewinapi.h coreincludecoreapi_funcs_type.h coreincludecoreapi_funcs_hash.h 

Бросается в глаза код получения структуры процессов PEB, настроенный на условную компиляцию в зависимости от архитектуры системы:

PPEB GetPEB() { #ifdef _WIN64     return  (PPEB)__readgsqword(0x60); #else     PPEB PEB;     __asm     {         mov eax, FS:[0x30]         mov [PEB], eax     }     return PEB; #endif } 

Там же представлен список нужных DLL, где хранятся WinAPI (это только часть используемых трояном библиотек):

const char* namesDll[] =  {     _CT_("kernel32.dll"), // KERNEL32 = 0     _CT_("user32.dll"), // USER32 = 1     _CT_("ntdll.dll"), // NTDLL = 2     _CT_("shlwapi.dll"), // SHLWAPI = 3     _CT_("iphlpapi.dll"), // IPHLPAPI = 4     _CT_("urlmon.dll"), // URLMON = 5  ..... 

Обрати внимание на макросы _CT_ — они шифруют строки. Ты ведь не думал, что в малвари подобного уровня текстовые строки будут храниться в открытом виде? Кроме того, в блоке инициализации этого модуля мы видим код, динамически получающий функции GetProcAddress и LoadLibraryA по их хешу:

    HMODULE kernel32;     if ( (kernel32 = GetDllBase(hashKernel32)) == NULL )         return false;     _GetProcAddress = (typeGetProcAddress)GetApiAddr( kernel32, hashGetProcAddress );     _LoadLibraryA = (typeLoadLibraryA)GetApiAddr( kernel32, hashLoadLibraryA );     if ( (_GetProcAddress == NULL) || (_LoadLibraryA == NULL) ) 

Далее троян выполняет поиск и сравнение с таблицей хешей искомых функций. Вот, например, часть кода, с помощью которой Carbanak определяет, найдена нужная функция или нет:

for( uint i = 0; i < exportDir->NumberOfNames; i++)     {         char* name = (char*)RVATOVA( module, *namesTable );         if( Str::Hash(name) == hashFunc )         {             ordinal = *ordinalTable;             break;     }         // Следующая функция         namesTable++;         ordinalTable++;     } 

На самом деле перед нами классический движок для поиска WinAPI по их хешу, о котором мы уже говорили в отдельной статье.

Кроме всего прочего, меня привлек кусок кода, в комментариях к которому было написано «антиэмуляционная защита от КАВа». Такой код встречается в нескольких местах этого проекта:

// Антиэмуляционная защита от КАВа  char path2[MAX_PATH];       // Символьный массив API(KERNEL32, GetTempPathA)( MAX_PATH, path2 );     // Получаем в него путь до папки временных файлов API(KERNEL32, CreateFileA)( path2, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0 );   // OPEN_EXISTING — открыть файл if( API(KERNEL32, GetLastError)() == 3 )        // ERROR_PATH_NOT_FOUND 

Суть этого приема заключается в том, что эмуляторы антивирусных решений не всегда могут корректно воспроизвести поведение окружения, в котором выполняется приложение. В данном случае троян сначала вызывает функцию GetTempPathA, позволяющую получить путь до папки временных файлов (temp), а затем пытается запустить несуществующий файл из нее. Если после этих действий ОС вернет ошибку ERROR_PATH_NOT_FOUND (обычная ошибка при выполнении приложения в реальной системе), малварь приходит к выводу, что исполнение кода не эмулируется средствами антивируса, и управление передается дальше.

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

Материалы из последних выпусков становятся доступны по отдельности только через два месяца после публикации. Чтобы продолжить чтение, необходимо стать участником сообщества «Xakep.ru».

Присоединяйся к сообществу «Xakep.ru»!

Членство в сообществе в течение указанного срока откроет тебе доступ ко ВСЕМ материалам «Хакера», увеличит личную накопительную скидку и позволит накапливать профессиональный рейтинг Xakep Score! Подробнее

1 год

7690 р.

1 месяц

720 р.

Я уже участник «Xakep.ru»

Источник

Последние новости