Вот еще один год позади и я снова готовлю этот субъективный итоговый материал на тему самых интересных и технологичных вредоносных программ прошлого года.

Ну, что же прошедшей год был весьма интересным и насыщенным, тут было, где развернуться буткит-технологиям и целенаправленным образцам кибероружия. Хотя впрочем, были достаточно интересные экземпляры руткитов семейства Win32/Festi, код которого не рассчитан на выполнение на х64 битных системах ввиду отсутствия механизмов обхода проверки цифровой подписи, но и без этого там нашлось, на что посмотреть. Таким образом, мой Top-5 за прошлый год выглядит следующим образом:

  1. Win32/Flamer (он же Flame) – за сложность в анализе и реконструкции алгоритмов. Очень много кода предусматривающего огромное количество внештатных ситуаций и очень изящно обходящего некоторые антивирусные продукты.

  1. Win32/Gapz – выстрелил под конец года с новой технологией реализации VBR-буткита и интересным методом внедрения кода в системный процесс explorer.exe, работающего в обход большинства HIPS систем.

  1. Win32/Sirefef (ZeroAccess) – так же один из интереснейших экземпляров уходящего года, а точнее его последние модификации. Использующий так же интересный метод внедрения кода и недокументированные возможности файловой системы NTFS для противодействия удалению собственных файлов.

  1. Win32/Festi – получает четвертое место за изощренную реализацию объектно-ориентированной платформы внутри тела основного драйвера и использования системы безтелесных расширений для проведения DDoS атак и рассылки спама. Эти расширения доступны только в памяти зараженной системы и не сохраняются на жестком диске.

  1. Win32/Rovnix – получает почетное последнее место в нашем рейтинге за дальнейшее развитие наиболее сложной файловой системы используемой в современных буткитах. Файловая система этого буткита базируется на стандарте FAT16 и ни в чем не уступает некоторым операционным системам.

Выше я постарался немного объяснить, почему именно эти угрозы привлекли мое внимание. И теперь мы погружаемся в пучину кода, в которой постараемся отыскать самые интересные детали приведенного мной списка угроз. Ну что же начнем по порядку с начала списка ;)

Win32/Flamer

Об этом звере говорили уже очень много, в том числе и на страницах журнала. Поэтому здесь мы не будем разводить тягомотину на тему кибервойны и строить прочих конспирологических теорий. А сосредоточимся лишь на фактах отраженных в коде Flame и его предшественников или последователей. Подробно изучая развитие сложных целенаправленных угроз, начиная со Stuxnet, я пришел к выводу, что существует связь в коде вредоносных программ Stuxnet, Duqu, Flame, Gauss и miniFlame. А точнее прослеживается некоторая связь в архитектуре этих вредоносных программ и далее удалось найти взаимосвязь между архитектурой базовой платформы, на которой они были разработаны. Таким образом, прослеживается следующая следующая зависимость в этих семействах:

Несмотря на поиски схожести в алгоритмах шифрования строк некоторыми известными компаниями, все же Flame базируется на собственной объектно-ориентированной платформе. А алгоритмы, на базе которых реализована работа со строками, имеют существенные отличия и реализация Flame значительно сложнее:

Архитектура Flame имеет существенные отличия от той платформы, на которой разработан Stuxnet или Duqu. А если провести параллель по сложности анализа и восстановления алгоритмов этих вредоносных программ, то у меня получается следующая диаграмма:

Именно поэтому Flame занимает почетное первое место на диаграмме и в нашем рейтинге. Ну, а теперь давай те углубимся в детали реализации этой вредоносной программы. Итак, внутри Flame живет ООП фреймворк базирующийся на событийно-ориентированной логике и реализованный в виде списков объектов на базе контейнеров библиотеки STL (Standard Template Library), а точнее на базе шаблона vector. Если изобразить абстрактную схему взаимосвязи объектов то получается следующее:

