Техника Process Doppelgänging (создание двойников процессов) была впервые представлена в декабре 2017 года на конференции BlackHat. С тех пор некоторые киберпреступники перешли на этот продвинутый метод, чтобы обходить современные антивирусные решения.
В апреле 2018 года нам впервые встретилась программа-вымогатель, которая избегает обнаружения, используя эту технику — SynAck. Стоит отметить, что SynAck — далеко не новый вымогатель, о его существовании известно еще с сентября 2017 года. Но наше внимание привлек свежий образец этой вредоносной программы, полагавшийся на Process Doppelgänging. Ниже мы представляем результаты нашего исследования этой новой разновидности SynAck.
Методы противодействия анализу и обнаружению
Process Doppelgänging
SynAck применяет технику, чтобы обходить современные средства защиты. Суть техники состоит в запуске вредоносного процесса из файла, участвующего в NTFS-транзакции, чтобы выдать этот процесс за легитимный.
Фрагмент процедуры, реализующей Process Doppelgänging
Обфускация исполняемого файла
Чтобы усложнить анализ вредоносной программы и защитить оригинальный код в исполняемом файле троянца, авторы вредоносных программ часто применяют самописные упаковщики файлов PE. Действия большинства таких упаковщиков можно без особых усилий обратить, чтобы получить пригодный для анализа оригинальный неизмененный PE-файл троянца.
В случае с SynAck все оказалось не так просто. Злоумышленники не упаковывали исполняемый файл троянца, вместо этого они провели изощренную обфускацию кода перед его компиляцией. В результате задача обратной разработки кода SynAck значительно усложнилась по сравнению с другими новыми разновидностями программ-вымогателей.
Логика передачи управления в этой троянской программе крайне запутана. Большинство вызовов (CALL) непрямые, а адреса назначения вычисляются посредством арифметической операции с двумя константами типа DWORD.
Все адреса функций WinAPI импортируются динамически на основе хэшей названий экспортируемых функций системных библиотек DLL. Сама по себе эта техника не нова и не особо усложняет анализ. Но авторы SynAck пошли еще дальше и замаскировали как адрес процедуры, извлекающей адрес функции API, так и целевое значение хэша.
Давайте подробнее рассмотрим, как SynAck обращается к функциям WinAPI. Возьмем, к примеру, следующий участок дизассемблированного кода:
Этот код берет значение DWORD по адресу 403b13, вычитает из него константу 78f5ec4d, получает результат 403ad0 и вызывает процедуру по этому адресу.
Данная процедура помещает две константы (N1 = ffffffff877bbca1 и N2 = 2f399204) в стек и переходит к исполнению процедуры по адресу 403680, чтобы вычислить результат операции N1 xor N2, равный a8422ea5.
Это значение представляет собой хэш функции API, которую хочет вызвать SynAck. Затем процедура 403680 находит адрес этой функции: она анализирует таблицы экспорта системных библиотек DLL, вычисляет хэш названия каждой функции и сравнивает его со значением a8422ea5. Обнаружив адрес функции API, SynAck переходит к исполнению кода по этому адресу.
Обратите внимание, что вместо простого вызова CALL применяется сочетание инструкций PUSH и RET, чтобы еще больше усложнить анализ. Авторы SynAck задействуют разные комбинации инструкций вместо CALL для вызова функций WinAPI:
push reg
retn- jmp reg
mov [rsp-var], reg
jmp qword ptr [rsp-var]
Деобфускация кода
В ответ на попытки маскировки, предпринятые разработчиками SynAck, мы разработали скрипт IDAPython, который автоматически анализирует код, извлекает все адреса промежуточных процедур и константы, а также вычисляет хэши названий функций WinAPI, которые хочет импортировать вредоносная программа.
Затем мы рассчитали хэши названий функций, экспортированных из системных DLL-библиотек Windows, и сравнили их со значениями, найденными в SynAck. В результате мы получили список со значениями хэшей и соответствующими им функциями API.
Часть списка функций API, импортированных SynAck, и их хэши
В дальнейшем наш скрипт, руководствуясь этим списком, сохраняет комментарии в базе данных IDA, помечая, какие функции API будет вызывать троянец. Так выглядит код из примера выше после деобфускации.
Экран дизассемблера — обратите внимание на комментарий с названием целевой функции API
Экран декомпиляции Hex-Rays — здесь тоже распознаны названия функций API
Языковая проверка
На ранних этапах выполнения троянец проверяет, находится ли зараженный компьютер в странах из заданного списка. Для этого он считывает список всех установленных клавиатурных раскладок на компьютере жертвы и сверяет его с жестко прописанным в теле вредоносной программы списком. Если SynAck находит совпадение, он приостанавливает свой процесс на 300 секунд, а затем вызывает функцию ExitProcess, чтобы предотвратить шифрование файлов жертвы.
Фрагмент процедуры, останавливающей работу троянца после языковой проверки
Фрагмент процедуры, проверяющей раскладки клавиатуры на зараженном компьютере
Проверка названия каталога
Вслед за языковой проверкой, которая встречается сравнительно часто в современных программах-вымогателях, SynAck узнает, из какого каталога был вызван его исполняемый файл. Если он запущен из «неправильной» папки, троянец просто завершит работу. Такая мера должна предотвратить автоматический анализ в песочнице.
Как и в случае с импортированными функциями API, троянец не содержит проверяемые строки, вместо этого он хранит их хэши, чтобы исключить нахождение исходных строк.
Тело SynAck включает девять хэшей; нам удалось подобрать два из них:
0x05f9053d == hash("output")
0x2cd2f8e2 == hash("plugins")
В процессе мы натолкнулись на множество коллизий — бессмысленных строк с таким же хэшем, как искомые осмысленные строки.
Криптографическая схема
Как и в других программах-вымогателях, в SynAck применяется сочетание симметричных и асимметричных алгоритмов шифрования. В основе алгоритма SynAck лежит гибридная схема ECIES. Ее элементами являются симметричный алгоритм шифрования (ENC), функция формирования ключа (KDF) и код аутентификации сообщения (MAC). Эти элементы взаимодействуют друг с другом и могут быть реализованы разными способами. В данной схеме, чтобы рассчитать ключ симметричного алгоритма ENC, используется протокол Диффи — Хеллмана на эллиптической кривой (ECDH).
Разработчики SynAck остановились на следующей реализации:
ENC: XOR
KDF: PBKDF2-SHA1 с одной итерацией
MAC: HMAC-SHA1
Кривая ECDH: secp192r1 (стандартная эллиптическая кривая NIST)
ECIES-XOR-HMAC-SHA1
Эта функция реализует схему ECIES в образце SynAck.
Входные данные: plaintext, input_public_key
Выходные данне: ciphertext, ecies_public_key, MAC
-
-
- Троянец генерирует пару асимметричных ключей: ecies_private_key и ecies_public_key;
- На основе созданного закрытого ключа ecies_private_key и открытого ключа input_public_key троянец вычисляет общий секрет согласно протоколу Диффи — Хеллмана на эллиптической кривой:
ecies_shared_secret = ECDH(ecies_private_key, input_public_key)
- Воспользовавшись функцией PBKDF2-SHA1 с одной итерацией, троянец получает два байтовых массива, key_enc и key_mac, из общего секрета;
- Исходный текст plaintext побайтово совмещается операцией XOR с массивом key_enc.
- SynAck вычисляет MAC (код аутентификации сообщения) для полученного шифротекста с помощью алгоритма HMAC-SHA1 и ключа key_mac.
-
Инициализация
На первом этапе троянец генерирует пару ключей: закрытый ключ (session_private_key) представляет собой случайное 192-разрядное значение, а открытый ключ (session_public_key) является точкой на стандартной эллиптической кривой NIST secp192r1.
Затем троянец собирает уникальные сведения о компьютере — название компьютера, имя пользователя, версию ОС, уникальный ИД заражения, закрытый ключ сессии и некие произвольные данные, — после чего зашифровывает их случайным 256-разрядным ключом AES. Зашифрованные данные сохраняются в виде буфера encrypted_unique_data.
SynAck шифрует ключ AES с помощью функции ECIES-XOR-HMAC-SHA1 (см. описание выше; далее упоминается как функция ECIES): ключ AES передается как параметр plaintext, а жестко прописанный киберпреступниками ключ master_public_key — как input_public_key.
На следующем этапе троянец формирует структуру cipher_info. Поле encrypted_aes_key содержит шифротекст, возвращенный функцией, public_key_n — открытый ключ ECIES, а message_authentication_code — MAC.
struct cipher_info
{
uint8_t encrypted_unique_data[240];
uint8_t public_key_n[49];
uint8_t encrypted_aes_key[44];
uint8_t message_authentication_code[20];
};
Увидеть ее можно на рисунке ниже.
Зашифрованные данные инициализации
Затем эти данные кодируются в формате base64 и включаются в послание вымогателей.
Послание вымогателей
Как мы видим, преступники просят жертву включить закодированный текст в свое сообщение.
Шифрование файлов
Содержимое каждого файла шифруется по алгоритму AES-256-ECB с применением случайного ключа. По окончании шифрования троянец формирует структуру с такой информацией, как метка шифрования 0xA4EF5C91, использованный ключ AES, размер блока шифрования и исходное имя файла. Эти данные можно представить как структуру:
struct encryption_info
{
uint32_t label = 0xA4EF5C91;
uint8_t aes_key[32];
uint32_t encrypted_chunk_size;
uint32_t reserved;
uint8_t original_name_buffer[522];
};
Затем троянская программа вызывает функцию ECIES и передает структуру encryption_info как параметр plaintext, а ранее созданный ключ session_public_key — как параметр input_public_key. Возвращенный функцией результат сохраняется в структуре, которую мы назвали file_service_structure. В поле encrypted_file_info содержится шифротекст, возвращенный функцией, ecc_file_key_public содержит открытый ключ ECIES, а в message_authentication_code находится MAC.
struct file_service_structure
{
uint8_t ecc_file_key_public[49];
encryption_info encrypted_file_info;
uint8_t message_authentication_code[20];
};
Эта структура добавляется в конец зашифрованного файла. В результате он имеет следующую структуру:
struct encrypted_file
{
uint8_t encrypted_data[file_size - file_size % AES_BLOCK_SIZE];
uint8_t original_trailer[file_size % AES_BLOCK_SIZE];
uint64_t encryption_label = 0x65CE3D204A93A12F;
uint32_t infection_id;
uint32_t service_structure_size;
file_service_structure service_info;
};
Пример приведен на рисунке ниже.
Структура зашифрованного файла
После шифрования файлы получают случайно генерируемые расширения.
Каталог после шифрования
Другие особенности
Завершение работы процессов и служб
Прежде чем зашифровать файлы, SynAck получает список всех запущенных процессов и служб, затем сверяет хэши их имен с двумя жестко прописанными списками хэшей (вместе насчитывающими несколько сотен значений). В случае совпадения троянец попытается завершить работу процесса (с помощью функции API TerminateProcess) или остановить службу (командой ControlService с параметром SERVICE_CONTROL_STOP).
Чтобы узнать, какие процессы и службы стремится завершить троянец, мы сопоставили хэши из его тела реальным названиям методом полного перебора. Ниже приведены некоторые результаты.
Процессы | Службы | ||
Хэш | Название | Хэш | Название |
0x9a130164 | dns.exe | 0x11216a38 | vss |
0xf79b0775 | lua.exe | 0xe3f1f130 | mysql |
0x6475ad3c | mmc.exe | 0xc82cea8d | qbvss |
0xe107acf0 | php.exe | 0xebcd4079 | sesvc |
0xf7f811c4 | vds.exe | 0xf3d0e358 | vmvss |
0xcf96a066 | lync.exe | 0x31c3fbb6 | wmsvc |
0x167f833f | nssm.exe | 0x716f1a42 | w3svc |
0x255c7041 | ssms.exe | 0xa6332453 | memtas |
0xbdcc75a9 | w3wp.exe | 0x82953a7a | mepocs |
0x410de6a4 | excel.exe | ||
0x9197b633 | httpd.exe | ||
0x83ddb55a | ilsvc.exe | ||
0xb27761ed | javaw.exe | ||
0xfd8b9308 | melsc.exe | ||
0xa105f60b | memis.exe | ||
0x10e94bcc | memta.exe | ||
0xb8de9e34 | mepoc.exe | ||
0xeaa98593 | monad.exe | ||
0x67181e9b | mqsvc.exe | ||
0xd6863409 | msoia.exe | ||
0x5fcab0fe | named.exe | ||
0x7d171368 | qbw32.exe | ||
0x7216db84 | skype.exe | ||
0xd2f6ce06 | steam.exe | ||
0x68906b65 | store.exe | ||
0x6d6daa28 | vksts.exe | ||
0x33cc148e | vssvc.exe | ||
0x26731ae9 | conime.exe | ||
0x76384ffe | fdhost.exe | ||
0x8cc08bd7 | mepopc.exe | ||
0x2e883bd5 | metray.exe | ||
0xd1b5c8df | mysqld.exe | ||
0xd2831c37 | python.exe | ||
0xf7dc2e4e | srvany.exe | ||
0x8a37ebfa | tabtip.exe |
Как видите, SynAck старается остановить программы, связанные с виртуальными машинами, офисными приложениями, интерпретаторами скриптов, базами данных, системами резервного копирования, игровыми приложениями и др. Вероятно, таким образом троянец гарантирует доступность ценных файлов, которые могли быть заняты запущенными процессами.
Очистка журналов событий
Чтобы предотвратить последующий криминалистический анализ зараженного компьютера, SynAck очищает все системные журналы событий. Это делается одним из двух способов. В версиях Windows, предшествующих Vista, троянец перебирает все ключи в ветке реестра SYSTEMCurrentControlSetServicesEventLog и задействует функции API OpenEventLog/ClearEventLog. В более современных версиях Windows он использует функции EvtOpenChannelEnum/EvtNextChannelPath/EvtClearLog библиотеки Wevtapi.dll.
Послание вымогателей на экране входа в систему
SynAck также умеет добавлять свой текст на экран входа Windows. Для этого программа изменяет ключи реестра LegalNoticeCaption и LegalNoticeText. В итоге еще до входа пользователя в систему Windows показывает сообщение киберпреступников.
Экран входа Windows с посланием вымогателей
Статистика заражения
В настоящее время мы зафиксировали сравнительно небольшое число атак в США, Кувейте, Германии и Иране. Это наводит на мысль, что SynAck используется для целевого вымогательства.
Вердикты
Trojan-Ransom.Win32.Agent.abwa
Trojan-Ransom.Win32.Agent.abwb
PDM:Trojan.Win32.Generic
Индикаторы заражения (IoC)
0x6F772EB660BC05FC26DF86C98CA49ABC
0x911D5905CBE1DD462F171B7167CD15B9
Целевая вымогательская кампания SynAck использует технику Doppelgänging