Утро реверс-инженера: 50 свежих семплов и никакого кофе
Ты открываешь папку с новыми образцами. 50 exe, 20 dll, пара скриптов. Каждый нужно прогнать в песочнице, покопаться в дизассемблере, вытащить C2, расписать IOCs. Хорошо если один из них окажется известным банкиром — тогда к вечеру управишься. А если это свежая разработка? Добро пожаловать в ночную смену.
Я ненавижу рутину. Особенно ту, что можно автоматизировать, но почему-то до сих пор не автоматизировали. Знакомая картина: запускаешь Cuckoo (или CAPE), ждешь 20 минут, смотришь отчет, потом открываешь Ghidra, руками тыкаешь в функции, пишешь отчет. Потом повторяешь для следующего. И так 50 раз. Кто-то скажет: "Так это же работа аналитика!" А я скажу: это работа, которую может делать AI-агент, пока ты пьешь кофе.
Давай соберем такого агента. Не игрушку из туториала, а production-ready систему, которая сама запускает VM, дизассемблирует бинарник и выдает готовый аналитический отчет. Внутри: песочница на VirtualBox + mitmproxy, Ghidra 11.2 с headless-режимом, и LLM (я буду использовать GPT-5 — на момент июля 2026 это лучший выбор для таких задач).
Дисклеймер: Весь описанный код предназначен для легального анализа в контролируемой среде. Не используйте его для запуска вредоносов на продакшн-серверах. Я серьезно.
Архитектура: три кита, на которых все держится
Система состоит из трех модулей, которые общаются через центральный оркестратор — самого AI-агента. Агент решает, что делать дальше: запросить динамический анализ, декомпилировать конкретную функцию или задать уточняющий вопрос. Паттерн — классический ReAct (Reasoning + Acting), который мы уже разбирали в статье про production-ready AI-агента с нуля. Агент хранит состояние выполнения и может ветвиться.
- Песочница (Dynamic Analyzer): VirtualBox + Python-обертка. После запуска образца снимаем сетевой трафик (tcpdump), логи API-вызовов (апи-монитор), изменения файловой системы и реестра.
- Ghidra Headless (Static Analyzer): Скрипты на Python (через PyGhidra) для декомпиляции, извлечения строк, импортов, графа вызовов. Запускаем в headless-режиме, чтобы не тащить GUI.
- LLM Agent: GPT-5 (или Claude Opus 4 — кому что ближе) с инструкцией аналитика. Агент получает сырые данные, генерирует гипотезы, может запустить повторный анализ с другими флагами. Использует семантическую память и RAG (векторную БД с известными IOCs).
Зачем нам такой зоопарк? Потому что ни один источник в одиночку не дает полной картины. Песочница покажет поведение, но не код. Ghidra покажет код, но не контекст выполнения. LLM соединит кусочки и выдаст вердикт. Это как собрать пазл, где каждый модуль — свой кусок.
Шаг 1: Песочница, которая не дает сбежать
Я ненавижу, когда виртуалка детектится вредоносом. Современные малвари проверяют: установлены ли Guest Additions, есть ли мышь, какой MAC-адрес. Поэтому наш модуль должен маскироваться. Используем VirtualBox 7.0 (последняя стабильная на июль 2026) с кастомными настройками: отключаем трейсы, меняем MAC, используем снапшот с "грязным" состоянием.
import virtualbox, time, subprocess
class Sandbox:
def __init__(self, vm_name='Win10_Analysis'):
self.vbox = virtualbox.VirtualBox()
self.session = virtualbox.Session()
self.vm = self.vbox.find_machine(vm_name)
def start_snapshot(self):
# Восстанавливаем чистый снапшот
self.vm.restore_snapshot('clean_network', self.session)
def run_sample(self, sample_path):
self.vm.launch_vm_process(self.session, 'gui', '')
time.sleep(30) # ждем загрузки
# Копируем файл через shared folder
subprocess.run(['VBoxManage', 'guestcontrol', self.vm.name, 'copyto',
'--target-directory', 'C:\\Users\\Public\\', sample_path])
# Запускаем через cmd
subprocess.run(['VBoxManage', 'guestcontrol', self.vm.name, 'run',
'--exe', 'cmd.exe', '--username', 'admin', '--password', 'admin',
'--', '/c', 'C:\\Users\\Public\\mal.exe'])
time.sleep(120) # ждем выполнения
# Выключаем
self.vm.power_down(self.session)
# Забираем логи
return self.collect_artifacts()
def collect_artifacts(self):
# собираем pcap, логи прокси, дампы памяти
...Проблема: время выполнения. Если образец висит и ждет C2, мы будем ждать вечно. Решение — таймаут и эвристика: если за 2 минуты нет сетевой активности и новых процессов — завершаем. В реальной песочнице (например, Cuckoo) есть еще принудительное завершение по таймеру. У нас все то же, но с контролем через AI-агента: если агент видит, что образец требует аргументов, он может перезапустить с другими.
Шаг 2: Ghidra без мыши
Ghidra 11.2 (на момент 2026 уже обновилась, добавили нативную поддержку Python 3.12) работает в headless-режиме. Для нас это значит — можно запускать скрипты из командной строки и получать JSON. Самый частый сценарий: декомпилировать функцию, извлечь строки и импорты. Напишем скрипт на Python через PyGhidra.
# ghidra_analyze.py
import json, sys
from ghidra.app.decompiler import DecompInterface
if __name__ == '__main__':
# получаем текущую программу из Ghidra API
program = getCurrentProgram()
ifc = DecompInterface()
ifc.openProgram(program)
functions = program.getFunctionManager().getFunctions(True)
results = []
for func in functions:
if func.getName() in ['entry', 'start']:
decomp = ifc.decompileFunction(func, 30, monitor)
if decomp:
results.append({'name': func.getName(), 'code': decomp.getDecompiledFunction().getC()})
print(json.dumps(results))
sys.exit(0)Запуск:
analyzeHeadless /path/to/project MyProject -import sample.exe -postScript ghidra_analyze.py -scriptPath /scripts/Результат — JSON с декомпилированным кодом ключевых функций. Агент получает этот JSON и анализирует: находит подозрительные вызовы (CreateRemoteThread, VirtualAllocEx), строки с URL, шифровальные константы.
Нюанс: Ghidra может декомпилировать криво, особенно если код обфусцирован. Тут на помощь приходит LLM: она видит сырой псевдокод и понимает, что на самом деле делает функция. Я не раз видел, как GPT-5 правильно интерпретировал запутанный алгоритм, который человек смотрел бы час.
Шаг 3: Мозг — LLM с инструментами
Самый важный компонент. Мы используем ReAct-паттерн с инструментами: run_dynamic, run_static, search_ioc_db, google_threat_intel. Агент получает задачу: "Проанализируй sample_42.exe". Он строит план: сначала динамический анализ, потом статический, потом сверка с базой угроз.
Обязательно используем memory (stateful) — агент помнит, что уже выяснил. И суб-агентов: как правильно использовать суб-агентов — здесь уместно: один суб-агент для динамики, один для статики, а главный координирует.
from langchain import OpenAI, Tool, AgentExecutor
from langchain.agents import initialize_agent, AgentType
llm = OpenAI(model='gpt-5', temperature=0.2)
tools = [
Tool(name='dynamic_analysis', func=sandbox.run_sample,
description='Запускает образец в песочнице. Возвращает логи API, сеть, файлы.'),
Tool(name='static_analysis', func=ghidra_headless.analyze,
description='Декомпилирует бинарник, возвращает функции, строки, импорты.'),
Tool(name='query_ioc_db', func=virus_total_db.search,
description='Ищет хеш или IP в базе известных индикаторов.')
]
agent = initialize_agent(tools, llm, agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, verbose=True)
agent.run('Analyze /samples/mal.exe and produce a structured report with C2, capabilities, and MITRE ATT&CK techniques.')В реальном коде добавляем async, retry, timeouts. И обязательно проверяем, что агент не сходит с ума и не пытается запустить образец на хост-системе. Для этого production-ready AI-агент должен иметь валидацию вызовов.
Главная ошибка: доверять LLM на слово
Галлюцинации — бич всех LLM. Агент может "увидеть" в декомпилированном коде то, чего нет. Например, придумать C2, который на самом деле — легитимный адрес обновления Windows. Как бороться? Верификация фактов через несколько независимых источников. Используем подход, описанный в статье MAVEN: как снизить галлюцинации LLM на 85%. У нас есть динамика и статика — если оба указывают на одно и то же, вероятность ошибки ниже. Также можно добавить суб-агента-верификатора, который проверяет выводы главного агента по сырым данным.
Второй камень — производительность. Headless Ghidra запускается долго. Для быстрого анализа можно кэшировать результаты одинаковых хешей. Третий — детект VM. Некоторые малвари не запускаются в виртуалке. Для обхода используем разные снапшоты с разными настройками (VMware вместо VirtualBox, фейковые MAC).
Живой пример: как агент разобрал банковского трояна
Допустим, у нас есть образец с хешем a1b2.... Агент сначала запускает динамический анализ. VM стартует, файл копируется, запускается. Через 30 секунд образец начинает стучаться на evil.com:443. Песочница снимает трафик, видит HTTPS, но не может расшифровать (без своего CA). Агент решает: нужно декомпилировать, чтобы найти сертификат или ключ шифрования. Запускает Ghidra, получает функции, находит строку с URL. LLM распознает, что это C2, и вычисляет, что трафик шифруется AES с ключом, вшитым в ресурсы. Агент извлекает ключ, возвращается к динамике, подсовывает его mitmproxy для расшифровки. Через час у нас полный отчет: C2, украденные данные, техники MITRE ATT&CK (T1059.001, T1027).
Конечно, не все образцы такие простые. Некоторые обфусцированы до неузнаваемости, и агент может зациклиться. Но даже частичная автоматизация экономит 80% времени.
Как не выстрелить себе в ногу
- Изоляция. Никогда не запускайте песочницу на том же хосте, где работает агент. Используйте отдельный гипервизор (ESXi) или облачную VM с VLAN.
- Лимиты. Агент может решить запустить бесконечный цикл анализа. Ставьте жесткие лимиты по времени и числу итераций. Используйте stateful memory, чтобы не повторять одни и те же действия.
- Логи. Все запросы к LLM и действия агента логируйте. Если вдруг агент выдаст ложный отчет, можно будет разобраться, почему.
- Человеческий контроль. Не стоит доверять агенту полностью. Пусть он готовит отчет, но финальный вердикт ставит человек. Автоматизация должна помогать, а не заменять экспертизу.
Что дальше: мультиагент и автономная охота
Следующий шаг — кластер агентов. Один агент анализирует, второй ищет похожие образцы в тире, третий генерирует YARA-правила. В статье как спроектировать современного AI-агента описан planner/executor паттерн — идеально для такой системы. Представь: ты загружаешь архив, а через час получаешь готовые сигнатуры, IOCs и описание атаки. Без человека.
Но есть и обратная сторона: чем больше автоматизации, тем сложнее отлавливать ошибки. Если агент пропустит C2, вся защита компании может оказаться под угрозой. Поэтому мой совет — внедрять поэтапно. Сначала автоматизируй только рутину: сбор логов, декомпиляцию. Анализ оставь человеку. Через месяц, когда доверие вырастет, подключай LLM к генерации отчетов. И никогда не убирай человека из цикла окончательного решения.
Кстати, тема самоорганизующихся AI-агентов становится все актуальнее — посмотрите эксперимент как AI-боты самоорганизовались в картель. Если наши агенты для анализа начнут договариваться между собой — это уже сюжет для киберпанка.
Бонус: Полный код проекта (песочница, Ghidra-скрипты, агент) и примеры датасетов доступны в открытом репозитории. Ссылка в моем профиле.