Вся эта красота реализована внутри основного модуля известного, как mssecmgr.ocx. Теперь давайте немного обсудим основные компоненты этой диаграммы.

Command Executers – объекты этого типа реализованы для взаимодействия с командными серверами и получения и последующей обработки полученных команд.

Tasks – объекты этого типа описывают текущие задачи, которые выполняются в отдельных потоках. Есть два типа задач, которые встречаются во всех известных модификациях Flame:

IDLER – собственно этот типа задач реализует выполнение задач с некоторой задержкой, она происходит через взаимодействие с вектором <DelayedTasks>.

CommandExecuter – отвечает за выполнение задач и выполнение команд из конфигурационной информации активного экземпляра Flame. В восстановленном примере кода это выглядит следующим образом:

Consumers – объекты созданные при определенных событиях (создание новых модулей, активация внешнего носителя). Именно этот тип объектов реализует событийно-ориентированную логику. Такой подход эффективен, поскольку Flame реализован для сбора информации и последующей передачи ее на командный центр. Известно несколько типов реализующих объекты потребителей (сonsumers):

process consumers – реагирует при запуски определенных программ

volume consumers – реагирует об активации нового тома в файловой системе

removable media consumers – реагирует на появление новых внешних носителей в системе

mobile devices consumers – реагирует при подключение мобильных устройств

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

Delayed Tasks – этот типа задач представлен объектами, которые выполняются с заранее определенной задержкой по врмени.

Описанные выше объекты реализуют основную архитектуру Flame, а сам подход к их реализации очень напоминает паттерн объектно-ориентированного программирования «команда». Stuxnet и Duqu построены на базе другого контейнера библиотеки STL, а точнее на базе типа list. Во Flame используется только тип vector, что вносит отличия в реализацию этих вредоносных программ.

Тип CommandExecuter реализует свой собственный интерфейс для обработки потока команд. Этот интерфейс можно описать в виде следующей структуры:

Вот так выглядит код обработчика команд с C&C этого ботнета:

Как видно из приведенного кода вся информация хранится в собственной базе данных SQLite и информация, касающаяся обработчиков команд, хранится по ключу CMD_QUEUE. Команды хранятся в формате сжатых бинарных данных. При декодировании команды Flame распаковывает данные и разделяет команды на блоки. Каждый блок обрабатывается конкретным обработчиком, который имеет свой идентификатор. Интерфейс обработчика может выглядеть следующим образом:

CmdExecuter_Dispatch функция обработчика, которая вызывается для обработки поступившей команды или находящейся первой в очереди обработки. Различные диспетчеры определены для обработки разных событий. Например, диспетчер DbQuery обрабатывает команды связанные с запросами базе данных SQLite.

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

Как уже отмечалось ранее Flame имеет собственную базу данных, реализованную на базе SQLite, в рамках которой хранятся собранные данные о зараженной системе и ее окружении. Схема этой базы данных выглядит следующим образом:

 

Table name

Description

Attack_Log

Keeps all the information on attack attempts

Attack_Queue

A queue of LUA scripts used in attack

Attack_Params

Parameters for LUA scripts for attack

Attack_Providers_Log

providers log (clan.repo.addProviderLog())

Cruise_Attack_Log

Log for “CRUISE” type of attack

Settings

Supplemental Parameters (last_log_store_time(getFlameTime()))

Entities

List of attacked machines

MetaData

data for Entities table (function clan.repo.updateMetadata())

Options_Per_Entity

Temporal table with the list of active attacks

Creds

Stolen credentials for attacks

 

 

Table name

Description

EventLog

Log of all the events (eventWriter.writeEven())

EventLogParams

Unique list of parameters for different events

AppTable

List of available plugin-applications (standalone LUA script)

Configuration

Configuration data for applications

StorageProducts

List of available plugin-products (auxiliary LUA object)

StorageMetaData

Configuration data for products

 

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

 

Type

LUA script name

Description

Libraries

