Всех приветствую. Если вы следите за рансомварь-сценой хоть краем глаза, то имя Qilin вам должно быть знакомо. По данным Cyble, Ransomware Live и прочих трекеров, Qilin с начала 2026 года стабильно занимает первое место по количеству жертв среди всех RaaS-группировок. За один только Q1 2026 - 338 подтверждённых жертв. Для сравнения, LockBit на пике в 2024 делал ~214 за квартал. Qilin их перегнали. И не просто по количеству, а по качеству - бьют по сферам здарвоохранения, производства, критической инфре После того как в 2024 году они зашифровали несколько больниц NHS в Великобритании и слили 400 гигов медицинских данных, стало понятно что эти ребята не шутят.
Сегодня потрошим их декриптор. Да-да, не энкриптор, а именно декриптор, но разница тут чисто конфигурационная - бинарь универсальный, один и тот же код умеет и шифровать и расшифровывать, всё зависит от встроенного JSON-конфига. Написан на Rust, собран под x86 Windows, весит 2.27 мегабайта. Внутри, как обычно у этих ребят, захардкоженный RSA-4096 ключ, списки на убийство, чёрные списки. Разберём всё по порядку, от PE-хедера до onion-домена переговорной площадки. Погнали.
Скачали семпл, распаковали, и первое что делаю - смотрю что это вообще за зверь.
Консольное 32-битное приложение. Stripped - отладочные символы вырезаны. Размер под 2 метра. Для Rust-бинаря это вполне адекватно, рантайм Rust'а сам по себе немало весит, плюс сюда вкомпилен целый зоопарк крейтов.
Смотрим PE-хедер подробнее:
Линкер 2.40 - это GNU ld из MinGW. То есть собирали не MSVC-тулчейном, а через
Секции:
Энтропия
Коммит
Cargo workspace с общими библиотеками (
Обратите внимание на
Вытаскиваем конфиг целиком. Первое что бросается в глаза:
Уникальный ID жертвы. Он же расширение зашифрованных файлов (
RSA-4096 приватный ключ, PKCS#1 формат. Этот ключ используется для расшифровки per-file симметричных ключей. Схема гибридная и стандартная для modern ransomware:
В декрипторе приватный ключ присутствует (логично, иначе как расшифровывать). В энкрипторе его нет - только публичный. Это видно по строкам:
Каждый зашифрованный файл содержит контейнер (footer в конце файла) с метаданными: зашифрованный per-file ключ, nonce, тип шифра, чекпоинт для возобновления. Маркер
Теперь к спискам. И вот тут начинается то, за что я люблю ковырять рансомварь - по конфигу можно прочитать как по книжке, что именно и в каком порядке делает бинарь.
Чёрный список директорий:
Стандартный набор - системные директории пропускаются чтоб не убить ОС (иначе жертва не сможет зайти и прочитать записку с требованиями). Не шифруют Tor, чтоб жертва могла через него зайти на .onion переговорную площадку. Трогательная забота.
Чёрный список файлов:
Загрузочные файлы и критические системные. Логика та же - Windows должна загрузиться.
Чёрный список расширений:
Последний элемент -
Процессы на убийство (kill list):
Убивают базы данных (SQL, Oracle, SAP), бэкап-агенты (Veeam, Commvault, BackupExec, Veritas, Acronis), офисные приложения (чтоб разлочить открытые файлы), Hyper-V (чтоб добраться до VHD/VHDX виртуальных дисков), TeamViewer (чтоб отрезать удалённый доступ администратора). Steam тоже в списке - ну мало ли, админ в контру играет пока бэкапы горят.
Сервисы на остановку:
Обратите внимание на последнюю строку -
А теперь самое вкусное. Захардкоженные креды:
Вот он. Аккаунт администратора домена.
Параметры шифрования:
При
Теперь про функциональность бинаря. По debug-строкам (а их там дохера - видимо в релизных билдах логирование не вырезается, что нам только на руку) можно восстановить полный пайплайн выполнения. Давайте пройдёмся по тому, что происходит когда оператор запускает этот бинарь на машине жертвы.
Первым делом парсится встроенный JSON-конфиг, инициализируются RSA-ключи и определяется количество ядер CPU (
Дальше начинается подготовка поля боя. Бинарь лезет в Service Control Manager (
Но вот что реально интересно, если после всего этого какой-то файл всё ещё залочен, бинарь не сдаётся. Он использует Restart Manager API:
После зачистки начинается сетевая фаза. Бинарь берёт те самые захардкоженные креды администратора и делает имперсонацию -
Теперь он ходит по сети от имени
Отдельная тема FDE/DASD режим. Бинарь умеет работать с дисками на низком уровне, обращаясь напрямую к устройству через Direct Access Storage Device:
Приводит оффлайн-диски в онлайн, снимает read-only атрибуты. Если нужно зашифровать VHD/VHDX образ Hyper-V, он его примонтирует и обработает. Когда все диски и шары собраны, начинается рекурсивный обход файловой системы через
И последний штрих, горизонтальное перемещение. Через PsExec бинарь копирует себя на соседние машины и запускает с флагом
Отдельно хочу выделить кросс-платформенную координацию.
Бинарь знает о существовании Linux-версии того же локера. Если видит что файл уже обработан Linux-билдом - пропускает. То есть в реальной атаке одновременно работают Windows и Linux варианты (ESXi, NAS, Linux-серверы), и они не мешают друг другу.
Подытоживая. Qilin - на сегодняшний день самая активная RaaS-группировка в мире по количеству жертв. Тулкит написан на Rust, кросс-компилируется из Docker-контейнера на Linux, имеет модульную архитектуру с переиспользованием кода между энкриптором и декриптором. Шифрование гибридное (RSA-4096 + AES-CTR/ChaCha20), с поддержкой FDE/DASD, интермиттирующего режима, multi-pass и чекпоинтов. Распространение через PsExec с захардкоженными кредами домена. Убийство бэкапов, антивирусов, баз данных. Разлокировка файлов через Restart Manager. Параллелизация через threadpool по всем ядрам. Координация между Windows и Linux инстансами. Всем пока, не болейте!
Не удалось прогрузить медиа
Сегодня потрошим их декриптор. Да-да, не энкриптор, а именно декриптор, но разница тут чисто конфигурационная - бинарь универсальный, один и тот же код умеет и шифровать и расшифровывать, всё зависит от встроенного JSON-конфига. Написан на Rust, собран под x86 Windows, весит 2.27 мегабайта. Внутри, как обычно у этих ребят, захардкоженный RSA-4096 ключ, списки на убийство, чёрные списки. Разберём всё по порядку, от PE-хедера до onion-домена переговорной площадки. Погнали.
Не удалось прогрузить медиа
Не удалось прогрузить медиа
Не удалось прогрузить медиа
Code:
PE offset: 0x80
Machine: 0x14C (i386)
Sections: 9
Linker version: 2.40
Magic: PE32
Линкер 2.40 - это GNU ld из MinGW. То есть собирали не MSVC-тулчейном, а через
i686-pc-windows-gnu . Они кросс-компилят из Docker-контейнера на Linux (об этом позже, это подтверждается строками в бинаре). Ни один нормальный Windows-разработчик не будет собирать x86-бинарь через MinGW в 2025 году - это 100% кросс-компиляция.Секции:
Code:
.text 0x19A3A0 entropy: 6.48 (код)
.data 0x160 (данные)
.rdata 0x6DBB8 entropy: 5.50 (read-only данные, тут конфиг)
.eh_frame 0x29ECC (DWARF exception handling)
.bss 0xB74 (неинициализированные данные)
.idata 0x17E0 (импорты)
.CRT 0x38 (C runtime init)
.tls 0x8 (thread local storage)
.reloc 0x106B4 (релокации)
Энтропия
.text = 6.48 - не упакован (упакованный был бы ближе к 7.9+). Код чистый, значит можно анализировать напрямую. Наличие .eh_frame секции аж на 170 КБ - характерный признак кросс-скомпиленного Rust-бинаря через MinGW. Это DWARF exception handling frames, а не SEH как было бы при MSVC. По секциям сразу видно - не пакован, не обфусцирован, бери и читай. Что мы и будем делать. Теперь определяем язык и версию компилятора.Не удалось прогрузить медиа
d5c2e9c342b358556da91d61ed4133f6f50fc0c3 - это Rust 1.73.0 (stable, октябрь 2023). Но тут момент - бинарь скомпилен в 2025, а рантайм от октября 2023. Значит либо пиннят версию тулчейна в rust-toolchain.toml, либо используют заранее подготовленный Docker-образ, который не обновляют. Второе подтверждается вот этой строчкой.
Code:
/usr/src/myapp/windows-rust/shared/flags/src/flags/mod.rs
/usr/src/myapp/ - это дефолтный WORKDIR в Dockerfile. Собирают на Linux в контейнере, таргетят Windows. Проект называется windows-rust. И вот тут мне стало интересно - а что ещё из строк можно вытянуть про структуру исходников? Оказалось, дохера. Восстановленная структура проекта:
Code:
windows-rust/
├── decryptor/
│ └── src/
│ └── config/
│ └── embedded_config.rs
│ └── pipelines/
│ └── decryption_pipeline.rs
└── shared/
├── cryptography/
│ └── src/decryption.rs
├── flags/
│ └── src/flags/
│ ├── mod.rs
│ ├── flag_value.rs
│ └── unit_parsing.rs
├── logging/
│ └── src/lib.rs
├── utilities/
│ └── src/lib.rs
└── windows/
└── src/
├── files/mod.rs
├── helper/mod.rs
├── processes/{mod.rs, process_api.rs}
├── services/{mod.rs, service_api.rs}
└── storage/{shares.rs, volumes.rs}
Cargo workspace с общими библиотеками (
shared/) и конкретным бинарём (decryptor/). Архитектура модульная - тот же shared/ используется и в энкрипторе, и в декрипторе, а что именно собирать определяется точкой входа. По-сути у них один репозиторий, из которого выходят оба бинаря. Крейты (зависимости), извлечённые из строк.
Code:
aes-0.8.3 - AES шифрование (software fixslice impl, без AES-NI)
aho-corasick-1.0.3 - паттерн-матчинг (чёрные/белые списки)
base64ct-1.6.0 - base64 для ключей (constant-time реализация!)
chrono-0.4.26 - дата/время для логов
rand-0.8.5 - CSPRNG для генерации per-file ключей
regex-automata-0.3.6 - регулярки для матчинга сервисов
serde_json-1.0.105 - парсинг JSON-конфига
threadpool-1.8.1 - пул потоков для параллельного шифрования
walkdir-2.3.3 - рекурсивный обход файловой системы
whoami-1.4.1 - определение текущего юзера/машины
zeroize-1.6.0 - безопасное обнуление ключей в памяти
Обратите внимание на
zeroize - это крейт для затирания чувствительных данных в памяти. После использования ключа шифрования, он зануляется, чтоб из дампа памяти его не вытащили. А base64ct - constant-time реализация base64, защита от тайминг аттак. Мелочи, но показывают уровень разработки.Не удалось прогрузить медиа
Code:
struct DecryptorEmbedConfiguration
company_id: String,
// + приватный RSA ключ + полный блоб конфигурации
}
Не удалось прогрузить медиа
Code:
"company_id": "yd9Ca9y5RN"
Уникальный ID жертвы. Он же расширение зашифрованных файлов (
.yd9Ca9y5RN), он же идентификатор на переговорной площадке. Одна строка - три функции. Однако экономно. Дальше - RSA-ключ.
Code:
"private_rsa_pem": "-----BEGIN RSA PRIVATE KEY-----\n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\n-----END RSA PRIVATE KEY-----\n"
RSA-4096 приватный ключ, PKCS#1 формат. Этот ключ используется для расшифровки per-file симметричных ключей. Схема гибридная и стандартная для modern ransomware:
- Для каждого файла генерируется уникальный симметричный ключ (AES-256-CTR или ChaCha20)
- Файл шифруется этим ключом
- Сам ключ шифруется публичным RSA и записывается в контейнер в конце файла
- Без приватного RSA-ключа расшифровать невозможно
В декрипторе приватный ключ присутствует (логично, иначе как расшифровывать). В энкрипторе его нет - только публичный. Это видно по строкам:
Code:
[DEBUG|DEC] File container extracted: key:|nonce:|st:|sk:|aes:
[DEBUG|DEC] File was encrypted with AES-CTR.
[DEBUG|DEC] File was encrypted with ChaCha20.
[DEBUG|DEC] Endblock found!
-----END CIPHERTEXT BLOCK-----[FATAL] Cannot parse private key
Каждый зашифрованный файл содержит контейнер (footer в конце файла) с метаданными: зашифрованный per-file ключ, nonce, тип шифра, чекпоинт для возобновления. Маркер
expand 32-byte k в строках - это ChaCha20 constant, подтверждает использование ChaCha20 наряду с AES-CTR.Не удалось прогрузить медиа
Чёрный список директорий:
Code:
"directory_black_list": [
"windows", "system volume information", "intel", "admin$", "ipc$",
"sysvol", "netlogon", "$windows.~ws", "application data", "mozilla",
"program files (x86)", "program files", "$windows.~bt", "msocache",
"tor browser", "programdata", "boot", "config.msi", "google",
"perflogs", "appdata", "windows.old", "..", ".", "$recycle.bin"
]
Стандартный набор - системные директории пропускаются чтоб не убить ОС (иначе жертва не сможет зайти и прочитать записку с требованиями). Не шифруют Tor, чтоб жертва могла через него зайти на .onion переговорную площадку. Трогательная забота.
Чёрный список файлов:
Code:
"file_black_list": [
"desktop.ini", "autorun.ini", "ntldr", "bootsect.bak", "thumbs.db",
"boot.ini", "ntuser.dat", "iconcache.db", "bootfont.bin", "ntuser.ini",
"ntuser.dat.log", "autorun.inf", "bootmgr", "bootmgr.efi",
"bootmgfw.efi", "#recycle"
]
Загрузочные файлы и критические системные. Логика та же - Windows должна загрузиться.
Чёрный список расширений:
Code:
"file_pattern_black_list": [
"themepack", "nls", "diapkg", "msi", "lnk", "exe", "scr", "bat",
"drv", "rtp", "msp", "prf", "msc", "ico", "key", "ocx", "diagcab",
"diagcfg", "pdb", "wpx", "hlp", "icns", "rom", "dll", "msstyles",
"mod", "ps1", "ics", "hta", "bin", "cmd", "ani", "386", "lock",
"cur", "idx", "sys", "com", "deskthemepack", "shs", "theme", "mpa",
"nomedia", "spl", "cpl", "adv", "icl", "msu",
"yd9Ca9y5RN" ← собственное расширение!
]
Последний элемент -
yd9Ca9y5RN - их собственное расширение. Чтоб не зашифровать уже зашифрованный файл повторно при перезапуске. Также не трогают exe/dll/sys - опять же, чтоб система жила.Процессы на убийство (kill list):
Code:
"process_black_list": [
"vmms", "vmwp", "vmcompute", - Hyper-V
"agntsvc", "dbeng50", "dbsnmp", "encsvc", - SQL/DB
"excel", "firefox", "infopath", "isqlplussvc",
"sql", "msaccess", "mspub", "notepad",
"ocomm", "ocssd", "onenote", "oracle", "outlook",
"powerpnt", "sqbcoreservice", "steam",
"synctime", "thebat", "thunderbird", "visio",
"winword", "wordpad", "xfssvccon",
"bedbh", "vxmon", "benetns", "bengien", "pvlsvr", - Veritas
"beserver", "raw_agent_svc", "vsnapvss",
"cagservice", "qbidpservice", "qbdbmgrn", - QuickBooks
"sap", "teamviewer_service", "teamviewer", - SAP + remote access
"tv_w32", "tv_x64",
"cvmountd", "cvd", "cvfwd", "cvods", - Commvault
"saphostexec", "saposcol", "sapstartsrv",
"avagent", "avscc", "dellsystemdetect",
"veeamnfssvc", "veeamtransportsvc", - Veeam
"veeamdeploymentsvc", "mvdesktopservice"
]
Убивают базы данных (SQL, Oracle, SAP), бэкап-агенты (Veeam, Commvault, BackupExec, Veritas, Acronis), офисные приложения (чтоб разлочить открытые файлы), Hyper-V (чтоб добраться до VHD/VHDX виртуальных дисков), TeamViewer (чтоб отрезать удалённый доступ администратора). Steam тоже в списке - ну мало ли, админ в контру играет пока бэкапы горят.
Сервисы на остановку:
Code:
"win_services_black_list": [
"vmms", "mepocs", "memtas", "veeam", "backup", "vss", "sql",
"msexchange", "sophos", "wsbexchange", "pdvfsservice",
"backupexecvssprovider", "backupexecagentaccelerator",
"backupexecagentbrowser", "backupexecdivecimediaservice",
"backupexecjobengine", "backupexecmanagementservice",
"backupexecrpcservice",
"gxblr", "gxvss", "gxclmgrs", "gxcvd", "gxcimgr", - Commvault
"gxmmm", "gxvsshwprov", "gxfwd",
"sapservice", "sap", "sap\\$", "sapd\\$",
"saphostcontrol", "saphostexec",
"qbcfmonitorservice", "qbdbmgrn", "qbidpservice",
"acronisagent", "veeamnfssvc", "veeamdeploymentservice",
"veeamtransportsvc", "mvarmor", "mvarmor64",
"vsnapvss", "acrsch2svc",
"(.*?)sql(.*?)" - любой сервис содержащий "sql"
]
Обратите внимание на последнюю строку -
(.*?)sql(.*?). Это регулярное выражение, которое матчит ЛЮБОЙ сервис со словом "sql" в имени. Не конкретный MSSQLSERVER, а вообще любой. Вот зачем им крейт regex-automata. Кто-то из разрабов Qilin явно задолбался каждый раз дописывать новые имена SQL-сервисов и решил вопрос кардинально. Sophos тоже в списке - отключают антивирус перед шифрованием. VSS (Volume Shadow Copy) - чтоб убить теневые копии. Exchange - чтоб разлочить почтовые базы (.edb).Не удалось прогрузить медиа
А теперь самое вкусное. Захардкоженные креды:
Code:
"accounts": [
"[email protected]:Br03r88%!"
]
Вот он. Аккаунт администратора домена.
[email protected] с паролем Br03r88%!. Домен жертвы - vernonus.local. Обратите внимание на опечатку, "adminstrator" вместо "administrator". Либо так реально называется аккаунт в домене (бывает), либо опечатка операторов при конфигурации билда. Так или иначе, это подтверждает что билд таргетированный, собран конкретно под эту компанию после получения первичного доступа и разведки в сети. Креды используются для имперсонации через DuplicateTokenEx / SetThreadToken - бинарь берёт токен этого аккаунта и ходит с ним по сетевым шарам.Не удалось прогрузить медиа
Параметры шифрования:
Code:
"n": 0, - количество проходов (0 = дефолт)
"p": 1, - passes
"fast": 0, - быстрый режим
"skip": 0, - пропуск байт
"step": 0 - шаг
При
fast: 0 и skip: 0 - шифрование полное, каждый байт файла. Если бы fast: 1 - шифровался бы только каждый N-ый блок. У данного билда скорость не в приоритете - шифруют всё.Не удалось прогрузить медиа
Теперь про функциональность бинаря. По debug-строкам (а их там дохера - видимо в релизных билдах логирование не вырезается, что нам только на руку) можно восстановить полный пайплайн выполнения. Давайте пройдёмся по тому, что происходит когда оператор запускает этот бинарь на машине жертвы.
Первым делом парсится встроенный JSON-конфиг, инициализируются RSA-ключи и определяется количество ядер CPU (
[INFO|DEC] Detected Total Cores:) - на основе этого создаётся пул потоков через threadpool, чтоб шифрование параллелилось по всем ядрам. Сразу после этого бинарь зачищает теневые копии через cmd.exe - стандартный vssadmin delete shadows /all /quiet или аналог через WMI. В строках это видно как:
Code:
shadows--spread-process
[INFO] No shadow copies present
cmd.exe /d /c
Дальше начинается подготовка поля боя. Бинарь лезет в Service Control Manager (
OpenSCManagerW - EnumServicesStatusW - ControlService) и останавливает все сервисы из чёрного списка, матча по тем самым регуляркам. Параллельно идёт убийство процессов - EnumProcesses - GetProcessImageFileNameW - TerminateProcess. Всё что попало в килл лист - SQL, Oracle, Veeam, TeamViewer - безжалостно убивается.Но вот что реально интересно, если после всего этого какой-то файл всё ещё залочен, бинарь не сдаётся. Он использует Restart Manager API:
Code:
[INFO] Trying to unlock the file.
[DEBUG|REL] File handler identified as process:
[DEBUG|REL] Trying to kill process:
RmRegisterResources - RmGetList - RmEndSession. Определяет какой процесс или сервис держит файл, и убивает конкретно его. Элегантное решение, вместо того чтоб убивать всё подряд, точечно снимает блокировки.После зачистки начинается сетевая фаза. Бинарь берёт те самые захардкоженные креды администратора и делает имперсонацию -
DuplicateTokenEx - SetThreadToken:
Code:
[DEBUG|IMP] Successfully impersonated SID:
[DEBUG|IMP] Successfully impersonated thread with extracted token
[DEBUG] Successfully converted primary token to impersonation token
Теперь он ходит по сети от имени
[email protected]. Через NetShareEnum перечисляет все доступные сетевые шары на каждом хосте в домене. Параллельно через GetLogicalDrives собирает все локальные диски - fixed, remote, removable, CD-ROM, RAM, ничего не пропускает.Отдельная тема FDE/DASD режим. Бинарь умеет работать с дисками на низком уровне, обращаясь напрямую к устройству через Direct Access Storage Device:
Code:
[INFO|FDE] FDE/DASD mode detected
[DEBUG|STORE] New disk attributes set, verifying...
[INFO|STORE] Successfully brought disk online and cleared read-only attributes
Приводит оффлайн-диски в онлайн, снимает read-only атрибуты. Если нужно зашифровать VHD/VHDX образ Hyper-V, он его примонтирует и обработает. Когда все диски и шары собраны, начинается рекурсивный обход файловой системы через
walkdir, с поддержкой симлинков, пропуском чёрных списков, статистикой по каждому проходу ([INFO|WALK] Pass completed: (total:|succ:|err:|ign:)). Каждый файл, прошедший фильтры, отправляется в пул потоков на шифрование. Per-file ключ генерируется через CSPRNG, оборачивается RSA-4096, файл шифруется AES-256-CTR или ChaCha20, в конец дописывается контейнер с метаданными. Бинарь даже считает скорость в мегабайтах в секунду:
Code:
[INFO|DEC] Started decryption on path with workers:
[INFO|DEC] File [] decrypted MB in s (MB/s)
[INFO|DEC] Decrypted in passes
И последний штрих, горизонтальное перемещение. Через PsExec бинарь копирует себя на соседние машины и запускает с флагом
--spread-process. Размножение по сети, пока не зашифрует всё до чего дотянется.Не удалось прогрузить медиа
Code:
[DEBUG|BLACK] Skipping file processed by linux instance.
[DEBUG|BLACK] Skipping file processed by other instance.
Бинарь знает о существовании Linux-версии того же локера. Если видит что файл уже обработан Linux-билдом - пропускает. То есть в реальной атаке одновременно работают Windows и Linux варианты (ESXi, NAS, Linux-серверы), и они не мешают друг другу.
Не удалось прогрузить медиа
👍87
🔥11
😁17
😢11
💯18
LIMB