
Заметки по реверс-инжинирингу, деобфусцированный исходный код, IOC и правила YARA для Python-RAT Tourmaline ClickFix, охватывающие его DNS-туннель и C2 через блокчейн-дедроп.
Я недавно наткнулся на образец искусно спроектированного вредоносного ПО, которое называет себя "Torumaline".
Этот README был очень любезно написан Claude, так как на момент создания этого репозитория я был крайне занят экзаменами.
Эксплуатация и расшифровка этого вредоносного ПО отняли у меня огромную часть времени, предназначенного для подготовки к математике!
Читайте пост в блоге!
ТОЛЬКО ДЛЯ ОБРАЗОВАТЕЛЬНЫХ И ИССЛЕДОВАТЕЛЬСКИХ ЦЕЛЕЙ
Все образцы предоставлены для анализа вредоносного ПО и защитных исследований. Не запускайте их вне песочницы и изолированной среды без доступа к сети.
Tourmaline (Tourmaline.exe) — это сложный многоступенчатый Windows-инфостилер/бэкдор, распространяемый через кампанию ClickFix — поддельное всплывающее окно Cloudflare "Verify you are human" в браузере, которое обманом заставляет пользователей вручную запустить вредоносную команду или установщик.
Бинарный файл представляет собой специально созданный установщик Inno Setup 6.7.0 (Revision 2, 64-битные смещения), который включает в себя полную среду выполнения Python 3.11 и две ступени обфусцированной полезной нагрузки на Python. Он устанавливает постоянный бэкдор с:
microsoft.com)tourmaline/
├── README.md # Этот файл
├── LICENSE # Лицензия для исследовательского использования
├── .gitignore
│
├── src/ # Извлечённый и деобфусцированный исходный код
│ ├── stage1_loader.py # Этап 1: Оригинальный обфусцированный XOR-загрузчик с тайм-локом (main.py)
│ ├── stage2_backdoor.py # Этап 2: Деобфусцированный основной бэкдор (из QGBdu.dxf)
│ └── decrypt_payload.py # Утилита: Восстановление ключа за O(1) и расшифровка полезной нагрузки
│
├── iocs/ # Индикаторы компрометации
│ ├── indicators.json # Структурированные данные IOC (IP-адреса, хеши, домены, реестр)
│ ├── indicators.csv # Плоский CSV для импорта в SIEM
│ └── rules.yar # Правила обнаружения YARA
│
└── samples/ # Образцы вредоносного ПО (защищены паролем)
├── README.md # Инструкции по архиву с образцами
├── Tourmaline_sample.zip # Пароль: infected - содержит Tourmaline.exe
└── QGBdu.dxf # Необработанный зашифрованный блоб полезной нагрузки Этапа 2
Вредоносное ПО распространяется через ClickFix — метод социальной инженерии, при котором скомпрометированный или контролируемый злоумышленником веб-сайт накладывает поддельную страницу проверки Cloudflare CAPTCHA или верификации браузера. Оверлей инструктирует жертву:
Win+RВставленная команда загружает и молча запускает Tourmaline.exe. Установщик запускается с параметрами /VERYSILENT /SUPPRESSMSGBOXES /NORESTART.
Примечание: Стандартный
innoextract 1.9не может извлечь этот бинарный файл — он поддерживает только Revision 1. Revision 2 использует 64-битные смещения и требует пользовательского парсинга (см.src/decrypt_payload.py).
Tourmaline.exe
│
├─ Установщик Inno Setup запускается молча
│ ├─ Извлекает среду выполнения Python 3.11 в %APPDATA%\Tourmaline\
│ ├─ Извлекает main.py (загрузчик Этапа 1)
│ ├─ Извлекает QGBdu.dxf (зашифрованный блоб Этапа 2)
│ ├─ Завершает все существующие экземпляры pythonw.exe
│ └─ Регистрирует персистентность (Task Scheduler / реестр)
│ └─ Имя: "TourmalineUpdate" / "Hardware monitoring service"
│
├─ Этап 1: main.py (XOR-загрузчик с тайм-локом)
│ ├─ Считает _n от 99 999 999 → 0 (анти-песочница задержка ~часы на медленных ВМ)
│ ├─ На каждом _n строит 33-байтовый XOR-ключ: struct.pack('>I', _n) + hardcoded_suffix
│ ├─ Проверяет ключ по известному открытому заголовку QGBdu.dxf
│ └─ При совпадении: полностью расшифровывает QGBdu.dxf и выполняет результат через exec()
│ └─ Обход за O(1): атака на основе известного открытого текста по первым 4 байтам (см. ниже)
│
└─ Этап 2: QGBdu.dxf → Python-бэкдор
├─ Читает MachineGuid из HKLM\SOFTWARE\Microsoft\Cryptography
├─ Формирует мьютекс Global\Tourmaline_<hash>
├─ Определяет IP-адрес C2 через тайник в Ethereum (тестовая сеть Sepolia)
├─ Устанавливает DNS-туннель к C2
└─ Цикл poll-execute: получает задачи, выполняет Python через exec(), возвращает вывод
Загрузчик (main.py) использует обратный отсчёт от 99 999 999 для поиска ключа XOR-расшифровки. На реальной машине это завершается за секунды (поскольку _n начинается с большого значения, а истинное значение близко к 14 511 188). В песочнице с коротким лимитом времени цикл никогда не завершается.
Структура ключа:
full_key = struct.pack('>I', _n) + bytes.fromhex('2b0cffe07b06ac25793b3f00cfaa2dd5881c2d6378165247539dbbdaeb')
Поскольку мы знаем первые 16 байт открытого текста (g1 = lambda l6, ), мы можем мгновенно восстановить _n с помощью атаки на основе известного открытого текста XOR:
key_prefix = bytes(ciphertext[i] ^ known_plaintext[i] for i in range(4))
# Результат: key_prefix = 00dd6c54 → _n = 14,511,188
Используйте src/decrypt_payload.py для воспроизведения этого.
Вредоносное ПО вызывает смарт-контракт Ethereum в тестовой сети Sepolia для получения активного IP-адреса C2. Это означает, что злоумышленник может изменить IP-адрес C2 в любое время, обновив контракт — традиционное нарушение работы C2 на основе блокировки IP-адресов становится неэффективным.
Contract : 0x2d7a04cca0c34005f58393f30ac725e25f19e5f5
Selector : 0xeb9fd6fe
Network : Ethereum Sepolia (chainId 11155111)
RPC : https://ethereum-sepolia-rpc.publicnode.com
Result : ChaCha20-encrypted blob containing current C2 IP
Возвращённые данные расшифровываются с помощью жёстко закодированного ключа ChaCha20, чтобы раскрыть актуальный адрес C2. На момент анализа он разрешался в 158.94.211.185 (проверено через живой вызов RPC).
Весь трафик C2 отправляется в виде необработанных UDP DNS-запросов напрямую на IP-адрес C2 через порт 53. Запросы структурированы как <encoded_data>.microsoft.com, обходя фильтрацию на основе DNS и выглядя как легитимная телеметрия Windows.
socket.getaddrinfo или какую-либо библиотеку DNSБэкдор реализует движок произвольного выполнения Python exec(). Задачи:
exec() в постоянном пространстве имён с захватом выводаПоддерживаемые типы задач: Python exec, загрузка/выгрузка файлов, команда оболочки, самообновление.
| Файл | SHA256 |
|---|---|
Tourmaline.exe | c9b390b3b7148f549df86503858d52e030b2b5e78fed0bc525ded5927f9265d6 |
Tourmaline.exe (MD5) | b74ac808dea2de31caf024310694ef0c |
См. iocs/rules.yar для правил обнаружения, охватывающих:
Если это вредоносное ПО было выполнено на машине:
taskkill /F /IM pythonw.exe%APPDATA%\Tourmaline\ или %COMMONAPPDATA%\Tourmaline\TourmalineUpdateHKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Run на наличие Tourmaline или SystemService158.94.211.185:53/UDP; блокируйте весь неожиданный исходящий UDP/53ethereum-sepolia-rpc.publicnode.compip install pyOpenSSL cryptography
# Из корня репозитория:
python3 src/decrypt_payload.py samples/QGBdu.dxf decrypted_stage2.py
7z x -pinfected samples/Tourmaline_sample.zip
См. LICENSE. Этот репозиторий предназначен только для образовательных и защитных исследовательских целей.
| Свойство | Значение |
|---|
| Имя файла | Tourmaline.exe |
| Размер | 11 341 339 байт (~10,8 МБ) |
| MD5 | b74ac808dea2de31caf024310694ef0c |
| SHA256 | c9b390b3b7148f549df86503858d52e030b2b5e78fed0bc525ded5927f9265d6 |
| Формат | Inno Setup 6.7.0 Unicode (Revision 2, 64-битные смещения) |
| Тип PE | 32-битный PE, 11 секций |
| Размер оверлея | 10 447 387 байт |
| Смещение магии Inno | 0xD9864 (890 148 байт) |
| Имя приложения | Tourmaline |
| Версия приложения | 2.63.519 |
| GUID приложения | {2C25872D-85FC-44C7-9B16-844E39E50A44} |
| Путь установки | {commonappdata}\Tourmaline |
| Встроенная среда выполнения | Python 3.11 (полная встраиваемая) |
| Файлы полезной нагрузки | 36 файлов в сплошном потоке LZMA2 |
| Параметр | Значение |
|---|
| IP-адрес C2 | 158.94.211.185 |
| Порт C2 | 53 (UDP) |
| Протокол | Пользовательский DNS-over-UDP туннель |
| Поддельный домен | microsoft.com |
| Ключ ChaCha20 | 36f555c87f71581f57d83576c88193fdc00a0173f741a3e198e2d7abdc9cda59 |
| Контракт блокчейна | 0x2d7a04cca0c34005f58393f30ac725e25f19e5f5 (Sepolia) |
| Публичный ключ ECDSA | MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEt17l3rGHHR9sYdHEvV8S+JRRCUHQQveSadlGk04xM/8WClDf/67Tyritt2+T18SY8n0xv1TKKl0AgnNFuboEEQ== |
| Имя службы | SystemService / TourmalineUpdate |
| Мьютекс | Global\Tourmaline_<MachineGuid-hash> |
| Тип | Значение |
|---|
| IP-адрес C2 | 158.94.211.185 |
| Порт C2 | 53/UDP |
| Поддельный домен | *.microsoft.com (пользовательский UDP, не настоящий DNS) |
| Ethereum RPC | https://ethereum-sepolia-rpc.publicnode.com |
| Смарт-контракт | 0x2d7a04cca0c34005f58393f30ac725e25f19e5f5 |
| Ключ | Значение |
|---|
HKLM\SOFTWARE\Microsoft\Cryptography\MachineGuid | Читается для фингерпринтинга жертвы |
%APPDATA%\Tourmaline\ | Каталог установки |
| Task Scheduler | TourmalineUpdate |
| Отображаемое имя службы | Hardware monitoring service |
| Мьютекс | Global\Tourmaline_<hash> |
| Поле | Значение |
|---|
| Дата обнаружения | Сентябрь 2026 |
| Исследователь | Vihaan Pundir (v-pun215) |
| Вектор распространения | ClickFix поддельная Cloudflare CAPTCHA |
| Классификация | Бэкдор / DNS-туннель C2 / Тайник в блокчейне |
| Платформа | Windows (64-бит) |