LUA.LIBS.attackop_base_prods

LUA.LIBS.attackop_base_sendfile

LUA.LIBS.casafety

LUA.LIBS.clan_entities

LUA.LIBS.clan_seclog

LUA.LIBS.fio

LUA.LIBS.flame_props

LUA.LIBS.json

LUA.LIBS.libclanattack

LUA.LIBS.libclandb

LUA.LIBS.libcommon

LUA.LIBS.libdb

LUA.LIBS.libflamebackdoor

LUA.LIBS.liblog

LUA.LIBS.libmmio

LUA.LIBS.libmmstr

LUA.LIBS.libnetutils

LUA.LIBS.libplugins

LUA.LIBS.libwmi

LUA.LIBS.rts_common

LUA.LIBS.table_ext

LUA.LIBS.transport_nu_base

auxiliary libraries

Applications

RTS.APPS.BASIC_INFO.BUFFER

RTS.APPS.EUPHORIA_APP.BUFFER

RTS.APPS.EVENT_WRITER.BUFFER

RTS.APPS.GET_CMD.BUFFER

RTS.APPS.LEAK_APP.BUFFER

RTS.APPS.MAIN_APP.BUFFER

RTS.APPS.PAYLOAD_LOGGER.BUFFER

RTS.APPS.POST_CMD.BUFFER

RTS.APPS.STORAGE_MANAGER.BUFFER

scripts which execute over main function Start(…)

Attacks

LUA.CLAN.ATTACK_OPS.FLAME

LUA.CLAN.ATTACK_OPS.FLAME_PRODS

LUA.CLAN.ATTACK_OPS.FLAME_STARTLEAK

LUA.CLAN.ATTACK_OPS.FLASK

LUA.CLAN.ATTACK_OPS.FLASK_PRODS

LUA.CLAN.ATTACK_OPS.JIMMY

LUA.CLAN.ATTACK_OPS.JIMMY_PRODS

LUA.CLAN.ATTACK_OPS.MOVEFILE

LUA.CLAN.ATTACK_OPS.RUNDLL

scripts which execute over function credAttack(ctx)

where ctx value is context of attack

Attack success handlers

LUA.CLAN.SUCCESS_HANDLERS.FLAME

LUA.CLAN.SUCCESS_HANDLERS.FLAME_STARTLEAK

LUA.CLAN.SUCCESS_HANDLERS.FLASK

LUA.CLAN.SUCCESS_HANDLERS.JIMMY

successful status of attack, which execute over function onSuccess(attackContext)

Attack products

LUA.CLAN.SAFETIES.REG

LUA.CLAN.SAFETIES.WMI

LUA.CLAN.CRED_HANDLERS.CRUISE

LUA.CLAN.CRED_HANDLERS.USERPASS

LUA.CLAN.TRANSPORTS.NU_DUSER

LUA.CLAN.TRANSPORTS.NU_SYSTEM

LUA.CLAN.EXECS.RESCH

LUA.CLAN.EXECS.WMI

Initializing script for class of product/provider

clanattack.providerObject()

Entity plugins

LUA.CLAN.ENTITY_SPOTTERS.NETVIEW

LUA.CLAN.ENTITY_SPOTTERS.SECLOG

LUA.CLAN.ENTITY_TYPES.NETVIEW

LUA.CLAN.ENTITY_TYPES.SECLOG

LUA.CLAN.ENTITY_TYPES.SNACK_BROWSER

LUA.CLAN.ENTITY_TYPES.SNACK_NBNS

handlers for objects type Entity

getEntities(maxCount)

findEntity(entity, db)

updateRepo(entity, db)

Supplemental

LUA.START_PARAMS.STD

MUNCH.SHOULD_ATTACK_SCRIPT

GADGET.LUA_CONSUMER.MUNCH_ATTACKED.SCRIPT

GADGET.LUA_CONSUMER.SNACK_ENTITY.ADD_TO_DB

