Когда в первой половине 2019 года появился новый шифровальщик Sodin (также известен как Sodinokibi и REvil), мы сразу обратили на него внимание, так как для распространения он использовал уязвимость в Oracle Weblogic и атаки на MSP-провайдеров. При детальном анализе мы обнаружили, что он также использует уязвимость для повышения привилегий в ОС Windows, что редко встречается среди шифровальщиков, а для обхода защитных решений использует легитимные функции процессора.
Согласно нашей статистике, большая часть жертв находилась в Азиатско-Тихоокеанском регионе: на Тайване, в Гонконге и Южной Корее.
Техническое описание
Эксплуатация уязвимости
Для повышения привилегий Trojan-Ransom.Win32.Sodin использует уязвимость в win32k.sys, попытки эксплуатации которой были впервые обнаружены нашими проактивными технологиями («Автоматическая защита от эксплойтов», AEP) еще в августе прошлого года. Уязвимость получила номер CVE-2018-8453. После исполнения эксплойта троянец получает максимальный уровень привилегий.
Информация о токене процесса после выполнения эксплойта
Фрагмент эксплойта по проверке класса окна
В зависимости от архитектуры процессора будет запущен один из двух содержащихся в теле троянца вариантов шелл-кода:
Процедура выбора подходящего варианта шелл-кода
Так как анализируемый нами бинарник является 32-разрядным исполняемым файлом, то для нас представляет интерес то, каким образом ему удается выполнить 64-битный код в своем адресном пространстве. На скриншоте изображен фрагмент шелл-кода, позволяющего выполнение 64-разрядных инструкций процессора:
Шелл-код, состоящий из 32- и 64-разрядных инструкций
В 64-разрядной ОС селектор 32-разрядного сегмента кода пользовательского режима равен 0x23, а селектор 64-х разрядного сегмента — 0x33. В этом нетрудно убедиться, взглянув на глобальную таблицу дескрипторов GDT в отладчике ядра:
Так выглядит часть GDT в OS Windows 10 x64
Селектор 0x23 указывает на четвертый дескриптор сегмента (0x23 >> 3), а селектор 0x33 — на шестой (нулевой дескриптор не используется). Флаг Nl говорит, что сегмент имеет 32-разрядную адресацию, а флаг Lo отмечает 64-разрядную. Важно то, что базовые адреса этих сегментов равны! На момент выполнения шелл-кода в сегментном регистре cs будет находиться селектор 0x23, т. к. код выполняется в 32-разрядном адресном пространстве. Имея это в виду, взглянем на листинг самого начала шелл-кода:
Сохранение полного адреса — 0x23:0xC
После выполнения команды по RVA-адресам 6 и 7 на вершине стека будет храниться длинный адрес возврата в формате селектор:смещение, он будет иметь вид 0x23:0x0C. По смещению 0x11 в стек кладется DWORD, младшее слово которого содержит селектор 0x33, а старшее слово кодирует в себе инструкцию retf, опкод которой равен 0xCB.
Сохранение полного адреса 0x33:0x1B на 64-разрядный код
Переход в 64-разрядный режим
Следующая инструкция — call (по адресу 0x16 RVA) — осуществляет ближний переход на данную инструкцию retf (по RVA — 0x14), предварительно отправив в стек ближний адрес возврата (смещение — 0x1b). Таким образом, на момент выполнения инструкции retf на вершине стека будет находиться адрес в формате селектор:смещение, где селектор равен 0x33, а смещение — 0x1b. После выполнения команды retf процессор приступит к выполнению кода по данному адресу, но уже в 64-разрядном режиме.
64-разрядный шелл-код
Возврат в 32-разрядный режим осуществляется в самом конце шелл-кода.
Возврат в 32-разрядный режим
Команда retf осуществит дальний переход по адресу 0x23:0x0C (его поместили в стек инструкций в самом начале шелл-кода — по RVA-адресу 6-7). Подобная техника выполнения 64-разрядного кода в 32-разрядном адресном пространстве процесса называется Heaven’s Gate и была описана приблизительно 10 лет назад.
Конфигурация троянца
В теле каждого образца Sodin в зашифрованном виде хранится конфигурационный блок, содержащий настройки и данные, необходимые троянцу для работы.
Расшифрованный конфигурационный блок троянца
В конфигурации Sodin есть следующие поля:
Поле | Назначение |
pk | публичный ключ распространителя |
pid | вероятно, id распространителя |
sub | вероятно, id кампании |
dbg | отладочная сборка |
fast | режим быстрого шифрования (максимум 0x100000 байт) |
wipe | удаление определенных файлов с перезаписью их содержимого произвольными байтами |
wfld | названия директорий, в которых троянец будет удалять файлы |
wht | названия директорий, файлов, а также список расширений, которые не будут шифроваться |
prc | названия процессов, которые будут завершены |
dmn | адреса серверов для отправки статистики |
net | отправка статистики о заражении |
nbody | шаблон текста с требованиями |
nname | шаблон имени файла с требованиями |
exp | использование эксплоита для повышения привилегий |
img | текст для обоев рабочего стола |
Криптографическая схема
Sodin использует гибридную схему для шифрования файлов жертвы. Содержимое файлов шифруется симметричным потоковым алгоритмом Salsa20, а ключи для него — асимметричным алгоритмом на эллиптических кривых. Рассмотрим схему в подробностях.
Так как некоторые данные сохраняются в реестре, мы будем использовать в статье те названия, которые используются самим шифровальщиком. Для тех сущностей, которые не попадают в реестр, будем использовать выдуманные.
Данные, сохраненные троянцем в реестре
Генерация ключей
Итак, в конфиге Sodin содержится поле pk, оно же попадает в реестр под именем sub_key — это 32-байтовый публичный ключ распространителя троянца. Ключ является точкой на эллиптической кривой Curve 25519.
При запуске троянец генерирует новую пару сессионных ключей на эллиптической кривой; публичный ключ из этой пары сохраняется в реестре под именем pk_key, а приватный будет зашифрован по алгоритму ECIES на ключе sub_key и сохранен в реестре под именем sk_key. Реализация ECIES в данном случае включает кривую Curve 25519, криптографический хэш SHA3-256 и блочный шифр AES-256 в режиме CFB. Другие реализации ECIES встречались в троянцах и ранее — например, в шифровальщике SynAck.
Любопытный момент: тот же сессионный приватный ключ будет зашифрован и на другом публичном ключе, «зашитом» в теле троянца вне зависимости от конфигурации. Будем называть его public skeleton key. Результат шифрования сохраняется в реестре под именем 0_key. Получается, что человек, знающий приватный ключ, соответствующий public skeleton key, сможет расшифровать файлы жертвы, даже если не имеет приватного ключа от sub_key. Это выглядит так, будто разработчик троянца встроил в алгоритм лазейку, позволяющую ему расшифровать файлы без ведома распространителей.
Фрагмент процедуры, генерирующей ключевые данные и сохраняющей некоторые из них в реестре
Шифрование файлов
При шифровании каждого файла генерируется новая пара асимметричных ключей на эллиптической кривой, назовем их file_pub и file_priv. Затем вычисляется SHA3-256(ECDH(file_priv, pk_key)), и результат используется как симметричный ключ для шифрования содержимого файла алгоритмом Salsa20. В зашифрованном файле сохраняется также следующая информация:
Данные, сохраняемые в каждом зашифрованном файле
Помимо уже рассмотренных выше полей здесь также есть nonce (произвольные инициализационные 8 байт для шифра Salsa20), file_pub_crc32 (контрольная сумма от file_pub), flag_fast (если он выставлен, значит в файле зашифрована только часть данных), zero_encr_by_salsa (нулевой dword, зашифрованный тем же ключом Salsa20, что и содержимое файла, — видимо, для проверки правильности расшифровки).
Зашифрованные файлы получают новое произвольное расширение (одно и то же для каждого случая заражения), рядом с ними сохраняется текст с требованиями, а на рабочий стол устанавливаются сгенерированные зловредом обои.
Требования злоумышленников
Фрагмент обоев рабочего стола, созданных шифровальщиком
Сетевое взаимодействие
Если соответствующий флаг выставлен в конфигурационном блоке, троянец будет отправлять на свои серверы информацию о зараженной машине. Передаваемые данные также шифруются по алгоритму ECIES с помощью еще одного публичного ключа, зашитого в теле Sodin.
Часть конфигурации Sodin, отвечающая за сетевое взаимодействие
Поле | Назначение |
ver | версия троянца |
pid | вероятно, id распространителя |
sub | вероятно, id кампании |
pk | публичный ключ распространителя |
uid | id заражения |
sk | значение sk_key (см. описание выше) |
unm | имя пользователя зараженной системы |
net | имя машины |
grp | домен/рабочая группа машины |
lng | язык системы |
bro | попадает ли язык или раскладка в системе в список (ниже) |
os | версия ОС |
bit | архитектура |
dsk | информация о дисках в системе |
ext | расширение зашифрованных файлов |
В процессе исполнения троянец осуществляет проверку языка системы и имеющихся раскладок клавиатуры:
В случае обнаружения совпадений со списком процесс зловреда завершается, и до отправки статистики дело не доходит.
MITRE ATT&CK techniques
Больше информации о сервисах кибербезопасности доступно по ссылке: https://www.kaspersky.ru/enterprise-security/cybersecurity-services
IOC
1ce1ca85bff4517a1ef7e8f9a7c22b16
Шифровальщик Sodin использует уязвимость в Windows и архитектурные возможности процессора
Максим
Добрый день, на этой неделе мой клиент столкнулся с этой гадостью на своём продакшн сервере. К счастью была резервная копия всех данных, но изза этого дерьма был потерян один рабочий день. Скажите, как эта зараза могла попасть на сервер, как от неё защититься в будущем?