Criando um 'Pentester Branco' Virtual no Meu Notebook: Um Guia para Automação com IA
Descubra como configurar um ambiente de pentest semi-autônomo em seu notebook utilizando modelos de IA locais e ferramentas como LM Studio e Kali Linux. Este guia detalha o processo de criação de um 'agente' de IA para auxiliar em testes de penetração éticos.
MundiX News·06 de julho de 2026·10 min de leitura·👁 2 views
Criando um 'Pentester Branco' Virtual no Meu Notebook: Um Guia para Automação com IA
Nas últimas semanas, embarquei em uma nova e fascinante empreitada: a utilização de modelos de Inteligência Artificial (IA) locais para realizar pentest 'white hat' (ético) de forma semi-automática. O objetivo é transformar meu notebook em um ambiente de testes robusto, capaz de auxiliar em auditorias de segurança de maneira eficiente e controlada.
O Setup Inicial: Hardware e Software
Para dar vida a este projeto, meu arsenal consiste em:
Notebook: Thinkpad P16 Gen2 equipado com processador i7-13850HX, placa de vídeo dedicada Nvidia RTX 2000 ADA (8 GB VRAM), SSDs Samsung 990 Pro de 1TB e Samsung 980 Pro de 2TB, e um total de 128 GB de RAM (dos quais 32 GB são dedicados a um RAMDISK estático para otimização).
Software: LM Studio rodando em Windows 11 25H2, com uma instalação atual do Python.
Virtualização: Uma instalação portátil do VirtualBox contendo diversas máquinas virtuais (VMs), incluindo a versão mais recente do Kali Linux e a Metasploitable 2 (um ambiente de laboratório para depuração local).
Embora a placa de vídeo com 8 GB de VRAM possa ser considerada um ponto fraco para modelos de IA muito pesados, a combinação de um processador rápido, SSDs velozes e uma quantidade generosa de RAM permite a execução de modelos de IA locais de grande porte. Após semanas de experimentação, optei pelo modelo Qwen 2.5 72B Instruct Q4_K_M, com impressionantes 44 GB. A vantagem desta escolha reside na capacidade de alocar parte das camadas do modelo na VRAM da GPU e o restante na RAM principal, garantindo uma velocidade de processamento de tokens (cerca de 2-3 tokens por segundo) suficiente para minhas necessidades de pentest ético, além de sua notável precisão e menor propensão a 'alucinações' em comparação com modelos menores.
Construindo a Ponte: O Script Python e a Configuração do Ambiente
Para orquestrar a comunicação entre o Windows, o modelo de IA local e a VM do Kali Linux, desenvolvi um script Python experimental, apelidado de "script-ponte". Este script, embora bruto e com espaço para melhorias, é funcional e foi customizado para o modelo Qwen 2.5 72B Instruct.
Configuração das Máquinas Virtuais e Rede:
Kali Linux:
Desligue a VM do Kali no VirtualBox.
Em "Configurações" -> "Rede" -> "Adaptador 1", configure o modo de rede para "NAT".
Em "Avançado" -> "Redirecionamento de Portas", adicione uma nova regra:
Protocolo: TCP
Porta do Host: 22222
Porta do Convidado: 22
Inicie o Kali, abra o terminal e ative o servidor SSH com: sudo systemctl enable ssh --now.
Para permitir que o script rode como root sem senha, edite o sudoers com sudo visudo e adicione a linha kali ALL=(ALL) NOPASSWD: ALL (substitua 'kali' pelo seu nome de usuário).
Configure um segundo adaptador de rede em modo "Rede Interna" para comunicação exclusiva com a VM Metasploitable 2 (ex: IPs 192.168.5.4 para Kali e 192.168.5.3 para Metasploitable 2).
Ambiente Python no Windows:
Instale o Python (certifique-se de marcar "Add python.exe to PATH").
Abra o Prompt de Comando (cmd) como administrador.
Navegue até o seu RAMDISK (ex: W:), crie uma pasta para o ambiente (md W:\AI_Bridge), entre nela (cd W:\AI_Bridge), crie e ative um ambiente virtual (python -m venv env e call env\Scripts\activate).
Instale as bibliotecas necessárias: pip install paramiko openai.
Configuração do LM Studio:
Inicie o LM Studio, carregue o modelo Qwen 2.5 72B Instruct Q4_K_M e inicie-o.
Ajuste as configurações de alocação de camadas entre VRAM e RAM conforme seu hardware.
Na aba "Developer" -> "Local Server", clique em "Start Server" (porta padrão: 1234).
O Script-Ponte (bridge.py):
Crie um arquivo bridge.py na pasta W:\AI_Bridge com o seguinte conteúdo (adaptado para o português):
python
import re
import os
import sys
import time
import threading
import msvcrt
import paramiko
from datetime import datetime
from openai import OpenAI
# === CONFIGURAÇÕES DE CONEXÃO SSH E ARQUIVOS ===KALI_IP ="127.0.0.1"KALI_PORT =22222KALI_USER ="kali"KALI_PASS ="kali"LOG_FILE =r"W:\AI_Bridge\autonomous_audit_log.txt"MAX_HISTORY_TURNS =10client = OpenAI( base_url="http://localhost:1234/v1", api_key="lm-studio", timeout=600.0)SSH_CONN =NoneSSH_CHAN =Nonedeflog_to_file(text):"""Registra ações da IA em um arquivo de log.""" timestamp = datetime.now().strftime("[%Y-%m-%d %H:%M:%S]") os.makedirs(os.path.dirname(LOG_FILE), exist_ok=True)withopen(LOG_FILE,"a", encoding="utf-8")as f: f.write(f"{timestamp}\n{text}\n{'='*50}\n")defrun_recv_thread(channel, stop_event):"""Thread para receber continuamente dados do Kali para o console Windows."""whilenot stop_event.is_set():try:if channel.recv_ready(): data = channel.recv(1024).decode('utf-8', errors='ignore')ifnot data: stop_event.set()break sys.stdout.write(data) sys.stdout.flush() time.sleep(0.01)except Exception: stop_event.set()breakdefrun_send_thread(channel, stop_event):"""Thread para enviar pressionamentos de tecla do Windows para o Kali."""whilenot stop_event.is_set():try: line = sys.stdin.readline()ifnot line:break channel.send(line)except Exception: stop_event.set()breakdefinteractive_shell(channel, manual_override=False):"""Ponte interativa que conecta o teclado ao socket do Kali."""print("\n"+"="*60)if manual_override:print(" ?? INTERCEPTAÇÃO MANUAL DE CONTROLE PELO OPERADOR (PAUSA DA IA) ?? ")else:print(" ?? INTERCEPTAÇÃO CRÍTICA DE CONTROLE DO SISTEMA (CANAL VIVO) ??")print("="*60)print("[SUCESSO] Conectado diretamente ao console de ataque em execução!")print("[!] Para retornar o controle ao agente de IA, digite 'exit' ou pressione Ctrl+C.\n") stop_event = threading.Event() t_recv = threading.Thread(target=run_recv_thread, args=(channel, stop_event), daemon=True) t_send = threading.Thread(target=run_send_thread, args=(channel, stop_event), daemon=True) t_recv.start() t_send.start()whilenot stop_event.is_set():try: time.sleep(0.1)except KeyboardInterrupt: stop_event.set()break stop_event.set()print("\n[-] Retornando ao ciclo autônomo da IA...")defprint_root_cheat_sheet():"""Exibe um menu interativo de dicas para o operador no momento do comprometimento."""print("\n\n"+"!"*60)print(" ?? ALVO COMPROMETIDO COM SUCESSO! O AUTOPILOTO DA IA ESTÁ EM MODO DE PAUSA TOTAL! ?? ")print("!"*60)print("\n SIGA ESTAS INSTRUÇÕES PARA CAPTURAR E ESTABILIZAR O SHELL:\n")print("?"*60)print(" Passo 1: Pressione ENTER uma vez para ativar o socket.")print(" Passo 2: Digite o comando para verificar seus privilégios atuais na sessão:\n whoami")print(" Passo 3: Para tornar o shell cego interativo, digite:\n python -c \"import pty; pty.spawn('/bin/bash')\" ")print(" Passo 4: Certifique-se de que o prompt root@metasploitable:/# apareceu corretamente.")print("?"*60)print(" Pressione Enter para ativar o canal de teclado vivo...\n")defexecute_ssh_cmd(command):global SSH_CONN, SSH_CHAN
command = re.sub(r'^(msf\s*x?v?\d*|kali@\w+|root@\w+)\s*[>#\$\s]*','', command, flags=re.IGNORECASE).strip()print(f"\n[*] [SSH] Enviando comando limpo para a sessão viva: {command}") log_to_file(f"[Execução autônoma de comando]: {command}")if SSH_CONN isNoneor SSH_CHAN isNoneor SSH_CHAN.closed:try: SSH_CONN = paramiko.SSHClient() SSH_CONN.set_missing_host_key_policy(paramiko.AutoAddPolicy()) SSH_CONN.connect(KALI_IP, port=KALI_PORT, username=KALI_USER, password=KALI_PASS, timeout=30) SSH_CHAN = SSH_CONN.get_transport().open_session() SSH_CHAN.get_pty() SSH_CHAN.invoke_shell() SSH_CHAN.send("stty cols 1000 && export PAGER=cat\n") time.sleep(0.5)if SSH_CHAN.recv_ready(): SSH_CHAN.recv(4096)except Exception as e:returnf"Erro ao inicializar SSH: {str(e)}",Falsetry: SSH_CHAN.send(f"{command}\n") time.sleep(2.0) full_output =[] last_read_time = time.time()whileTrue:if SSH_CHAN.recv_ready(): data = SSH_CHAN.recv(4096).decode('utf-8', errors='ignore')if data: sys.stdout.write(data) sys.stdout.flush() full_output.append(data) last_read_time = time.time()if time.time()- last_read_time >1.5:break time.sleep(0.05) combined_output ="".join(full_output) trigger_detected =Falseif re.search(r'(session \d+ opened|session opened|meterpreter >|command shell session|already interactive|uid=0\(root\))', combined_output, re.IGNORECASE): print_root_cheat_sheet() trigger_detected =True interactive_shell(SSH_CHAN, manual_override=False)return combined_output, trigger_detected
except Exception as e:print(f"[-] ERRO CRÍTICO NO PONTE SSH: {str(e)}")returnf"Erro ao executar: {str(e)}",Falsedefmain(): CURRENT_MODEL ="Qwen2.5-Coder-72B-Instruct"print("=== [AGENTE ATIVO] Iniciando Motor Autônomo (V8.0-AbsoluteAutonomy) ===")print("[!] Proteção contra corte de linhas, falhas falsas do msf e comandos 'set' vazios ativa.")print("[*] Limpando o ambiente do Kali Linux antes de iniciar a missão...")try: temp_ssh = paramiko.SSHClient() temp_ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) temp_ssh.connect(KALI_IP, port=KALI_PORT, username=KALI_USER, password=KALI_PASS, timeout=10) temp_ssh.exec_command("sudo killall -9 ruby msfconsole nmap nc telnet ftp") temp_ssh.close()print("[+] Ambiente do Kali completamente limpo.")except Exception as e:print(f"[!] Aviso durante a limpeza do Kali: {e}") user_goal =input("\nDefina a tarefa para o agente: ") log_to_file(f"INICIANDO MISSÃO AUTÔNOMA: {user_goal}") full_system_instruction =("Você é um agente autônomo de pentest de IA. Você controla o terminal do Kali Linux.\n""Seu objetivo é completar a tarefa do usuário e obter um root-shell.\n\n""REGRAS RÍGIDAS DE INTERAÇÃO COM O TERMINAL:\n""1. REGRA DE VELOCIDADE NMAP ABSOLUTA: Você é PROIBIDO de usar flags lentas '-p-' ou '-A'! ""Para escaneamento, use ESTRITAMENTE a flag rápida e leve: 'nmap -sV --open <target>'.\n""2. O terminal mantém o contexto (como um Bash vivo). Todas as suas ações são executadas em uma única sessão contínua.\n""3. PROIBIÇÃO ABSOLUTA DE PONTO E VÍRGULA: Dentro do msfconsole, você é estritamente proibido de separar comandos com ';'! ""O Metasploit interpreta ';' como parte do nome do módulo e gera um erro. Envie comandos separando-os com uma nova linha normal.\n""4. REGRA DE LHOST OBRIGATÓRIO: Antes de digitar o comando 'exploit' ou 'run' no Metasploit, você DEVE definir manualmente o IP local correto com o comando 'set LHOST <IP_do_agente>' na etapa anterior. ""Não confie nos valores padrão do Metasploit.\n""5. CONTEXTO DO PROMPT: Sempre analise o prompt do prompt no log. Se o prompt atual contiver 'msf >' ou 'msf exploit', isso significa que você ESTÁ DENTRO do msfconsole.\n""6. Envie comandos estritamente dentro de um bloco de código ```bash ... ``` sem comentários.") session_history =[{"role":"system","content": full_system_instruction},{"role":"user","content":f"Missão inicial: {user_goal}. Seu IP local para LHOST: {KALI_IP if KALI_IP !='127.0.0.1'else'192.168.5.4'}"}] step_counter =1 last_terminal_prompt =""try:whileTrue:if msvcrt.kbhit(): key = msvcrt.getch().decode('utf-8', errors='ignore').lower()if key =='p':print("\n[!] SINAL DE PAUSA MANUAL DETECTADO PELO OPERADOR DA IA.")global SSH_CHAN
if SSH_CHAN andnot SSH_CHAN.closed: interactive_shell(SSH_CHAN, manual_override=True)print("[+] Pausa removida. Devolvendo controle ao agente de IA...")print(f"\n Iniciando etapa de cálculo #{step_counter}...")iflen(session_history)>(MAX_HISTORY_TURNS *2)+2:del session_history[2:4]try: completion = client.chat.completions.create(model=CURRENT_MODEL, messages=session_history, temperature=0.0)except Exception as e:print(f"[-] Erro ao chamar a API: {e}")breaktry:ifhasattr(completion,'choices')andlen(completion.choices)>0: first_choice = completion.choices[0]ifhasattr(first_choice,'message')andhasattr(first_choice.message,'content'): response = first_choice.message.content
elifisinstance(first_choice,dict)and'message'in first_choice: response = first_choice['message']['content']else: response =getattr(first_choice,'text','')else: data = completion.model_dump()ifhasattr(completion,'model_dump')elsedict(completion) response = data['choices'][0]['message']['content']except Exception as e:print(f"[-] Erro ao analisar a resposta da API: {e}")break clean_response = response.strip()print(f"\n[Resposta do Assistente de IA]:\n{clean_response}") cmd_to_run =""try: commands = re.findall(r'```(?:bash|sh)?\s*(.*?)\s*```', clean_response, re.DOTALL)ifnot commands:ifany(k in clean_response for k in["nmap","set ","use ","exploit","msfconsole","exit"]): lines =[l.strip()for l in clean_response.split('\n')if l.strip()]if lines: cmd_to_run ="\n".join(lines)else:print(f"[-] IA enviou texto normal na etapa {step_counter}.") session_history.append({"role":"assistant","content": response}) session_history.append({"role":"user","content":"Erro: Envie um comando bash específico no formato ```bash ... ```"}) step_counter +=1continueelse: first_block = commands[0] target_lines =[line.strip()for line in first_block.split('\n')if line.strip()andnot line.strip().startswith('#')]if target_lines: cmd_to_run ="\n".join(target_lines)except Exception as parse_err:print(f"[-] Erro interno de análise de string: {parse_err}. Recuperando etapa.") cmd_to_run =""ifnot cmd_to_run:print("[-] Nenhum comando válido detectado. Solicitando novamente.") session_history.append({"role":"user","content":"Erro de análise de marcação. Repita o comando corretamente."})continue first_line_check = cmd_to_run.split('\n')[0].strip()if"set "in first_line_check and"msf >"in last_terminal_prompt andnot"exploit("in last_terminal_prompt:print("[!] Interceptando erro de datastore: IA envia 'set' no menu raiz. Corrigindo feedback.") user_feedback ="Atenção: Você está no menu raiz msf >. Seu comando set foi ignorado. Primeiro, selecione um exploit com o comando 'use <caminho_do_modulo>'!" session_history.append({"role":"assistant","content": response}) session_history.append({"role":"user","content": user_feedback}) step_counter +=1continue is_actually_in_msf ="msf >"in last_terminal_prompt or"msf exploit("in last_terminal_prompt or"msf auxiliary("in last_terminal_prompt
if"msfconsole"in first_line_check and is_actually_in_msf:print(f"[!] Interceptando recursão: IA chamando msfconsole dentro de msfconsole.") user_feedback ="Atenção: Você já está dentro do msfconsole! Não digite 'msfconsole'. Use comandos puros 'use' ou 'set'." session_history.append({"role":"assistant","content": response}) session_history.append({"role":"user","content": user_feedback}) step_counter +=1continueifany(k in first_line_check for k in["set ","use ","exploit"])andnot is_actually_in_msf and"kali@kali"in last_terminal_prompt:print("[!] Saindo do msf real: Restaurando automaticamente o console Metasploit.") cmd_to_run =f"msfconsole -q -x '{cmd_to_run}'"if"nmap"in first_line_check and is_actually_in_msf:print("[!] Modelo envia nmap dentro do msfconsole. Forçando saída para Bash.") cmd_to_run ="exit"print(f"\n[Agente enviando]: {cmd_to_run}") kali_output, root_pwned = execute_ssh_cmd(cmd_to_run)if root_pwned:print("\n[*] Interceptação manual concluída. O controlador está segurando a janela.")break last_terminal_prompt = kali_output
ifnot kali_output orlen(kali_output.strip())==0: user_feedback =f"O resultado da execução do comando '{cmd_to_run}' está vazio. Continue a auditoria do host."else: user_feedback =f"O resultado da execução do seu comando '{cmd_to_run}':\n```text\n{kali_output}\n```\nAnalise esta saída do terminal, preste atenção ao prompt do prompt e envie o PRÓXIMO comando." session_history.append({"role":"assistant","content": response}) session_history.append({"role":"user","content": user_feedback}) step_counter +=1print("-"*40)except KeyboardInterrupt:print("\n[-] Operação do agente interrompida de emergência pelo operador.")print("\n"+"="*60)print("[FIM] Ciclo principal concluído. A janela está sendo mantida pelo script.")print("Pressione Enter para sair completamente...")input()if __name__ =="__main__": main()
Execução e Próximos Passos
Para iniciar o ambiente, após a configuração inicial e com o LM Studio rodando com o modelo carregado:
Inicie as VMs do Kali Linux e Metasploitable 2.
Abra o Prompt de Comando no Windows, navegue até W:\AI_Bridge e execute o script bridge.py.
Um arquivo .bat pode ser criado para automatizar a ativação do ambiente Python e a execução do script.
Para atualizar as bibliotecas, execute pip install --upgrade paramiko openai no ambiente ativado.
Com o ambiente pronto, você pode definir sua primeira tarefa, por exemplo: "Audite o host 192.168.5.3 (Metasploitable 2) do zero até obter um root-shell. Comece com nmap. Seu IP é 192.168.5.4". Em poucos minutos, o agente de IA, guiado pelo script-ponte, realizará o escaneamento e buscará por vulnerabilidades, pausando e entregando o controle ao operador (você) ao obter acesso root, juntamente com dicas úteis.
Embora a Metasploitable 2 seja um ambiente controlado, este projeto representa um ponto de partida promissor para explorar as capacidades da IA em pentest ético. Há muito a ser aprimorado, mas o potencial para automação e auxílio em tarefas de segurança é imenso. Boa sorte em seus experimentos éticos e legais!
🛡️⚡
Pare de pesquisar. Comece a hackear.
O MundiX é seu copiloto de pentest com IA: comandos exatos, análise de outputs e próximo passo na kill chain — em segundos.
Sem cartão para começar · Planos a partir de R$49/mês
Criando um 'Pentester Branco' Virtual no Meu Notebook: Um Guia para Automação com IA
Nas últimas semanas, embarquei em uma nova e fascinante empreitada: a utilização de modelos de Inteligência Artificial (IA) locais para realizar pentest 'white hat' (ético) de forma semi-automática. O objetivo é transformar meu notebook em um ambiente de testes robusto, capaz de auxiliar em auditorias de segurança de maneira eficiente e controlada.
O Setup Inicial: Hardware e Software
Para dar vida a este projeto, meu arsenal consiste em:
Notebook: Thinkpad P16 Gen2 equipado com processador i7-13850HX, placa de vídeo dedicada Nvidia RTX 2000 ADA (8 GB VRAM), SSDs Samsung 990 Pro de 1TB e Samsung 980 Pro de 2TB, e um total de 128 GB de RAM (dos quais 32 GB são dedicados a um RAMDISK estático para otimização).
Software: LM Studio rodando em Windows 11 25H2, com uma instalação atual do Python.
Virtualização: Uma instalação portátil do VirtualBox contendo diversas máquinas virtuais (VMs), incluindo a versão mais recente do Kali Linux e a Metasploitable 2 (um ambiente de laboratório para depuração local).
Embora a placa de vídeo com 8 GB de VRAM possa ser considerada um ponto fraco para modelos de IA muito pesados, a combinação de um processador rápido, SSDs velozes e uma quantidade generosa de RAM permite a execução de modelos de IA locais de grande porte. Após semanas de experimentação, optei pelo modelo Qwen 2.5 72B Instruct Q4_K_M, com impressionantes 44 GB. A vantagem desta escolha reside na capacidade de alocar parte das camadas do modelo na VRAM da GPU e o restante na RAM principal, garantindo uma velocidade de processamento de tokens (cerca de 2-3 tokens por segundo) suficiente para minhas necessidades de pentest ético, além de sua notável precisão e menor propensão a 'alucinações' em comparação com modelos menores.
Construindo a Ponte: O Script Python e a Configuração do Ambiente
Para orquestrar a comunicação entre o Windows, o modelo de IA local e a VM do Kali Linux, desenvolvi um script Python experimental, apelidado de "script-ponte". Este script, embora bruto e com espaço para melhorias, é funcional e foi customizado para o modelo Qwen 2.5 72B Instruct.
Configuração das Máquinas Virtuais e Rede:
Kali Linux:
Desligue a VM do Kali no VirtualBox.
Em "Configurações" -> "Rede" -> "Adaptador 1", configure o modo de rede para "NAT".
Em "Avançado" -> "Redirecionamento de Portas", adicione uma nova regra:
Protocolo: TCP
Porta do Host: 22222
Porta do Convidado: 22
Inicie o Kali, abra o terminal e ative o servidor SSH com: sudo systemctl enable ssh --now.
Para permitir que o script rode como root sem senha, edite o sudoers com sudo visudo e adicione a linha kali ALL=(ALL) NOPASSWD: ALL (substitua 'kali' pelo seu nome de usuário).
Configure um segundo adaptador de rede em modo "Rede Interna" para comunicação exclusiva com a VM Metasploitable 2 (ex: IPs 192.168.5.4 para Kali e 192.168.5.3 para Metasploitable 2).
Ambiente Python no Windows:
Instale o Python (certifique-se de marcar "Add python.exe to PATH").
Abra o Prompt de Comando (cmd) como administrador.
Navegue até o seu RAMDISK (ex: W:), crie uma pasta para o ambiente (md W:\AI_Bridge), entre nela (cd W:\AI_Bridge), crie e ative um ambiente virtual (python -m venv env e call env\Scripts\activate).
Instale as bibliotecas necessárias: pip install paramiko openai.
Configuração do LM Studio:
Inicie o LM Studio, carregue o modelo Qwen 2.5 72B Instruct Q4_K_M e inicie-o.
Ajuste as configurações de alocação de camadas entre VRAM e RAM conforme seu hardware.
Na aba "Developer" -> "Local Server", clique em "Start Server" (porta padrão: 1234).
O Script-Ponte (bridge.py):
Crie um arquivo bridge.py na pasta W:\AI_Bridge com o seguinte conteúdo (adaptado para o português):
import re
import os
import sys
import time
import threading
import msvcrt
import paramiko
from datetime import datetime
from openai import OpenAI
# === CONFIGURAÇÕES DE CONEXÃO SSH E ARQUIVOS ===
KALI_IP = "127.0.0.1"
KALI_PORT = 22222
KALI_USER = "kali"
KALI_PASS = "kali"
LOG_FILE = r"W:\AI_Bridge\autonomous_audit_log.txt"
MAX_HISTORY_TURNS = 10
client = OpenAI(
base_url="http://localhost:1234/v1",
api_key="lm-studio",
timeout=600.0
)
SSH_CONN = None
SSH_CHAN = None
def log_to_file(text):
"""Registra ações da IA em um arquivo de log."""
timestamp = datetime.now().strftime("[%Y-%m-%d %H:%M:%S]")
os.makedirs(os.path.dirname(LOG_FILE), exist_ok=True)
with open(LOG_FILE, "a", encoding="utf-8") as f:
f.write(f"{timestamp}\n{text}\n{'='*50}\n")
def run_recv_thread(channel, stop_event):
"""Thread para receber continuamente dados do Kali para o console Windows."""
while not stop_event.is_set():
try:
if channel.recv_ready():
data = channel.recv(1024).decode('utf-8', errors='ignore')
if not data:
stop_event.set()
break
sys.stdout.write(data)
sys.stdout.flush()
time.sleep(0.01)
except Exception:
stop_event.set()
break
def run_send_thread(channel, stop_event):
"""Thread para enviar pressionamentos de tecla do Windows para o Kali."""
while not stop_event.is_set():
try:
line = sys.stdin.readline()
if not line:
break
channel.send(line)
except Exception:
stop_event.set()
break
def interactive_shell(channel, manual_override=False):
"""Ponte interativa que conecta o teclado ao socket do Kali."""
print("\n" + "="*60)
if manual_override:
print(" ?? INTERCEPTAÇÃO MANUAL DE CONTROLE PELO OPERADOR (PAUSA DA IA) ?? ")
else:
print(" ?? INTERCEPTAÇÃO CRÍTICA DE CONTROLE DO SISTEMA (CANAL VIVO) ??")
print("="*60)
print("[SUCESSO] Conectado diretamente ao console de ataque em execução!")
print("[!] Para retornar o controle ao agente de IA, digite 'exit' ou pressione Ctrl+C.\n")
stop_event = threading.Event()
t_recv = threading.Thread(target=run_recv_thread, args=(channel, stop_event), daemon=True)
t_send = threading.Thread(target=run_send_thread, args=(channel, stop_event), daemon=True)
t_recv.start()
t_send.start()
while not stop_event.is_set():
try:
time.sleep(0.1)
except KeyboardInterrupt:
stop_event.set()
break
stop_event.set()
print("\n[-] Retornando ao ciclo autônomo da IA...")
def print_root_cheat_sheet():
"""Exibe um menu interativo de dicas para o operador no momento do comprometimento."""
print("\n\n" + "!"*60)
print(" ?? ALVO COMPROMETIDO COM SUCESSO! O AUTOPILOTO DA IA ESTÁ EM MODO DE PAUSA TOTAL! ?? ")
print("!"*60)
print("\n SIGA ESTAS INSTRUÇÕES PARA CAPTURAR E ESTABILIZAR O SHELL:\n")
print("?" * 60)
print(" Passo 1: Pressione ENTER uma vez para ativar o socket.")
print(" Passo 2: Digite o comando para verificar seus privilégios atuais na sessão:\n whoami")
print(" Passo 3: Para tornar o shell cego interativo, digite:\n python -c \"import pty; pty.spawn('/bin/bash')\" ")
print(" Passo 4: Certifique-se de que o prompt root@metasploitable:/# apareceu corretamente.")
print("?" * 60)
print(" Pressione Enter para ativar o canal de teclado vivo...\n")
def execute_ssh_cmd(command):
global SSH_CONN, SSH_CHAN
command = re.sub(r'^(msf\s*x?v?\d*|kali@\w+|root@\w+)\s*[>#\$\s]*', '', command, flags=re.IGNORECASE).strip()
print(f"\n[*] [SSH] Enviando comando limpo para a sessão viva: {command}")
log_to_file(f"[Execução autônoma de comando]: {command}")
if SSH_CONN is None or SSH_CHAN is None or SSH_CHAN.closed:
try:
SSH_CONN = paramiko.SSHClient()
SSH_CONN.set_missing_host_key_policy(paramiko.AutoAddPolicy())
SSH_CONN.connect(KALI_IP, port=KALI_PORT, username=KALI_USER, password=KALI_PASS, timeout=30)
SSH_CHAN = SSH_CONN.get_transport().open_session()
SSH_CHAN.get_pty()
SSH_CHAN.invoke_shell()
SSH_CHAN.send("stty cols 1000 && export PAGER=cat\n")
time.sleep(0.5)
if SSH_CHAN.recv_ready():
SSH_CHAN.recv(4096)
except Exception as e:
return f"Erro ao inicializar SSH: {str(e)}", False
try:
SSH_CHAN.send(f"{command}\n")
time.sleep(2.0)
full_output = []
last_read_time = time.time()
while True:
if SSH_CHAN.recv_ready():
data = SSH_CHAN.recv(4096).decode('utf-8', errors='ignore')
if data:
sys.stdout.write(data)
sys.stdout.flush()
full_output.append(data)
last_read_time = time.time()
if time.time() - last_read_time > 1.5:
break
time.sleep(0.05)
combined_output = "".join(full_output)
trigger_detected = False
if re.search(r'(session \d+ opened|session opened|meterpreter >|command shell session|already interactive|uid=0\(root\))', combined_output, re.IGNORECASE):
print_root_cheat_sheet()
trigger_detected = True
interactive_shell(SSH_CHAN, manual_override=False)
return combined_output, trigger_detected
except Exception as e:
print(f"[-] ERRO CRÍTICO NO PONTE SSH: {str(e)}")
return f"Erro ao executar: {str(e)}", False
def main():
CURRENT_MODEL = "Qwen2.5-Coder-72B-Instruct"
print("=== [AGENTE ATIVO] Iniciando Motor Autônomo (V8.0-AbsoluteAutonomy) ===")
print("[!] Proteção contra corte de linhas, falhas falsas do msf e comandos 'set' vazios ativa.")
print("[*] Limpando o ambiente do Kali Linux antes de iniciar a missão...")
try:
temp_ssh = paramiko.SSHClient()
temp_ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
temp_ssh.connect(KALI_IP, port=KALI_PORT, username=KALI_USER, password=KALI_PASS, timeout=10)
temp_ssh.exec_command("sudo killall -9 ruby msfconsole nmap nc telnet ftp")
temp_ssh.close()
print("[+] Ambiente do Kali completamente limpo.")
except Exception as e:
print(f"[!] Aviso durante a limpeza do Kali: {e}")
user_goal = input("\nDefina a tarefa para o agente: ")
log_to_file(f"INICIANDO MISSÃO AUTÔNOMA: {user_goal}")
full_system_instruction = (
"Você é um agente autônomo de pentest de IA. Você controla o terminal do Kali Linux.\n"
"Seu objetivo é completar a tarefa do usuário e obter um root-shell.\n\n"
"REGRAS RÍGIDAS DE INTERAÇÃO COM O TERMINAL:\n"
"1. REGRA DE VELOCIDADE NMAP ABSOLUTA: Você é PROIBIDO de usar flags lentas '-p-' ou '-A'! "
"Para escaneamento, use ESTRITAMENTE a flag rápida e leve: 'nmap -sV --open <target>'.\n"
"2. O terminal mantém o contexto (como um Bash vivo). Todas as suas ações são executadas em uma única sessão contínua.\n"
"3. PROIBIÇÃO ABSOLUTA DE PONTO E VÍRGULA: Dentro do msfconsole, você é estritamente proibido de separar comandos com ';'! "
"O Metasploit interpreta ';' como parte do nome do módulo e gera um erro. Envie comandos separando-os com uma nova linha normal.\n"
"4. REGRA DE LHOST OBRIGATÓRIO: Antes de digitar o comando 'exploit' ou 'run' no Metasploit, você DEVE definir manualmente o IP local correto com o comando 'set LHOST <IP_do_agente>' na etapa anterior. "
"Não confie nos valores padrão do Metasploit.\n"
"5. CONTEXTO DO PROMPT: Sempre analise o prompt do prompt no log. Se o prompt atual contiver 'msf >' ou 'msf exploit', isso significa que você ESTÁ DENTRO do msfconsole.\n"
"6. Envie comandos estritamente dentro de um bloco de código ```bash ... ``` sem comentários."
)
session_history = [
{"role": "system", "content": full_system_instruction},
{"role": "user", "content": f"Missão inicial: {user_goal}. Seu IP local para LHOST: {KALI_IP if KALI_IP != '127.0.0.1' else '192.168.5.4'}"}
]
step_counter = 1
last_terminal_prompt = ""
try:
while True:
if msvcrt.kbhit():
key = msvcrt.getch().decode('utf-8', errors='ignore').lower()
if key == 'p':
print("\n[!] SINAL DE PAUSA MANUAL DETECTADO PELO OPERADOR DA IA.")
global SSH_CHAN
if SSH_CHAN and not SSH_CHAN.closed:
interactive_shell(SSH_CHAN, manual_override=True)
print("[+] Pausa removida. Devolvendo controle ao agente de IA...")
print(f"\n Iniciando etapa de cálculo #{step_counter}...")
if len(session_history) > (MAX_HISTORY_TURNS * 2) + 2:
del session_history[2:4]
try:
completion = client.chat.completions.create(model=CURRENT_MODEL, messages=session_history, temperature=0.0)
except Exception as e:
print(f"[-] Erro ao chamar a API: {e}")
break
try:
if hasattr(completion, 'choices') and len(completion.choices) > 0:
first_choice = completion.choices[0]
if hasattr(first_choice, 'message') and hasattr(first_choice.message, 'content'):
response = first_choice.message.content
elif isinstance(first_choice, dict) and 'message' in first_choice:
response = first_choice['message']['content']
else:
response = getattr(first_choice, 'text', '')
else:
data = completion.model_dump() if hasattr(completion, 'model_dump') else dict(completion)
response = data['choices'][0]['message']['content']
except Exception as e:
print(f"[-] Erro ao analisar a resposta da API: {e}")
break
clean_response = response.strip()
print(f"\n[Resposta do Assistente de IA]:\n{clean_response}")
cmd_to_run = ""
try:
commands = re.findall(r'```(?:bash|sh)?\s*(.*?)\s*```', clean_response, re.DOTALL)
if not commands:
if any(k in clean_response for k in ["nmap", "set ", "use ", "exploit", "msfconsole", "exit"]):
lines = [l.strip() for l in clean_response.split('\n') if l.strip()]
if lines:
cmd_to_run = "\n".join(lines)
else:
print(f"[-] IA enviou texto normal na etapa {step_counter}.")
session_history.append({"role": "assistant", "content": response})
session_history.append({"role": "user", "content": "Erro: Envie um comando bash específico no formato ```bash ... ```"})
step_counter += 1
continue
else:
first_block = commands[0]
target_lines = [line.strip() for line in first_block.split('\n') if line.strip() and not line.strip().startswith('#')]
if target_lines:
cmd_to_run = "\n".join(target_lines)
except Exception as parse_err:
print(f"[-] Erro interno de análise de string: {parse_err}. Recuperando etapa.")
cmd_to_run = ""
if not cmd_to_run:
print("[-] Nenhum comando válido detectado. Solicitando novamente.")
session_history.append({"role": "user", "content": "Erro de análise de marcação. Repita o comando corretamente."})
continue
first_line_check = cmd_to_run.split('\n')[0].strip()
if "set " in first_line_check and "msf >" in last_terminal_prompt and not "exploit(" in last_terminal_prompt:
print("[!] Interceptando erro de datastore: IA envia 'set' no menu raiz. Corrigindo feedback.")
user_feedback = "Atenção: Você está no menu raiz msf >. Seu comando set foi ignorado. Primeiro, selecione um exploit com o comando 'use <caminho_do_modulo>'!"
session_history.append({"role": "assistant", "content": response})
session_history.append({"role": "user", "content": user_feedback})
step_counter += 1
continue
is_actually_in_msf = "msf >" in last_terminal_prompt or "msf exploit(" in last_terminal_prompt or "msf auxiliary(" in last_terminal_prompt
if "msfconsole" in first_line_check and is_actually_in_msf:
print(f"[!] Interceptando recursão: IA chamando msfconsole dentro de msfconsole.")
user_feedback = "Atenção: Você já está dentro do msfconsole! Não digite 'msfconsole'. Use comandos puros 'use' ou 'set'."
session_history.append({"role": "assistant", "content": response})
session_history.append({"role": "user", "content": user_feedback})
step_counter += 1
continue
if any(k in first_line_check for k in ["set ", "use ", "exploit"]) and not is_actually_in_msf and "kali@kali" in last_terminal_prompt:
print("[!] Saindo do msf real: Restaurando automaticamente o console Metasploit.")
cmd_to_run = f"msfconsole -q -x '{cmd_to_run}'"
if "nmap" in first_line_check and is_actually_in_msf:
print("[!] Modelo envia nmap dentro do msfconsole. Forçando saída para Bash.")
cmd_to_run = "exit"
print(f"\n[Agente enviando]: {cmd_to_run}")
kali_output, root_pwned = execute_ssh_cmd(cmd_to_run)
if root_pwned:
print("\n[*] Interceptação manual concluída. O controlador está segurando a janela.")
break
last_terminal_prompt = kali_output
if not kali_output or len(kali_output.strip()) == 0:
user_feedback = f"O resultado da execução do comando '{cmd_to_run}' está vazio. Continue a auditoria do host."
else:
user_feedback = f"O resultado da execução do seu comando '{cmd_to_run}':\n```text\n{kali_output}\n```\nAnalise esta saída do terminal, preste atenção ao prompt do prompt e envie o PRÓXIMO comando."
session_history.append({"role": "assistant", "content": response})
session_history.append({"role": "user", "content": user_feedback})
step_counter += 1
print("-" * 40)
except KeyboardInterrupt:
print("\n[-] Operação do agente interrompida de emergência pelo operador.")
print("\n" + "="*60)
print("[FIM] Ciclo principal concluído. A janela está sendo mantida pelo script.")
print("Pressione Enter para sair completamente...")
input()
if __name__ == "__main__":
main()
Execução e Próximos Passos
Para iniciar o ambiente, após a configuração inicial e com o LM Studio rodando com o modelo carregado:
Inicie as VMs do Kali Linux e Metasploitable 2.
Abra o Prompt de Comando no Windows, navegue até W:\AI_Bridge e execute o script bridge.py.
Um arquivo .bat pode ser criado para automatizar a ativação do ambiente Python e a execução do script.
Para atualizar as bibliotecas, execute pip install --upgrade paramiko openai no ambiente ativado.
Com o ambiente pronto, você pode definir sua primeira tarefa, por exemplo: "Audite o host 192.168.5.3 (Metasploitable 2) do zero até obter um root-shell. Comece com nmap. Seu IP é 192.168.5.4". Em poucos minutos, o agente de IA, guiado pelo script-ponte, realizará o escaneamento e buscará por vulnerabilidades, pausando e entregando o controle ao operador (você) ao obter acesso root, juntamente com dicas úteis.
Embora a Metasploitable 2 seja um ambiente controlado, este projeto representa um ponto de partida promissor para explorar as capacidades da IA em pentest ético. Há muito a ser aprimorado, mas o potencial para automação e auxílio em tarefas de segurança é imenso. Boa sorte em seus experimentos éticos e legais!
📤 Compartilhar & Baixar
🧰 Ferramentas recomendadas
Divulgação: alguns links são patrocinados. Podemos receber comissão se você comprar — sem custo extra para você. Só indicamos o que faz sentido para a comunidade.