Компания FortiGuard Labs столкнулась с вредоносным поддельным документом, выдающим себя за украинскую компанию "Энергоатом", государственное предприятие, управляющее атомными электростанциями Украины.
Havoc Demon Malware
Документ с макросом называется "zatverdzhenniy_spisok_osib_na_otrim", что в переводе означает "утвержденный список лиц для приема". Он прибывает в архиве ISO-образа с тем же именем. Впервые он был представлен на VirusTotal в середине марта этого года.
При его открытии появляется изображение, инструктирующее пользователя включить выполнение макрокода Word для раскрытия информации, якобы защищенной M.E. Doc (My Electronic Document). Эта популярная в Украине система управления документами используется для обмена важными и конфиденциальными документами с организациями (включая контролирующие органы) в электронном виде.
Размытое содержимое с логотипом "Энергоатома" отображается за инструкцией, создавая впечатление, что она защищает важную информацию. На самом деле это обычное изображение, размещенное на верхнем слое документа. Если перетащить его в сторону, то под ним окажется якобы защищаемая информация.
После включения макроса изображение исчезает, создавая впечатление, что критическая информация каким-то образом была раскрыта. Документ содержит объявление о списке людей, якобы утвержденных для получения защитного оборудования.
Чтобы усложнить анализ и попытаться избежать обнаружения, в коде VBA макроса используется несколько интересных приемов.
При попытке просмотреть или отладить код VBA в документе приложение Word завершает работу. Аналогично, когда состав документа анализируется с помощью oletools (пакет инструментов python, используемых для анализа файлов Microsoft OLE2), инструмент выдает несколько ошибок, включая потоковые файлы, которые были определены, но не присутствуют в архиве. Инструмент также сообщает об ошибке неправильной сигнатуры при попытке распаковать определенный поток внутри файла. Мы не подтвердили, привела ли одна из этих аномалий непосредственно к вышеупомянутому сбою. Тем не менее, oletools в конечном итоге извлек полный код вредоносного макроса VBA, предназначенный для выполнения документом.
В вероятной попытке сделать расположение макрокода менее очевидным, двоичный файл проекта VBA, содержащий фактический код VBA, перенаправляется на файл "EbDYTPZ.vEypm" вместо стандартного "vbaProject.bin". Эта ассоциация подробно описана в "word\_rels\ document.xml.rels" архива Office Open XML со следующей строкой:
1 2 3 | "<Relationship Id="rId1" Type="http://schemas.microsoft.com/office/2006/relationships/vbaProject" Target="EbDYTPZ.vEypm"/>". |
Как обычно, код VBA настроен на выполнение при открытии документа через события AutoOpen и Document_Open.
Как уже упоминалось, макрос начинает с удаления изображения наложения, которое внутри является объектом Shape с атрибутом Name "happy". Чтобы найти это изображение, он перебирает все объекты Shape в документе и удаляет объект с таким же именем.
Чтобы скрыть строки, которые он использует во время выполнения, он в основном использует простое кодирование, вычитая 35 из каждого символа исходной строки и кодируя результат в Base64. Кроме того, перед декодированием он использует другие операции, такие как инверсия строки и разделение символов.
В качестве антиотладочной техники при выполнении основной процедуры заражения используется функция Application.OnTime, обычно применяемая для планирования выполнения определенной процедуры VBA вместо ее прямого вызова. В данном случае она планирует немедленное выполнение функции "ostrategicy". При отладке эта строка кода выдает ошибку "Can't execute code in break mode", а затем прекращает выполнение.
Затем вредоносная программа проверяет, существует ли в системе закодированный путь "C:\Users\user\AppData\Local\Microsoft\Office\OfficeTelemetry.dll". Как будет показано далее, это тот же путь к файлу, куда будет записана полезная нагрузка. Такая странная деталь реализации заставляет нас думать, что это может быть незавершенная работа и тестовый образец, созданный для кампании по борьбе с угрозами, которая будет запущена в ближайшее время.
Файл по вышеуказанному пути выполняется, если он существует. В противном случае код извлекает полезную нагрузку, которая ловко хранится в виде узла с именем "TwXfx" в пользовательской части XML-документа.
Пользовательские части XML - это функция, которая была введена в формате Office Open XML. Она используется для хранения произвольных данных, к которым документ может получить программный доступ.
Чтобы добраться до данных полезной нагрузки, он начинает с перечисления всех объектов пользовательской части XML в документе, а затем проверяет, есть ли в них узел с именем "TwXfx". Этот узел содержит закодированную полезную нагрузку.
Хотя полезная нагрузка в этом документе хранится в одном узле, код VBA также поддерживает закодированную полезную нагрузку, разделенную на несколько узлов, что еще больше усложняет ее извлечение. На самом деле, прежде чем предположить, что данные хранятся в одном узле, он сначала проверяет, хранятся ли они в нескольких узлах. Для этого он пытается найти имя узла, в данном случае "TwXfx", с добавлением индекса, т.е. "TwXfx_0". Если узел существует, он переходит к поиску следующего, увеличивая индекс (например, TwXfx_1). Так повторяется до тех пор, пока не будет найден узел, что означает, что он достиг конца полезной нагрузки.
Как только узел найден, содержимое узла считывается, а его XML-теги удаляются. Кроме того, если в начале данных найдена строка "__b_", она также удаляется. Аналогично декодированию строк, двоичная полезная нагрузка извлекается путем декодирования данных с помощью Base64 и добавления 35. Только на этот раз полученные байты дополнительно декодируются с помощью xor 82. Декодированная полезная нагрузка представляет собой 64-битный исполняемый файл (.exe).
Хранение двоичного файла полезной нагрузки в качестве пользовательской XML-части документа - это техника, очень похожая на ту, что представлена в этом блоге с сайта mgeeky.tech. Даже на уровне кода есть поразительное сходство между кодом, используемым вредоносным документом, и тем, что представлено в этом блоге. Автор сайта предлагает частный инструмент, предоставляющий аналогичные возможности. Тем не менее, создатель этого вредоносного документа мог легко воспроизвести технику из общедоступного PoC, ссылка на который содержится в блоге. На рисунке 5 показано одно из нескольких сходств кода, наблюдаемых в функции поиска узла полезной нагрузки в документе.
После того, как полезная нагрузка декодирована, она записывается в жестко заданный путь "C:\Users\user\AppData\Local\Microsoft\Office\OfficeTelemetry.dll" и выполняется с помощью ShellExecute со следующей командной строкой:
1 | C:\Windows\System32\conhost.exe --headless |
1 | "C:\Users\user\AppData\Local\Microsoft\Office\OfficeTelemetry.dll" "" |
В конечном итоге это приводит к выполнению агента Havoc Demon.
Судя по имени файла двоичного файла полезной нагрузки, он пытается маскироваться под легитимный компонент Microsoft Office. Он даже подписан недействительным сертификатом portal.office.com.
Хотя этот файл имеет расширение DLL и содержит множество экспортов, он представляет собой отдельный EXE-файл.
После выполнения он размещает упакованную и сжатую полезную нагрузку в разделе .vdata памяти, выделенной для текущего процесса.
Хранение полезной нагрузки структурировано следующим образом:
- Смещение 0x0: Magic (8 байт)
- Смещение 0x8: флаг шифрования (0 = не шифруется, 3 = шифрование RC4).
- Смещение 0x9: флаг сжатия (0 = не сжато, 3 = сжатие LZNT1)
- Смещение 0xa: Ключ RC4 (64 байта)
- Смещение 0ffset 0x4a: Сжатый размер (4 байта)
- Смещение 0x4e: Размер без сжатия (4 байта)
- Смещение 0x52: длина строки конфигурации загрузчика (2 байта)
- Смещение 0x154: начало зашифрованной и сжатой конфигурации загрузчика и полезной нагрузки
После расшифровки и декомпрессии полезной нагрузки мы видим конфигурацию, разделенную трубкой, за которой следует собственно исполняемый шеллкод
Формат конфигурации загрузчика выглядит следующим образом:
Поле 1: Тип инъекции: Текущий процесс (1) или в новый процесс (2)
Поле 2: Флаг ожидания завершения потока инъекции перед завершением загрузчика (только для типа инъекции 1).
Поле 3: Процесс для инъекции (только для типа инъекции 2)
Поле 4: Процесс для инъекции (только для типа инъекции 2)
Поле 5: Флаг для записи пустого файла в %TEMP% после успешной инъекции.
Поле 6: Таймаут ожидания, используемый для событий Windows в коде
Поле 7: Используемый флаг Unknown (только для инъекций типа 1)
Поле 8: Флаг для включения обфускации сна после создания инжектированного потока (только для инъекций типа 1)
Поле 9: Флаг для включения обфускации сна через отдельный поток
Поле 10: Флаг для включения обфускации сна
Поле 11: Флаг для исправления API
После разбора конфигурации этот загрузчик добавляет заглушку, содержащую 79 байт нежелательных инструкций, перед собственно шеллкодом полезной нагрузки. Байты с 25 жестко закодированными смещениями в этой заглушке заменяются случайными байтами, чтобы затруднить обнаружение шеллкода.
Перед попыткой запуска полезной нагрузки он сначала убеждается, что файл в каталоге %TEMP% не существует. Имя этого файла формируется из значения, вычисленного из hour / 3 + year + month + day текущего времени. Следовательно, полезная нагрузка будет выполняться не более 8 раз в день.
Для запуска шеллкода загрузчик вызывает ZwCreateThreadEx для создания нового приостановленного потока инъекции, скрытого от отладчиков, используя флаги создания потока THREAD_CREATE_FLAGS_CREATE_SUSPENDED (0x01) и THREAD_CREATE_FLAGS_HIDE_FROM_DEBUGGER (0x4). Сняв флаг THREAD_CREATE_FLAGS_HIDE_FROM_DEBUGGER перед вызовом ZwCreateThreadEx и используя точки останова памяти, шеллкод можно отлаживать обычным способом, когда поток возобновит выполнение.
Хотя в данном примере эта функция не включена, загрузчик также поддерживает обфускацию сна, чтобы затруднить обнаружение сканерами памяти. Для этого он перенаправляет вызовы Windows Sleep API в свою собственную функцию, которая выполняет следующее:
- Приостанавливает все потоки в текущем процессе
- Возвращает исправленные байты кода API Sleep.
- Возвращает исправления к API безопасности (только если исправления были настроены)
- Кодирует чувствительные области памяти в текущем процессе с помощью рандомизированного XOR-ключа.
- Вызывает Sleep с заданным таймаутом
- Декодирует чувствительные области памяти в текущем процессе с помощью того же XOR-ключа.
- Патчит API, связанные с безопасностью, для их отключения
- Патчит Sleep для повторного перенаправления к этой функции
- Возобновляет все потоки в текущем процессе
Исправленными API являются:
- WldpQueryDynamicCodeTrust в wldp.dll
- AmsiScanBuffer в amsi.dll
- EtwEventWrite в ntdll.dll
Интересно, что известные имена полей конфигурации Cobalt Strike также встречаются в открытом тексте в образце, возможно, чтобы запутать инструменты статического анализа.
Второй этап состоит из шеллкода с прикрепленной к нему DLL Havoc C2 agent. Havoc C2 framework - это набор инструментов для постэксплойта с открытым исходным кодом, разработанный компанией C5pider и состоящий из следующих компонентов:
Демонический агент: Развертывается на зараженных машинах и взаимодействует с настроенным сервером Teamserver
Teamserver: Командно-контрольный (C2) сервер, который управляет коммуникациями с агентами.
Клиент: Используется агентом(ами) угрозы для подключения к серверу Teamserver для управления и выдачи команд подключенным агентам. Поскольку клиент не развертывается как часть инфекции, он не будет обсуждаться далее в этой статье.
Шелл-код ищет байты 0x4d 0x5a и 0x50 0x45, обозначающие заголовки "MZ" и "PE" исполняемого файла Windows PE, чтобы найти полезную нагрузку в памяти. Затем он вызывает загрузчик (в исходном коде он называется KaynLdr).
KaynLdr разрешает нативные API LdrLoadDll, ZwAllocateVirtualMemory и NtProtectVirtualMemory с помощью хэширования API, прежде чем использовать их для выделения памяти, загрузки полезной нагрузки агента Демона и выполнения непосредственно из памяти.
Соответствующие хэши API следующие:
- LdrLoadDll: 0x9e456a43
- NtAllocateVirtualMemory: 0xf783b8ec
- NtProtectVirtualMemory: 0x50e92888
DLL, загружаемая KaynLdr, является агентом Havoc Demon, который является аналогом Beacon для популярного фреймворка Cobalt Strike. Конфигурация встроена в образец Demon.
Demon взаимодействует с сервером C2, указанным в конфигурации, через HTTP или HTTPS POST-запросы. Рандомизированный 256-битный ключ и 128-битный IV генерируются и передаются серверу C2 при первом запросе на регистрацию (Рисунок 11) для шифрования последующих данных, передаваемых между агентом и сервером C2, с помощью AES-256-CTR.
Соответствующие поля в запросе на регистрацию следующие:
1. Размер пакета данных
2. Магическое значение: 0xDE 0xAD 0xBE 0xEF (жестко закодировано в Havoc).
3. Идентификатор агента
4. ID команды: 0x63 (DEMON_INITIALIZE)
5. 32-байтовый ключ AES
6. 16-байтовый AES IV
7. Зашифрованные AES данные
Хотя Demon может быть настроен на ротацию между несколькими доменами C2, для данного образца указан только один домен C2, "ukrtatnafta[.]org". Этот домен очень похож на ukrtatnafta[.]com, принадлежащий "Укртатнафте", украинской нефтеперерабатывающей компании.
Чтобы смешаться с легитимным HTTP/HTTPS-трафиком, Demon случайным образом выбирает один из нескольких URI, заданных в конфигурации, и применяет указанный список HTTP-заголовков в запросах к C2. Конфигурация C2 сервера Teamserver, извлеченная из этого образца, показана ниже.
- Host: ukrtatnafta[.]org:443
- HTTPS: True
- Proxy enabled: No
- Method: POST
- Headers:
- Content-Type: application/javascript
- Pragma: public
- ETag: W/736fh0-3e
- Last-Modified: Mon, 05 Dec 2016 14:54:50 GMT
- Server: nginx/1.14.2
- Connection: keep-alive
- Expires: Mon, 06 Mar 2023 13:23:47 GMT
- User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36
URIs:
- /wp-content/themes/pressa/js/avias.js
- /wp-content/themes/pressa/js/mobile_menu.js
- /wp-content/plugins/contact-form-7/includes/js/scripts.js
- /wp-content/themes/pressa/js/bootstrap.js
- /wp-content/themes/pressa/js/hovermenu.js
- /wp-content/themes/pressa/js/retina-1.1.0.js
- /wp-content/plugins/js_composer/assets/lib/bower/isotope/dist/isotope.pkgd.min.js
- /wp-content/themes/pressa/js/custom-script.js
- /wp-includes/js/wp-emoji-release.min.js
- /maps-api-v3/api/js/52/1/intl/uk_ALL/util.js
- /wp-includes/js/wp-embed.min.js
Основные функции Demon включают:
- Перечисление информации о хосте и сети (пользователи, группы, домены, общие ресурсы и т.д.).
- Выполнение команд через командную строку
- Выполнение команд PowerShell
- внедрение и выполнение DLL, шеллкода, сборок .NET, файлов Cobalt Strike BOF
- Манипулировать процессами (список, создание, поиск, уничтожение и т.д.)
- Манипулировать файлами и каталогами (список, скачивание, загрузка, просмотр, удаление и т.д.)
- Манипулировать токенами доступа (кража, выдача себя за другого и т.д.)
- Делать скриншоты
URLs
- https://ukrtatnafta.org
- https://ukrtatnafta.org/maps-api-v3/api/js/52/1/intl/uk_ALL/util.js
- https://ukrtatnafta.org/wp-content/plugins/contact-form-7/includes/js/scripts.js
- https://ukrtatnafta.org/wp-content/plugins/js_composer/assets/lib/bower/isotope/dist/isotope.pkgd.min.js
- https://ukrtatnafta.org/wp-content/themes/pressa/js/avias.js
- https://ukrtatnafta.org/wp-content/themes/pressa/js/bootstrap.js
- https://ukrtatnafta.org/wp-content/themes/pressa/js/custom-script.js
- https://ukrtatnafta.org/wp-content/themes/pressa/js/hovermenu.js
- https://ukrtatnafta.org/wp-content/themes/pressa/js/mobile_menu.js
- https://ukrtatnafta.org/wp-content/themes/pressa/js/retina-1.1.0.js
- https://ukrtatnafta.org/wp-includes/js/wp-embed.min.js
- https://ukrtatnafta.org/wp-includes/js/wp-emoji-release.min.js
SHA256
- 17637fac7f989549acd248ca9e5293d2b9a1a2e4bb0f7e4edf5571df35129f0c
- 9f797d705facebd1687b7765cbf65231e71821eb3c38dcc171a3fc88b9f52328
- b6cb8a7cdce0bfd3a7402d22fb0014dedb259d6c91c1538ac74097b8ca22ca5c
- b773fa65bb375e6fe6d387f301f6bf33219189ea1d4a06762e965a9eba7de4e8