В августе этого года мы публиковали информацию о новом state-sponsored вредоносном ПО под названием Cremes (aka Remsec). Антивирусные продукты ESET обнаруживают его компоненты как Win32/Cremes и Win64/Cremes. Cremes является сложным трояном со множеством компонентов, которые используются для кибершпионажа. Информация о Cremes также была опубликована специалистами Федеральной Службы Безопасности (ФСБ), поскольку Cremes использовался для кибершпионажа за сотрудниками государственных учреждений.


Cremes включает в себя и Ring 0 компонент (руткит), который используется злоумышленниками как LPE-шлюз (kernel gate) для исполнения своего кода в режиме ядра. В отличие от уже таких хорошо известных руткитов и буткитов как ZeroAccess, TDL4, Mebroot, Gapz и др., Cremes не обременяет себя сложными процедурами компрометации MBR и ранних стадий загрузки ядра NT для исполнения своего Ring 0 кода в системе в обход DSE, вместо этого он использует для этого легитимные драйверы.

Авторы Cremes прибегли к использованию двух плагинов с названиями kgate и xkgate для размещения там Ring 0 кода. Нам удалось обнаружить внутри обоих плагинов временные метки, которые свидетельствуют о дате разработки плагинов и использовались авторами в отладочных целях. Согласно этим меткам, авторы прибегли к разработке xkgate позднее чем kgate. Валидность даты в xkgate подтверждается также временной меткой из заголовка PE-файла (хотя они и различаются на один день).


Рис. Временные метки внутри обоих плагинов

Плагин kgate


Плагин kgate используется в качестве установщика в систему Ring 0 кода как на 32-х, так и на 64-битных версиях Windows. Для 32-битной системы, kgate прибегает к использованию функций драйвера Agnitum Sandbox.sys, который позволяет с использованием специального IOCTL запроса загрузить драйвер руткита в систему. Для этого плагин извлекает из своего тела (секции .rdata) драйвер Sandbox.sys и записывает его на диск, после чего налету формирует PE-файл для своего вредоносного Ring 0 кода и записывает его в файл aswfilt.dll. Ниже приведены свойства этого драйвера.

  • Имеет компактный размер и может уместиться на одну страницу виртуальной памяти (4КБ).
  • Так как сам PE-файл генерируется на лету, он не имеет временной метки в PE-заголовке. Он также имеет одну безымянную NONPAGED-секцию с кодом и данными драйвера.
  • Драйвер использует динамически подгружаемые импорты и хранит их в специальной структуре DeviceObject->DeviceExtension.
  • Драйвер использует обфускацию смещений внутри кода.
  • С точки зрения кодинга, драйвер написан квалифицированными авторами


Рис. Плагин сбрасывает в файловую систему драйвер Agnitum Sandbox.sys, создает его сервис в системном реестре и загружает его в память для последующей эксплуатации.


Рис. Плагин генерирует файл руткита, прописывает его в реестре и указывает Sandbox.sys загрузить драйвер.

Ответ на вопрос, зачем авторам понадобилось записывать содержимое руткита в файл aswfilt.dll кроется в драйвере Sandbox.sys. Если мы посмотрим на его код, то увидим ссылку на него внутри драйвера.


Рис. Ссылка на aswfilt.dll внутри легитимного драйвера Sandbox.sys.

После небольшого анализа кода Sandbox.sys, нам удалось обнаружить, что ссылка на данный файл внутри драйвера связана с тем IOCTL-кодом, который плагин отправляет драйверу. Особенность заключается в том, что aswfilt.dll является названием плагина Agnitum, который драйвер Sandbox.sys может загрузить в память после того, как ему отправлен данный IOCTL код.






Рис. При обработке драйвером IOCTL-кода, он проверяет название файла и загружает его в системную память с использованием API ядра ZwLoadDriver.

Руткит используется плагином kgate лишь для одной цели — исполнение указанной ему из пользовательского режима функции в режиме ядра с обходом SMEP. Для коммуникации с клиентом, руткит создает объект-устройство \Device\rwx, при этом клиент использует путь \\.\GLOBALROOT\Device\rwx для открытия устройства. Для отключения SMEP и исполнения функции, клиент отправляет Ring 0 коду IOCTL с кодом 0x1173000C.