GADGET.LUA_CONSUMER.SNACK_ENTITY.ATTACK_NOW

scripts which don’t have exact context

 

Flame существенно отличается от обычных вредоносных программ и как видно из всего вышеописанного имеет очень продуманную реализацию. Над этой вредоносной программой совершенно однозначно работала команда высококвалифицированных программистов, которые написали расширяемый и поддерживаемый в дальнейшем код. Все это хорошо прослеживается в процессе обратного анализа и настолько продуманной вредоносной программы мне еще не встречалось раньше. Именно поэтому Win32/Flamer занимает почетное первое место.

Win32/Gapz

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

 

Detection name

Compilation date

LPE exploits

Bootkit technique

Win32/Gapz.A

11/09/2012

30/10/2012

CVE-2011-3402

CVE-2010-4398

COM Elevation

VBR

Win32/Gapz.B

06/11/2012

CVE-2011-3402

COM Elevation

no bootkit

Win32/Gapz.C

19/04/2012

CVE-2010-4398

CVE-2011-2005

COM Elevation

MBR

 

Как видно из таблицы используется достаточно большое количество различных способов повышения привелегий:

  1. CVE-2011-3402 (TrueType Font Parsing Vulnerability)

  2. CVE-2010-4398 (Driver Improper Interaction with Windows Kernel Vulnerability)

  3. COM Elevation (UAC whitelist)

Но сейчас они уже не представляют для нас большого интереса, так как уже давно описаны в общедоступных источниках информации и ни раз упоминались на страницах журнала. Сейчас мы сфокусируемся на исследовании дропера, а точнее его структуры и нового метода внедрения кода. Итак, дропер помимо точкивхода (entrypoint) имеет еще ряд экспортируемых функций, которые имеют сове предназначение в процессе заражения системы.

Если остановится несного подробнее н

start – точка входа дроппера с которой начинается выполнение кода и после проверки на наличие активных антивирусных продуктов просиходит внедрение кода в адресное пространство процесса explorer.exe

• icmnf – эта экспортируемая функция отвечает за поднятие привилегий и вызывается уже внедренным кодом из контекста процесса explorer.exe

isyspf – эта экспортируемая функция отвечает уже непосредственно за заражение системы, если все предыдущие стадии выполнения отработали корректно

Эту последовательность действий можно описать следующей диаграммой:

Ну, а теперь давайте перейдем к описанию метода внедрения кода, который обходит большинство известных HIPS систем, которые реализованы практически в каждом антивирусном продукте. Так же стоит отметить, что эта техника внедрения используется во всех известных на данный момент версиях дропера семейства Win32/Gapz. Итак, теперь пройдемся по шагам алгоритма внедрения кода:

  1. Сначала открывается одна из разделяемых секций \BaseNamedObjects которые загружены в адресное пространство explorer.exe, после чего происходит запись шеллкода в конец этой секции.

  1. После успешно выполненного первого шага дроппер осуществляет поиск окна “Shell_TrayWnd

  2. После этого происходит вызов WinAPI функции GetWindowLong() для получения адреса оконного обработчика для окна “Shell_TrayWnd

  3. Далее происходит вызов функции SetWindowLong(), которая модифицирует “Shell_TrayWnd” данные ассоциированные с этим окном

  4. За тем следует вызов функции SendNotifyMessage() которая передает управление на шеллкод размещенный ранее в адресном пространстве процесса explorer.exe

После того, как функция SendNotifyMessage() будет выполнена обработчик окна “Shell_TrayWnd” и контроль передается по адресу, на который был получен при помощи вызова функции SetWindowLong(), на одном из предыдущих шагов. Этот адрес указывает на обработчик ntdll.KiUserApcDispatcher() который продемонстрирован на следующем рисунке:

После обработки ntdll.KiUserApcDispatcher() происходит передача управления непосредственно на шеллкод, который выглядит следующим образом:

