Дослідження руткіта Cremes

У серпні цього року ми публікували інформацію про новому 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-дзвінків або системних операцій для приховування своєї активності в системі. Замість цього, авторів просто цікавила можливість гарантованого виконання свого коду в режимі ядра, тобто підвищення своїх привілеїв в системі. З допомогою використовуваного ними підходу така методика є досить успішною.
Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.