Рис. Руткит отключает SMEP для исполнения функции из user mode, при этом, предварительно, привязав поток к текущему процессору.

Следующая структура используется руткитом в качестве контекста (DeviceObject->DeviceExtension).

struct RootkitStruct {

PVOID ExAllocatePool;
PVOID ExFreePool;
PVOID IoCompleteRequest;
PVOID IoCreateDevice;
PVOID IoDeleteDevice;
PVOID KeAcquireSpinLock;
PVOID KeCancelTimer;
PVOID KeInitializeEvent;
PVOID KeInitializeSpinLock;
PVOID KeInitializeTimer;
PVOID KeQueryInterruptTime;
PVOID KeReleaseSpinLock;
PVOID KeSetEvent;
PVOID KeSetTimer;
PVOID KeWaitForMultipleObjects;
PVOID ObfReferenceObject;
PVOID ObDereferenceObject;
PVOID PsCreateSystemThread;
PVOID PsGetVersion;
PVOID PsTerminateSystemThread;
PVOID ZwClose;
PVOID ZwCreateKey;
PVOID ZwDeleteKey;
PVOID ZwEnumerateKey;
PVOID ZwOpenKey;
PVOID ZwSetValueKey;
PVOID ZwUnloadDriver;
PVOID KeQueryActiveProcessors;
PVOID KeSetSystemAffinityThread;
PVOID KeRevertToUserAffinityThread;
ULONG Flag;
KEVENT Event;
ULONG dwField1;
KTIMER Timer;
KSPIN_LOCK SpinLock;
ULONG dwField2;
LARGE_INTEGER IntervalTime;
UNICODE_STRING unDriverRegistryPath;
};

Драйвер использует интересную процедуру выгрузки по таймеру и позволяет клиенту из пользовательского режима задавать интервал ожидания. Для этого драйвер создает отдельный системный поток, который ждет на таймере и в случае истечения времени вызывает функцию ZwUnloadDriver. Выгрузка драйвера из своего же кода может быть выполнена некорректно, поскольку поток может вернуться уже на несуществующую страницу памяти.


Рис. Функция fnCreateDriverRegKeyOrRemoveIt выполняет удаление сервиса драйвера и выгружает его с помощью ZwLoadDriver.

Ниже приведена структура исполняемого файла плагина.


Рис. Структура PE-файла плагина kgate.

Плагин xkgate


Название плагина xkgate можно интерпретировать как extended kgate, т. е. расширенный kgate. В отличие от своего предшественника, он не имеет на борту 32-х разрядной версии, а рассчитан только на 64-битную версию Windows. Ниже в таблице указаны сравнения возможностей обоих плагинов.



Ниже приведена информация о цифровых подписях используемых драйверов AV продуктов авторами Cremes.


Рис. Цифровые подписи драйверов Avast и Agnitum.

Как видно, оба плагина содержат идентичный код в секциях с 64-битным кодом krwkr64 и krdrv64. Для загрузки этого Ring 0 кода авторы Cremes выбрали еще одну жертву — драйвер Avast. Эксплуатация этого драйвера сложнее чем драйвера Agnitum, рассмотрим его более подробно.

Первое что делает xkgate для загрузки Ring 0 кода, это создает специальный мьютекс для предотвращения повторной загрузки драйвера Avast в память (функция).


Рис. Код открытия/создания мьютекса.

После этого код вызывает функцию fnDropAvastDriverAndPrepareEnv, которая выполняет следующие действия.

  • Создает директорию \SystemRoot\Temp\aswSnx, куда записывает файлы Avast.
  • Сбрасывает в файловую систему файл aswSnx.sys.
  • Сбрасывает в файловую систему snx_lconfig.xml
  • Также извлекает из себя snx_gconfig.xml.
  • Создает пустой файл snxhk.dll.
  • Создает файл aswSnx.exe и записывает в него содержимое notepad.exe.


