В мире вредоносного программного обеспечения, где скорость обнаружения и реагирования имеет ключевое значение, способность угрозы оставаться незамеченной в течение многих месяцев является тревожным показателем. История GhostWeaver, сложного инструмента удалённого администрирования (RAT), построенного на PowerShell, ярко иллюстрирует этот тренд. Этот вредоносный инструмент, активно используемый группировкой, отслеживаемой аналитиками Mandiant как UNC4108, демонстрирует изощрённый подход к закреплению в системе, уклонению от систем безопасности и организации скрытого командного канала, что привело к компрометации тысяч систем. Проблема усугубляется тем, что многие стандартные средства защиты, включая корпоративные DNS-фильтры, оказываются неэффективными против его тактик.
Описание
Согласно подробному исследованию, GhostWeaver представляет собой «файловую» вредоносную программу, не оставляющую артефактов на диске. Его основная коммуникация с сервером управления осуществляется через нестандартный порт 25658 с использованием устаревшей версии протокола TLS 1.0, что само по себе является попыткой обойти системы обнаружения вторжений (IDS), настроенные на анализ современного трафика. Полезная нагрузка передаётся в виде JSON-объектов, сжатых алгоритмом GZip. Интересно, что антивирусные вендоры часто детектируют эту угрозу под названием Pantera, что указывает на давнюю историю её развития. Группа исследователей TRAC Labs в феврале 2025 года присвоила ей собственное имя - GhostWeaver.
Жизненный цикл атаки начинается не с прямого внедрения RAT, а с тщательной разведки и фильтрации целей. Инициатором выступает другая угроза - так называемый распределитель трафика (TDS) TAG-124, также известный как ParrotTDS или SocGholish. Он внедряется на скомпрометированные сайты на WordPress и показывает посетителям поддельные окна с предложением обновить браузер. При согласии пользователя загружается JavaScript-степпер, который, в свою очередь, запускает PowerShell. Далее в дело вступает загрузчик MintsLoader, который выполняет профилирование системы. Он проверяет наличие виртуальной машины, тип графического процессора и архитектуру кэша центрального процессора, присваивая цели числовой «счёт». Если система выглядит как реальный компьютер пользователя (низкий счёт), загружается GhostWeaver. Если же обнаружены признаки песочницы или виртуальной среды (высокий счёт), жертве подсовывается безобидная программа-пустышка или происходит перенаправление, что позволяет злоумышленникам избегать анализа.
Ключевой особенностью GhostWeaver является его система генерации доменных имён (DGA). Вредоносная программа использует целых четыре различных алгоритма DGA на разных этапах своей работы, что значительно усложняет блокировку. В частности, для выхода на командный сервер применяется алгоритм, генерирующий новое доменное имя каждую неделю. Однако самое опасное заключается в том, как GhostWeaver обходит традиционные средства защиты. Он не полагается на локальные DNS-серверы, которые могут находиться под контролем корпоративной политики безопасности. Вместо этого в его код жёстко вшиты адреса публичных DNS-резолверов, таких как Hurricane Electric, OpenDNS и Cloudflare. Это позволяет программе отправлять запросы на разрешение своих DGA-доменов напрямую, минуя корпоративные фильтры и системы анализа DNS-трафика. Таким образом, даже если доменное имя присутствует в чёрном списке на внутреннем сервере, вредоносная программа его просто не спросит.
После установления соединения с сервером управления GhostWeaver демонстрирует высокую степень автоматизации. Исследователи, подключившись к активным командным серверам, обнаружили, что те практически мгновенно - в течение 170 миллисекунд - отвечают на приветственный сигнал (beacon) отправкой установщика для закрепления в системе. Установщик, который антивирусные движки на VirusTotal почти не детектируют, обладает продвинутыми функциями. Он использует метод обхода контроля учётных записей (UAC) через уязвимость в COM-объекте CMSTPLUA и маскирует свой процесс под explorer.exe, модифицируя структуру PEB (Process Environment Block) в памяти. Для обеспечения постоянного присутствия создаётся скрытая запланированная задача, которая запускает полезную нагрузку каждые три минуты. Установщик предлагает на выбор четыре различных режима закрепления, причём логика выбора зависит от обнаруженного на системе антивирусного продукта, что говорит о тщательной адаптации под среду жертвы.
Данные о масштабах операции частично раскрываются в контексте другой кампании этой же группировки, нацеленной на пользователей распределённой вычислительной платформы BOINC. По данным компании Huntress, только через эту кампанию было скомпрометировано более 10 000 машин. Долгое время пребывания вредоносной программы в системе - в одном из случаев расследование показало, что скомпрометированная рабочая станция подавала сигналы на сервер управления каждые три минуты на протяжении 13 месяцев до обнаружения - указывает на серьёзные пробелы в мониторинге сетевой активности. Это не обязательно был сбой системы обнаружения; скорее, политики безопасности разрешали исходящие соединения на нестандартные порты без должной проверки.
Для специалистов по информационной безопасности история GhostWeaver содержит несколько критически важных уроков. Во-первых, традиционная защита на уровне DNS-фильтрации может быть полностью нейтрализована, если вредоносная программа использует собственные резолверы. Это подчёркивает необходимость применения стратегии нулевого доверия (Zero Trust) к сетевым подключениям, когда исходящий трафик блокируется по умолчанию и разрешается только для предварительно одобренных и проверенных сервисов. Во-вторых, мониторинг сетевой активности должен включать анализ соединений на нестандартные порты, особенно с использованием устаревших криптографических протоколов, таких как TLS 1.0. В-третьих, файловые угрозы, выполняющиеся в памяти, требуют продвинутых методов обнаружения, основанных на поведенческом анализе и отслеживании подозрительной активности PowerShell, а не только на сигнатурах файлов. Наконец, долгий dwell time (время пребывания угрозы в системе) указывает на важность регулярного проактивного поиска угроз (threat hunting), направленного на выявление скрытых аномалий, которые могли быть пропущены автоматизированными системами.
Индикаторы компрометации
IPv4
- 104.200.73.68
- 104.238.34.204
- 104.238.61.8
- 157.180.9.209
- 167.17.76.102
- 167.17.76.31
- 178.156.128.182
- 192.169.6.190
- 5.161.113.150
- 5.161.214.209
- 5.161.229.58
- 64.49.13.171
- 64.52.80.211
- 64.7.199.144
- 66.23.193.124
- 86.107.101.93
Domains
- 0f2onmxtqv5ih2h.top
- 9hsawit1nbfbg9e.top
- amatua.org
- cup4fqhvsolr3xq.top
- email.zimbraservices.net
- ga1yo3wu78v48hh.top
- happychristmas.click
- q632gmdjjxpjsqp.fun
- rosettahome.cn
- rosettahome.top
- spo1.servers.guru
- spo2.servers.guru
- spo3.servers.guru
- spo4.servers.guru
- v5fcvlydx1cjsgf.top
- zimbraservices.net
SHA1
- 006f5bb92720aca33aab33505e17c42cc2f9f236
SHA256
- 12dbcf61cfbfa903c0224e27803d8e94075eb0023037d7d1d2a832dcad08aed0
- 1a0abc0235744543ced5ffce406375a3ab5e1c7953865baa471cc69116960ee3
- 253cfd712e819991ad07acec38b8afbf9bf07acb43faf7a998ce74605595f28c
- 269f99b5e172a37074a8ad1c95b76b6066e01a03e507e580949c34633469e37e
- 2dd4dba195a2994751e11f855a1a4d9f6ca384867b8e5f62b0e692729603fe05
- 32879fb539171628354e59868de1c9dca363be9c1b5bb9ca3f915b9042bd506b
- 3b868b5ac32114ebd3e995a3adb6d6fbbb91440820cf921f73afd41e11249456
- 4b7815407c14ddc776cf2b2a3a20b2e8b7d78c7b7a06d72d4934abe09cb895f7
- 9076d50f2bbe05164da6ebf077f471de9ddc46afbfb2f819f550231d12489d20
- 93fd8688d406f11554cc2e64b62b1bc35979ef8e2711ac7212ab7e4016521687
- a08eb452f289a6260786fe375cddb1bc009ac8556b7af6316ffc912c7dd31857
- a373fdaa1be3b46a88487d6839f5ff8332380ed9c93a8cb1439f43a0440d2e0a
- aa9bc093018e55b23fbb4d9548c4140a3f59162a216ba2df6c82691533dcb435
- bb06ef8bcfb7037e436710e81f5f4d9feaff97bdf46f2b1320ae8cf0fcee457d
- c2071569d65449e02722b02c5cb6b365dcf52ee5df5a7ffac779751405cdcfaf
- e354c5e4db754a83d4e81aa8777d5685c8451ac0eea1120783f0be024f656e61
- fb0238b388d9448a6b36aca4e6a9e4fbcbac3afc239cb70251778d40351b5765
YARA
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | rule GhostWeaver_PS1_Obfuscated { meta: id = "4yK2n9g8FzSWbGDNR8CDEB" fingerprint = "30999b8e0e0921d43835dfac174c058c046ff04835f999b137a895cfc4fd3ba5" version = "1.0" date = "2026-03-08" modified = "2026-03-08" status = "RELEASED" sharing = "TLP:CLEAR" source = "HTTPS://WWW.DERP.CA/BLOG/GHOSTWEAVER-TAG124-POWERSHELL-RAT" author = "derp.ca" description = "GhostWeaver/Pantera RAT - obfuscated PowerShell builder output" category = "MALWARE" malware = "GHOSTWEAVER" mitre_att = "T1059.001" reference = "https://www.derp.ca/blog/ghostweaver-tag124-powershell-rat" triage_score = 10 triage_description = "GhostWeaver/Pantera RAT obfuscated PowerShell builder output detected." strings: $builder_stamp = /\$global:keystr=streams\\[0-9]{3}\\stub\\[0-9]{8,15}/ ascii wide $arith_decoder1 = "[system.String]::new(@((" ascii wide nocase $arith_decoder2 = "[char[]]@((" ascii wide nocase $arith_sep = "),(" ascii wide $exec_ctx = "$executioncontext" ascii wide nocase $join_op = "-join ''" ascii wide condition: filesize > 200KB and filesize < 1MB and ( $builder_stamp or ( ($arith_decoder1 or $arith_decoder2) and #arith_sep > 500 and $exec_ctx and $join_op ) ) } |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | rule GhostWeaver_PS1_Decoded { meta: id = "4gcK8OxIKebmDMhHw8lPiz" fingerprint = "02f00e7859c9852f022babbe93938651acf2eab3dc4f1c026b6b85d869cd6490" version = "1.0" date = "2026-03-08" modified = "2026-03-08" status = "RELEASED" sharing = "TLP:CLEAR" source = "HTTPS://WWW.DERP.CA/BLOG/GHOSTWEAVER-TAG124-POWERSHELL-RAT" author = "derp.ca" description = "GhostWeaver/Pantera RAT - decoded PowerShell (memory or post-deobfuscation)" category = "MALWARE" malware = "GHOSTWEAVER" mitre_att = "T1059.001" reference = "https://www.derp.ca/blog/ghostweaver-tag124-powershell-rat" triage_score = 10 triage_description = "GhostWeaver/Pantera RAT decoded PowerShell payload detected." strings: $proto_ssl = "SslStream" ascii wide nocase $proto_gzip = "GzipStream" ascii wide nocase $proto_json_in = "ConvertFrom-Json" ascii wide nocase $proto_json_out = "ConvertTo-Json" ascii wide nocase $proto_sslproto = "SslProtocols" ascii wide nocase $beacon = "'ClientInfo'" ascii wide $cmd_iex = "'iex'" ascii wide $cmd_plugin = "'plugin'" ascii wide $cmd_selfdelete = "'selfdelete'" ascii wide $cmd_saveplugin = "'savePlugin'" ascii wide $cmd_sendplugin = "'sendPlugin'" ascii wide $mutex = "euzizvuze" ascii wide $port = "25658" ascii wide $dga_random = "System.Random" ascii wide nocase $dga_doy = "DayOfYear" ascii wide nocase $dga_tld_top = ".top" ascii wide $dga_tld_fun = ".fun" ascii wide $dga_tld_xyz = ".xyz" ascii wide $dga_tld_cn = ".cn" ascii wide condition: (2 of ($proto_*)) and ( ($beacon and 3 of ($cmd_*)) or ($mutex and $port and $dga_random and $dga_doy and 3 of ($dga_tld_*)) or (4 of ($cmd_*) and $mutex) ) } |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | rule GhostWeaver_Persistence_Installer { meta: id = "5JZRC0pj4MOxL8jRH8TIdt" fingerprint = "41f3bcd5aae841a7d831853422f12593f6f9a8e7f492f4f24c54496f4ae1939e" version = "1.0" date = "2026-03-08" modified = "2026-03-08" status = "RELEASED" sharing = "TLP:CLEAR" source = "HTTPS://WWW.DERP.CA/BLOG/GHOSTWEAVER-TAG124-POWERSHELL-RAT" author = "derp.ca" description = "GhostWeaver/Pantera persistence installer delivered via C2 iex command" category = "MALWARE" malware = "GHOSTWEAVER" mitre_att = "T1548.002" reference = "https://www.derp.ca/blog/ghostweaver-tag124-powershell-rat" triage_score = 10 triage_description = "GhostWeaver/Pantera persistence installer with UAC bypass detected." strings: $uac_guid = "A6BFEA43-501F-456F-A845-983D3AD7B8F0" ascii wide nocase $uac_coget = "CoGetObject" ascii wide $uac_elevation = "Elevation:Administrator!new:" ascii wide $peb_func = "Masquerade-PEB" ascii wide $headless = "--headless powershell" ascii wide $headless_cmd = "--headless cmd" ascii wide $schtask_interval = "PT3M" ascii wide $schtask_desc = "Maintenance task" ascii wide $dpapi = "DataProtectionScope" ascii wide nocase $azure_prefix = /Azure[A-Za-z]+\.(ps1|log|jpg)/ ascii wide condition: ($uac_guid and ($uac_coget or $uac_elevation)) or ($peb_func and ($headless or $headless_cmd)) or ($schtask_interval and $schtask_desc and ($headless or $headless_cmd)) or ($dpapi and ($headless or $headless_cmd) and $azure_prefix) } |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | rule GhostWeaver_TLS_Certificate { meta: id = "2PS1wclvHTVqqWL0fNQQnE" fingerprint = "6c09c97d19548a9db9519f2cb4ad85ac3f2a363899775f896afbb9ebd36f8ab4" version = "1.0" date = "2026-03-08" modified = "2026-03-08" status = "RELEASED" sharing = "TLP:CLEAR" source = "HTTPS://WWW.DERP.CA/BLOG/GHOSTWEAVER-TAG124-POWERSHELL-RAT" author = "derp.ca" description = "GhostWeaver/Pantera pinned self-signed TLS certificate (CN=GeoTrust LTD.)" category = "MALWARE" malware = "GHOSTWEAVER" mitre_att = "T1553.004" reference = "https://www.derp.ca/blog/ghostweaver-tag124-powershell-rat" triage_score = 10 triage_description = "GhostWeaver/Pantera pinned TLS certificate detected." strings: $cert_der = { 30 82 04 ee 30 82 02 d6 // SEQUENCE headers a0 03 02 01 02 02 10 00 // version + serial prefix 9e d7 a1 52 31 31 20 57 // serial number (unique) 1a 4e 51 63 87 70 69 30 // serial + algo prefix } $cert_b64 = "MIIE7jCCAtagAwIBAgIQAJ7XoVIxMSBXGk5RY4dwa" ascii wide $cert_cn_str = "GeoTrust LTD." ascii wide $cert_sha1 = { 00 6f 5b b9 27 20 ac a3 3a ab 33 50 5e 17 c4 2c c2 f9 f2 36 } condition: any of them } |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | rule MintsLoader_Victim_Profiler { meta: id = "1NXLHyr8lbJ1fnH1QXX29d" fingerprint = "76cb07d1866e0bc442d0ae6b214fcfd5d123d986d020c58bf7d9b1129715eedf" version = "1.0" date = "2026-03-08" modified = "2026-03-08" status = "RELEASED" sharing = "TLP:CLEAR" source = "HTTPS://WWW.DERP.CA/BLOG/GHOSTWEAVER-TAG124-POWERSHELL-RAT" author = "derp.ca" description = "MintsLoader/TAG-124 victim profiler - sandbox detection and scoring" category = "MALWARE" malware = "MINTSLOADER" mitre_att = "T1497.001" reference = "https://www.derp.ca/blog/ghostweaver-tag124-powershell-rat" triage_score = 10 triage_description = "MintsLoader/TAG-124 sandbox scoring and victim profiling detected." strings: $check_vm = "IsVirtualMachine" ascii wide nocase $check_gpu = "AdapterDACType" ascii wide nocase $check_cache = "CacheMemory" ascii wide nocase $check_video = "Win32_VideoController" ascii wide nocase $amsi = "AmsiOpenSession" ascii wide $callback_htr = /[a-z0-9]{5,15}htr[a-z0-9]{3,8}\.php/ ascii wide $callback_param_key = "&key=" ascii wide $callback_param_s = "&s=" ascii wide $dga4_charset = "'abcdefghijklmn'" ascii wide condition: (($check_vm or $amsi) and ($check_gpu or $check_cache) and $check_video) or ($callback_htr and $callback_param_key and $callback_param_s) or ($dga4_charset and ($check_vm or $check_gpu or $check_cache)) } |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | rule MintsLoader_JS_Dropper { meta: id = "6SZfp0qlIsOShAB3dnLBkq" fingerprint = "4e38a8d263fef79611f3e1221573773c4a4537874e575c6e962c76ea48bf61dd" version = "1.0" date = "2026-03-08" modified = "2026-03-08" status = "RELEASED" sharing = "TLP:CLEAR" source = "HTTPS://WWW.DERP.CA/BLOG/GHOSTWEAVER-TAG124-POWERSHELL-RAT" author = "derp.ca" description = "MintsLoader/TAG-124 JavaScript dropper - XOR-obfuscated, delivers PowerShell" category = "MALWARE" malware = "MINTSLOADER" mitre_att = "T1059.007" reference = "https://www.derp.ca/blog/ghostweaver-tag124-powershell-rat" triage_score = 10 triage_description = "MintsLoader/TAG-124 XOR-obfuscated JavaScript dropper detected." strings: $cc_on = "//@cc_on" ascii $obf_func = /a0_0x[0-9a-fA-F]{3,8}/ ascii $str_mlhttp = "MLHTT" ascii $str_activex = "eXObj" ascii $str_wsh = "'WSH'" ascii $str_post = "'POST'" ascii $str_eval = "'eval'" ascii $delivery_url = /\/1\.php\?s=[0-9a-f\-]{8,40}/ ascii $delivery_url2 = /\/1\.php\?s=flibabc[0-9]{1,3}/ ascii $activex_shell = "WScript.Shell" ascii wide condition: filesize < 50KB and $cc_on and ( (#obf_func > 10 and 3 of ($str_*)) or (($delivery_url or $delivery_url2) and $activex_shell) ) } |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | rule GhostWeaver_Network_Indicators { meta: id = "5nlhxIWY2MajrhjApbjA04" fingerprint = "2ae818b4786a04722abd38415114d19f5d71b2e2eccbc146c832f1429dd238bd" version = "1.0" date = "2026-03-08" modified = "2026-03-08" status = "RELEASED" sharing = "TLP:CLEAR" source = "HTTPS://WWW.DERP.CA/BLOG/GHOSTWEAVER-TAG124-POWERSHELL-RAT" author = "derp.ca" description = "GhostWeaver/Pantera network-level indicators (C2 traffic, DGA domains)" category = "MALWARE" malware = "GHOSTWEAVER" mitre_att = "T1568.002" reference = "https://www.derp.ca/blog/ghostweaver-tag124-powershell-rat" triage_score = 10 triage_description = "GhostWeaver/Pantera C2 beacon or command traffic detected." strings: $json_clientinfo = /\"Packet\":\s?\"ClientInfo\"/ ascii nocase $json_ping = /\"Packet\":\s?\"Ping\"/ ascii nocase $json_pong = /\"Packet\":\s?\"pong\"/ ascii nocase $json_hwid = /\"HWID\":\s?\"/ ascii $json_version = /\"Version\":\s?\"/ ascii $json_group = /\"Group\":\s?\"/ ascii $json_plugin = /\"Packet\":\s?\"plugin\"/ ascii nocase $json_sendplugin = /\"Packet\":\s?\"sendPlugin\"/ ascii nocase $json_iex = /\"Packet\":\s?\"iex\"/ ascii nocase condition: ($json_clientinfo and $json_hwid and $json_version and $json_group) or ($json_plugin and $json_sendplugin) or (($json_pong or $json_ping) and ($json_iex or $json_plugin)) } |