Опасное приглашение, или Как работает боевая нагрузка к фишинговому письму
Недавно специалисты PT ESC обнаружили документ формата Publisher с названием «Приглашение 29–30 ноября 2018.pub» (1edd5b6a02ec82cec381c1a1ec74a67e). В этом материале мы расскажем, как обычный с виду документ превращается в троян, позволяющий злоумышленнику захватывать изображение с веб-камер, записывать звук по команде или при обнаружении окна Skype, запускать PowerShell-скрипты, делать скриншоты экрана, копировать файлы с медиаустройств.
Итак, при открытии документа появляется окно с размытым документом-заглушкой и просьбой включить скрипт Microsoft Publisher.
После того как пользователь его включит, исполнится встроенный в документ сценарий на JavaScript. Выглядит он так:
Результатом работы скрипта будет раскодирование двух файлов, PDF и EXE, из Base64. Оба файла будут записаны по адресу C:\Users\{Username}\AppData\Roaming\DBFUpdate. Соответственно, оба файла исполнятся, и пользователь увидит на экране документа такую заглушку:
Treasure Hunter RAT
Злоумышленники используют многомодульный RAT с большим набором функций, который предоставляет полный доступ к зараженной машине.
Особенности кода:
- Целиком написан на С++ с большим количеством STL-конструкций, которые используются внутри.
- Применение библиотеки boost, в частности JSON и Archive.
- Отладочные функции (подробнее в секции, посвященной stager).
Основной троян
Основной троян закрепляется на машине жертвы и представляет из себя платформу, на которую загружаются из С2 вредоносные модули.
Сначала stager инициализирует рабочую директорию, в которой впоследствии будут храниться собранная модулями информация, утилиты, необходимые для работы модулей, и т. п.
Ниже — инициализация путей для создания рабочей директории:
После того как созданы необходимые директории, основной троян осуществляет сбор информации о зараженной машине и отправляет ее на контрольный сервер.
Троян интересуется такими данными:
- идентификатором версии ОС, на которой запущен основной троян;
- установленным по умолчанию языком интерфейса;
- старшим номером версии Service Pack ОС;
- именем компьютера и идентификатором машины (подробнее о получении идентификатора машины — в разделе, посвященном сетевому протоколу).
Так происходит сбор информации о зараженной машине:
Далее основной троян закрепляется на зараженной машине через модификацию значения в реестре по адресу HKCU\Environment\UserInitMprLogonScript. Здесь прописывается имя исполняемого файла, которое было выделено при инициализации рабочей директории, в этом случае оно равно «DCTHOST.exe». Данный способ описан в блоге Hexacorn, a также использовался APT28 и группой Cobalt в их ComDLLDroper.
И последний шаг в инициализации основного трояна — копирование исполняемого файла из его текущего местоположения в рабочую директорию с таким же именем, какое было выделено при инициализации рабочей директории.
После того как основной троян инициализирован, осуществляется подготовка к приему команд. В cписок запущенных модулей добавляется модуль Core, коим и является основной троян. Далее запускается команда из модуля Core c идентификатором 0. Реализация данной команды в основном модуле отсутствует, вместо нее просто заглушка. Конструктор объекта модуля Core представлен ниже.
В конце происходит запуск двух потоков. Один из потоков запускает таймер, который просыпается по умолчанию каждую секунду и пытается запросить команду у С2.
Второй поток осуществляет загрузку дополнительных библиотек и стандартных модулей. Библиотеки, как и модули, имеют идентификатор, но в отличие от модулей идентификаторы библиотек отрицательные, начинаются с –1, растут в сторону меньших чисел. Ниже — список библиотек, загружаемых с С2.
Отладочные функции основного трояна
В самом начале своей работы, сразу после инициализации, основной троян устанавливает обработчик исключений через SetUnhandledExceptionFilter, который содержит в себе интересную функциональность. При возникновении исключений они попадают в обработчик, который записывает минидамп приложения, сохраняя также информацию об исключении. После чего перезапускает сам себя. На скришоте — создание минидампа:
Сетевой протокол
Обмен между ПО и С2 происходит с помощью самописного бинарного протокола. Каждое сообщение описывается с помощью BinPackage (название взято из RTTI). Каждый BinPackage по своей сути является оберткой над std: vector, который хранит в себе набор PackageRecord (название выдумано). PackageRecord является минимальной единицей для хранения данных.
struct PackageRecord
{
_DWORD dataId;
_DWORD datatype;
_DWORD szData;
char[] data;
};
Подробнее о полях этой структуры:
- dataId — указывает на тип записи. Либо запись является идентификатором модуля, либо идентификатором команды, либо полезной нагрузкой.
- szData — размер данных, хранимых в записи.
- datatype — тип данных.
Всего было зафиксировано использование трех типов данных:
- Значение »0» — означает, что данные, хранимые в записи, необходимо интерпретировать как DWORD.
- Значение »1» — данные, хранимые в записи, необходимо интерпретировать как ASCIIZ-строку.
- Значение »2» — данные, хранимые в записи, необходимо интерпретировать как зашифрованные данные/raw buffer.
При отправке BinPackage на контрольный сервер к нему добавляется идентификатор машины. Идентификатор представляет из себя GUID раздела, из которого вырезаются все спецсимволы. На рисунке — получение идентификатора машины:
Перед отправкой все записи, хранящиеся в BinPackage, собираются последовательно в единый буфер и подвергаются шифрованию. Для шифрования используется библиотека WinAES, а конкретно AES-128-CBC.
С помощью CryptoAPI Windows генерируются два псевдослучайных массива размером 16 байт. Один для IV, другой для ключа. Выполняется шифрование, и зашифрованные данные складываются обратно в BinPackage, который содержит зашифрованный пакет и состоит из трех записей:
- запись с ID 0×777 — содержит в себе ключ, использованный для шифрования;
- запись с ID 0×555 — содержит в себе IV, использованный для шифрования;
- запись с ID 0×999 — содержит в себе зашифрованные данные (в общем виде запись с таким ID обозначает полезную нагрузку и используется не только для хранения зашифрованных данных).
После окончания процесса шифрования сформированный BinPackage опять собирается в единый буфер и отправляется через HTTP POST-запрос на управляющий сервер 151.80.237.222.
Ниже — пример пакета, содержащего информацию о машине:
А это пример зашифрованного пакета с информацией о системе:
Модули
Каждый модуль, за исключением Core, загружается с контрольного сервера. Все модули можно разделить на две категории — модули, загружаемые автоматически, и модули, загрузка которых осуществляется по запросу с контрольного сервера.
Пример пакета, запрашивающего модуль:
Ответ на запрос модуля:
Каждый модуль имеет простой интерфейс, состоящий из трех функций: вызываемой при загрузке модуля Init, вызываемой при завершении fini и функции, изменяющей конфигурацию модуля. Также каждый модуль обладает экспортом c именем GetModule, который строит объект, представляющий данный модуль, и возвращает его основному трояну. Все обнаруженные нами модули запускаются в памяти с помощью рефлективной загрузки.
Далее названия модулей даны в том виде, в котором они присутствуют в RTTI как имена классов.
Модуль CCore
Данный модуль представляет базовую функциональность и встроен непосредственно в основной троян. Его конструктор можно увидеть в таблице ниже:
ID модуля | ID команды | Описание |
---|---|---|
0 | 0 | В основном трояне вместо команды заглушка, и точное ее назначение установить не удалось |
1 | Изменить конфигурацию модуля | |
2 | Запросить информацию о компьютере | |
3 | Скачать утилиту с контрольного сервера | |
4 | Запросить листинг директории, содержащей утилиты | |
5 | Загрузить модуль и выполнить его |
Модуль CShell
Данный модуль предоставляет удаленный шелл на зараженную машину. При инициализации модуля создается процесс cmd.exe, к которому прикрепляются два пайпа: один для стандартного ввода и один для стандартного вывода, через которые осуществляются прием и передача команд от контрольного сервера и обратно. Также в этот момент запускается поток, который автоматически забирает весь вывод и отправляет его на контрольный сервер. На рисунке — инициализация модуля СShell.
ID модуля | ID команды | Описание |
---|---|---|
2 | 0 | Послать команду в шелл |
1 | Вывести файл. Читается файл, путь до которого передается с контрольного сервера, и содержимое этого файла загружается на контрольный сервер | |
2 | Получить список всех дисков, существующих в системе. Данные отправляются на контрольный сервер в формате JSON | |
3 | Загрузить файл с контрольного сервера. Путь, куда сохранить файл, и данные получаются с контрольного сервера |
Модуль CFileSystemBrowser
Это пассивный модуль, который по запросу позволяет получать информацию о структуре файловой системы. Так происходит инициализация модуля CFileSystemBrowser:
ID модуля | ID команды | Описание |
---|---|---|
3 | 0 | Получить список всех дисков, существующих в системе. Данные отправляются на С2 в формате JSON |
1 | Получить листинг директории. Листинг формируется в формате JSON | |
2 | Вывести файл. Читается файл, путь до которого передается с С2, и содержимое этого файла загружается на С2 | |
3 | Удалить файл. Путь до файла передается с С2 |
Модуль CScreenShot
Данный модуль позволяет создавать скриншоты экрана или захватывать изображение с веб-камеры. Может это делать как по запросу, так и с определенным периодом по таймеру.
ID модуля | ID команды | Описание |
---|---|---|
4 | 0 | Сделать скриншот и отправить его на контрольный сервер |
1 | Запустить таймер, после срабатывания которого осуществляется снятие скриншота с экрана машины. Полученные скриншоты упаковываются в BinPackage и сохраняются в папку logs. Имена для файлов генерируются с помощью API GetTempFileName с префиксом «MS_». | |
2 | Получить видео устройств, доступных на зараженной машине | |
3 | Захватить кадр с веб-камеры и отправить его на контрольный сервер |
Модуль CSender
Данный модуль изначально не активирован. Осуществляет загрузку содержимого папки logs на контрольный сервер. Активируется тогда, когда приходит запрос на смену конфигурации, в котором содержится период проверки.
Модуль CKeylogger
Данный модуль также изначально не активирован. Он активируется тогда, когда приходит запрос на смену конфигурации, содержащий размер буфера, в котором хранится лог. Перехват ввода осуществляется через rawinput. Помимо этого, кейлоггер отслеживает окно, в котором пользователь производит ввод, и логирует его заголовок.
Модуль CDictaphone
Данный модуль осуществляет запись звука по команде или при обнаружении окна Skype. При запуске запускает поток, который перечисляет все окна и их дочерние окна в системе и ищет среди классов окно, имя класса у которого равно TLiveConversation или TCallMonitorControl. Если такое окно было найдено, начинается запись. Ниже — инициализация модуля CDictaphone:
И поиск окна Skype
Запись осуществляется через MCI путем отправки специальных команд. Так выглядит цикл записи модуля CDictaphone:
После закрытия окна или поступления команды на завершение записи полученные данные сохраняются во временную папку, после чего кодируются MP3-кодировщиком lame (он считается утилитой и должен быть уже загружен, заполучить его с контрольного сервера не удалось). Закодированный файл сохраняется в папку logs. Генерация имени папки аналогична генерации имен для скриншотов.
ID модуля | ID команды | Описание |
---|---|---|
7 | 0 | Начать запись и завершить ее по прошествии 15 минут |
1 | Остановить запись | |
2 | Проверить статус: ведется ли сейчас запись |
Модуль CProcessesManager
Это пассивный модуль, по запросу способный вернуть список процессов или завершить по переданному ему PID.
ID модуля | ID команды | Описание |
---|---|---|
8 | 0 | Возвращает список процессов: их имена, PID и имя пользователя который является владельцем процесса. |
1 | Завершение процесса по PID |
Модуль CDownloader
Модуль предназначен для загрузки больших файлов на контрольный сервер. Осуществляет передачу данных чанками, размер которых устанавливается его конфигурацией. Модуль читает данные из файла, путь до которого он получает с контрольного сервера, а чанки упаковывает в BinPackage. К каждому BinPackage, содержащему чанк, добавляется запись с идентификатором 0×888, включающая путь до файла. После передачи каждого чанка осуществляется sleep на 5 секунд.
ID модуля | ID команды | Описание |
---|---|---|
9 | 0 | Заглушка, точное значение установить не удалось |
1 | Осуществляет передачу большого объема данных (0×500000 байт), после чего замеряет время, потраченное на передачу, и отправляет это значение на С2 | |
2 | Осуществляет загрузку файла с машины |
Модуль CPS
Данный модуль позволяет запускать PowerShell-скрипты.
ID модуля | ID команды | Описание |
---|---|---|
10 | 0 | Получает с С2 PowerShell-скрипт и выполняет его |
Модуль CDeviceMonitor
Пассивный модуль, который осуществляет мониторинг подключаемых медиаустройств и копирует с них файлы. Для обнаружения подключения устройств использует широковещательные сообщения WM_DEVICECHANGE. После подключения устройства на контрольный сервер отправляется информация о том, когда было подключено устройство, его метка тома и путь до устройства. Код, используемый для получения пути до устройства, очень похож на этот. Все файлы копируются в папку logs. Имена генерируются так же, как для скриншотов. Отдельно создается файл fsIndex.dat, в котором находится сериализованный с помощью boost: archive словарь. Этот словарь хранит оригинальные пути до файлов, которые были скопированы, и их MD5-хеши. Ниже — получение DevicePath:
В качестве эпилога несколько рекомендаций:
- Не надо открывать вложения в письмах от неизвестных адресатов и тем более включать скрипт Microsoft Publisher.
- Не менее опасно кликать по ссылкам в письмах неизвестных отправителей. На сайте, куда вы перейдете, может размещаться вредоносное ПО, которое автоматически загрузится на ваш ПК.
- Необходимо регулярно обновлять ПО, особенно Microsoft Windows и Microsoft Office, что позволит закрыть доступ для широкого спектра вредоносного ПО.