Как видно из вышеприведенного рисунка шеллкод создает поток в контексте процесса explorer.exe и восстанавливает оригинальное значение, изменённое на предыдущей стадии при помощи вызова SetWindowLong(). После успешно созданного потока дропер переходит к следующей стадии выполнения связанной с повышением привилегий, так как процесс explorer.exe выполняется с привилегиями текущего пользователя. Подобный трюк использует довольно не стандартные функции для внедрения кода, что не дает возможности различным поведенческим анализаторам заподозрить не ладное и вовремя среагировать. У читателя может возникнуть закономерный вопрос, а как же обход ASLR на x64 системах, иначе шеллкод не найти в памяти процесса explorer.exe. Все верно, разработчики не стали заморачиваться и для поиска шеллкода используется не сложный ROP код. Подробно останавливаться на этом моменте я не буду, так как подобная методика уже не раз была описана в рамках статей Алексея Синцова об эксплуатации уязвимостей. А сейчас перейдем еще к одной интересной особенности Gapz, а точнее к внутреннему устройству буткит части.

Итак, прежде чем углубляться в детали, давайте рассмотрим схему, иллюстрирующую известные методологии заражения системы при помощи буткитов.

До момента обнаружения семейства Gapz самым передовым буткитом был Rovnix, который первым стал инфицировать VBR (Volume Boot Record). Но методология, использованная в Gapz еще более изощренная, поэтому в моем личном хит-параде буткитов лидером теперь является именно Gapz.

Итак, в последних модификациях Win32/Gapz происходит модификация VBR активного раздела. Происходит модификация только четырех байт оригинального VBR кода при помощи, которых передается управление на вредоносный код. Подобный подход к заражению делает Gapz довольно незаметным в системе и изменение всего лишь четырех байт затрудняют обнаружение этой угрозы стандартными способами. Суть подхода использованного в Gapz, является модификация только поля “Hidden Sectors”, а все остальные данные VBR и IPL (Initial Program Loader) остаются не тронутыми.

Давайте посмотрим на устройство активного раздела VBR:

VBR код ответственный за загрузку и IPL (initial program loader)

BIOS Parameter Block – структура данных хранящая параметры раздела NTFS

Text Strings – строковые константы для отображения в случае ошибки

• 0xAA55 – два байта сигнатуры начала VBR кода

Наиболее интересным местом для анализа VBR в нашем случае будет блок BPB (BIOS Parameter Block) в структуре которого находится поле “Hidden Sectors”. Значение этого поля содержат количество секторов предшествующих IPL хранящихся в томе NTFS.

Таким образом, VBR код считывает 15 секторов начиная с этого значения и передает управление на код буткита. Происходит замена значения количества секторов и теперь управление передается в другое место. Ак выглядит загрузочный код после заражения Win32/Gapz:

Еще одной интересной особенностью вредоносной программы Gapz, является то, что у нее отсутствует как токовое тело драйвера. А весь код загруженные в адресное пространство ядра представляет собой последовательности шеллкода. Нечто подобное уже было реализовано в TDL3 несколько лет назад. Отдельно стоит отметить, что подобный подход к загрузке вредоносного кода в ядро операционной системы автоматически обходит защитный механизм ELAM (Early Launch Anti-Malware Module) появившийся начиная c Windows 8. Так как вредоносный код оказывается загруженным в адресное пространство ядра значительно раньше, нежели происходит проверка ELAM.

Очевидно что ELAM оказывается бесполезным в случае активного буткит заражения, если драйвер или шеллкод оказался в ядре раньше защитных проверок.

В качестве итога по Gapz хочу отметить, что по-прежнему находятся новые способы разработки эффективных буткитов, а так же способов внедрения кода вопреки активному защитному ПО. По моему мнению, Win32/Gapz занял почетное второе место нашего рейтинга более чем заслуженно.

Win32/Sirefef