Рис. Вызов функции fnDropAvastDriverAndPrepareEnv внутри fnLoadAvast.

После этого fnLoadAvast вызывает fnCreateAvastServiceAndLoadDriver для создания раздела реестра для Avast. Ниже указаны предпринимаемые действия.

  • Создает раздел реестра System\CurrentControlSet\Services\aswSnx.
  • Создает в нем параметр ImagePath со значением \SystemRoot\Temp\aswSnx\aswSnx.sys.
  • Создает параметр Type.
  • Создает подраздел Parameters.
  • Создает в нем параметр DataFolder со значением \??\Global\GLOBALROOT\SystemRoot\Temp\aswSnx.
  • Создает параметр ProgramFolder со значением \??\Global\GLOBALROOT\SystemRoot\Temp\aswSnx.
  • Создает подраздел Instances.
  • Создает в нем подраздел DefaultInstance.
  • Создает в нем параметры Altitude и Flags.
  • Загружает aswSnx.sys с использованием NtLoadDriver.

После того как aswSnx.sys загружен, fnLoadAvast удаляет файлы snxhk.dll и snxhk64.dll с помощью NtSetInformationFile. Далее функция создает процесс с названием aswSnx.exe, который представляет из себя notepad.exe. После этого создается дескриптор на устройство Avast с названием \Device\aswSnx.


Рис. Функция создания псевдо — aswSnx.exe.

После создания процесса aswSnx.exe с остановленным стартовым потоком, функция дублирует открытый дескриптор на устройство \Device\aswSnx из процесса плагина в новый процесс aswSnx.exe. Далее туда же копируется специальный код из секции плагина .avit, которая отвечает за взаимодействие с драйвером Avast. Он выполняет функцию DeviceIoControl, которая приводит к исполнению вредоносного Ring 0 кода.


Рис. Функция эксплуатации драйвера Avast.

Ниже указаны характеристики загружаемого Ring 0 кода.

  • Имеет компактный размер и умещается в одну страницу виртуальной памяти.
  • Использует динамические импорты, которые также хранятся в контексте устройства.
  • Плагин kgate имеет 32-битный аналог этого кода.
  • Не содержит функцию DriverEntry.
  • Исполняет требуемый клиентом код через механизм быстрого DeviceControl (Fast I/O) FastIoDeviceControl.
  • Использует недокументированные функции ядра Windows.

Для упрощения анализа рассмотрим идентичную 32-битную версию Ring 0 кода, которая хранится в плагине kgate.

Так как код режима ядра не загружается самим ядром Windows и не представляет из себя полноценный файл драйвера, для загруженного кода не создан объект драйвера, который должен передаваться ему через DriverEntry. Поэтому, первое что делает руткит, это создает для себя объект драйвера с помощью ObCreateObject.




Рис. Функция создания объекта драйвера и вставки его в системную очередь Windows через недокументированную функцию ObInsertObject.

Для обработки запроса DeviceControl, драйвер регистрирует не стандартный в таких случаях обработчик IRP_MJ_DEVICE_CONTROL, а использует вместо этого функцию быстрого ввода-вывода DriverObject->FastIoDispatch.FastIoDeviceControl.


Рис. Функция регистрации DriverObject->FastIoDispatch.FastIoDeviceControl.

Эта функция-обработчик используется только для исполнения кода требуемого клиентом кода в режиме ядра.


Рис. Обработчик Fast I/O руткита.

Заключение


Применяемые авторами Cremes методы для загрузки руткита в память являются действительно интересными, так как для этого используются легитимные драйверы режима ядра антивирусных продуктов. В отличие от прочих известных руткитов, Cremes не заинтересован в перехвате каких-либо API-вызовов или системных операций для сокрытия своей активности в системе. Вместо этого, авторов просто интересовала возможность гарантированного исполнения своего кода в режима ядра, т. е. повышение своих привилегий в системе. С помощью используемого ими подхода такая методика является достаточно успешной.
Поделиться с друзьями
-->

Комментарии (1)


  1. VANSCoder
    24.10.2016 00:02

    <сарказм>Зато аваст бесплатный</сарказм>