
pfSense CE 2.9.0-DEVELOPMENT - Alta - Remota - RCE - limitador número dnctl
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · pfsense-limiter-number
Write-up: https://abraxaslabs.tech/research/pfsense-limiter-number
Classe: RCE Alcance: Remoto
pfSense CE 2.9.0-DEVELOPMENT (9363ac5) - pfsense.org
Os Traffic Shaper Limiters emitem um campo number oculto na edição. A criação sobrescreve esse número com dnpipe_find_nextnumber(). A edição não. validate_input nunca verifica number. GetNumber() é concatenado sem aspas em dnctl pipe|sched|queue delete. O mwexec do PHP é /bin/sh -c. O privilégio é page-firewall-trafficshaper-limiter, não Diagnostics: Command.
| ID | ainda sem CVE |
| Classe | RCE |
| Alcance | Remoto (WebGUI autenticado) |
| CWE | CWE-78 |
| CVSS | Alto: 8.8 CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H |
| Produto | pfSense CE |
| Afetado | 2.9.0-DEVELOPMENT (9363ac5b8651a1c7a333180425ce7719070f95f9) limiter number |
| Autenticação | Sessão WebGUI com page-firewall-trafficshaper-limiter |
| Licença | GNU Affero GPL v3.0 |
| Lab | apenas 127.0.0.1 |
Fixe o master público 9363ac5. O lab é um gadget PHP de ReadConfig / SetNumber / delete_queue fixados. Loopback 127.0.0.1:18840.
| Método | Sink | Privilégio |
|---|---|---|
Criar um limiter, POST save com number do atacante, depois excluir esse limiter | mwexec("/sbin/dnctl pipe delete " . $this->GetNumber()) (shaper.inc:3820) | Integridade (comprovado em lab): shell root. Lab: edit-delete gravou o witness (edit-delete-exec=yes). A sobrescrita na criação e o caminho apply-file não gravaram nada. |
| Mesmo shell root | filesystem do host | Recon (inferido): config.xml, chaves. |
Shell root ou dnctl de números do atacante | dummynet | Disponibilidade (inferido): interrupção de limiter / dummynet. |
Comprovado em lab vs inferido: sobrescrita na criação (sem witness), caminho apply-file (dnctl de um arquivo, sem witness) e execução edit-delete (witness) são comprovados em lab. O recon do filesystem é inferido a partir do PHP-FPM root.
Requer: sessão WebGUI com page-firewall-trafficshaper-limiter. CSRF no POST save. O delete é GET action=delete.
| Superfície | Lab |
|---|---|
| Caminho de criação | dnpipe_find_nextnumber() sobrescreve, create-overwrites=yes |
| Caminho de aplicação | dnctl de /tmp/rules.limiter, nome de arquivo não controlado pelo usuário, apply-file=yes |
| Charset do nome do limiter | ^[a-zA-Z0-9_-]+$ |
| Não autenticado | fechado |
| Diagnostics: Command | permanece fechado a menos que também concedido |
Parâmetros AQM em /tmp/rules.limiter são linguagem dummynet extra, não este resíduo.
cd lab
./run.sh
Loopback 127.0.0.1:18840. Projeto Compose pfsense-limiter-number. Tag de imagem pfsense-limiter-number:2.9.0-dev. Testemunha PFSENSE-LIMITER-NUMBER-WITNESS. Última linha:
SUCCESS PFSENSE-LIMITER-NUMBER create-overwrites=yes apply-file=yes edit-delete-exec=yes PFSENSE-LIMITER-NUMBER-WITNESS
Faça cast para int em GetNumber() antes de cada dnctl. Ignore o number do POST na edição, ou valide seu intervalo em relação ao id ativo do dummynet. A criação já sobrescreve; faça a edição fazer o mesmo.
9363ac5b8651a1c7a333180425ce7719070f95f9shaper.inc delete_queue / GetNumberfirewall_shaper_vinterface.php