Эта угроза меня заинтересовала тоже довольно интересным и не стандартным методом внедрения кода системный процесс services.exe. Итак, давайте пройдемся по шагам алгоритма внедрения кода:

  1. На первом этапе происходит извлечение шеллкода хранящегося внутри дропера

  1. На этом этапе происходит непосредственное внедрение кода в services.exe (Service Control Manager). Граф потока выполнения шеллкода представлен ниже:

А функция внедрения кода в декомпилированом виде выглядит следующим образом:

  1. В последних версиях ZeroAccess использовал две техники внедрения кода:

— первый способ использовал трюк с вызовом ZwOpenThread()/ZwOpenProcess(), модификацией памяти и вызовом ZwQueueApcThread(). Этотметодиспользовалсядлязаражения x86 систем.

— Второй же способ использовался для заражения 64-битных систем и осуществляет модификации в файле Service Control Manager.

На следующем шаге второго способа внедрения кода происходит объекта секции посредством вызова ZwCreateSection() и копирование services.exe содержимого файла созданного на предыдущем этапе. После этого модифицируется код функции ScRegisterTCPEndpoint() и удаляется поддержка ASLR в этом модуле путем модификации соответствующего флага в PE-заголовке (это необходимо для стабильной работы шеллкода, так как он работает с заранее заданными адресами).

  1. Заключительным четвертым шагом является создание нового файла services.exe с оригинальным названием, но измененным внутри. Создание файла осуществляется при помощи вызова ZwCreateFile(), что позволяет заполнить расширенные атрибуты NTFS. Что позволяет указать в них путь к вредоносному dll-модулю. Этот модуль не хранится не посредственно в services.exe и загружается используя недокументированные особенности файловой системы NTFS.

Так выглядит модифицированная функция ScRegisterTCPEndpoint():

Win32/Sirefef интересный и сложный образец современных руткит-технологий. Авторы которых постоянно совершенствуют свое творение и добавляют нам хлопот с его обнаружением. Поэтому мы отдаем этой угрозе почетное третье место за нестандартные приемы использованные в процессе внедрения кода.

Win32/Festi

Так как место в журнале не резиновое, а я и так разошелся в описании предыдущих угроз, я не буду уделять много внимания Festi. Ведь совсем недавно (несколько номеров назад) была опубликована подробная статья, описывающая эту вредоносную программу. Скажу только, что Festi получает четвертое место нашего рейтинга за интересный подход в реализации ООП фреймворка внутри драйвера и бестелесную систему плагинов, которые не хранятся на диске. Подробности об этой вредоносной угрозе также можно найти в моем личном блоге (amatrosov.blogspot.com).

Win32/Rovnix

До появления семейства Gapz именно этот буткит был наиболее технологичным. В этом же году эта буткит платформа не претерпела больших изменений, а все обновления были направлены на затруднение обнаружения со стороны антивирусного ПО и доработки скрытой файловой системы. Таким образом, распаковщик основного тела буткита стал полиморфным. В общем виде это выглядит так:

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

Коснулись изменения и срытой файловой системы, в которой появилась возможность множественных внедрений кода, что позволяет устанавливать несколько вредоносных программ одновременно и контролировать их работу их драйвера в ядре операционной системы.

За все это Rovnix опять попал в наш рейтинг, но уже на последнее место, так как не содержит принципиальных нововведений, но при этом, не сильно утратив свою технологичность и эффективность.

В качестве заключения

Среди огромного потока угроз, который проходит через наши исследовательские центры по всему миру встречается не так много действительно интересных и не стандартных вредоносных программ, исследуя которые можно почерпнуть, что то новое. В этой статье я постарался собрать именно такие те, что меня самого увлекли за прошедший год. К примеру, на исследование Flame понадобилось несколько месяцев, чтобы получить более менее понятную картину и установить все взаимосвязи с его предшественниками на уровне кода. Будем надеяться в следующем году нам будет чем наполнить очередной технологическийрейтинг угроз ;)