
pfSense CE 2.9.0-DEVELOPMENT - Alta - Remoto - RCE - QinQ parent-if ifconfig
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · pfsense-qinq-parent-if
Classe: RCE Alcance: Remoto
pfSense CE 2.9.0-DEVELOPMENT (9363ac5) - pfsense.org
A edição QinQ armazena um nome de interface pai sem verificação does_interface_exist. A edição VLAN já rejeita um pai que não seja uma iface ativa. Form_Select não revalida o POST. Cria write_configs mesmo quando interface_qinq_configure retorna antecipadamente. A adição/remoção de membro então interpola o vlanif armazenado em ifconfig sem escape. O exec do PHP é /bin/sh -c. O PHP-FPM do WebGUI é root. O privilégio é page-interfaces-qinq-edit, não Diagnostics: Command.
| ID | sem CVE ainda |
| 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) edição QinQ |
| Autenticação | Sessão WebGUI com page-interfaces-qinq-edit |
| Licença | GNU Affero GPL v3.0 |
| Lab | apenas 127.0.0.1 |
Fixeio o master público 9363ac5. O lab é um gadget PHP das linhas fixadas vlan_interface / interface_qinq_configure / membro exec, HTTP em loopback em 127.0.0.1:18810.
| Método | Sink | Privilégio |
|---|---|---|
| POST de criação QinQ com um pai que não é uma iface ativa, depois POST de edição adicionando um membro | interface_qinq2_configure exec ifconfig vlan create ... (interfaces.inc:620) | Integridade (comprovado em lab): shell root via /bin/sh -c. Lab: adição de membro qinq2 gravou o witness (member-sink=yes). |
Mesmo vlanif armazenado, POST de edição removendo um membro | exec("/sbin/ifconfig {$parent}.{$tag} destroy") (interfaces_qinq_edit.php:212) | Integridade (comprovado em lab): mesmo exec root. Destroy não tem limite IF_NAMESIZE. |
| Mesmo shell root | sistema de arquivos do host | Recon (inferido): config.xml, chaves, outros tenants. Esta página não imprime a saída do exec. |
Shell root ou ifconfig quebrado | dispositivos vlan | Disponibilidade (inferido): criar/destruir dispositivos vlan; o plano de dados está em jogo. |
Comprovado em lab vs inferido: rejeição de VLAN, create-only sem exec, bloqueio IF_NAMESIZE no comprimento 16, e witness de adição de membro qinq2 são comprovados em lab. Recon do sistema de arquivos e interrupção do plano de dados são inferidos a partir do PHP-FPM root.
Requer: sessão WebGUI com page-interfaces-qinq-edit. Token CSRF. Dois POSTs (criar, depois editar membro). O admin padrão tem a página. Um usuário limitado pode receber apenas esta página.
| Superfície | Lab |
|---|---|
| Verificação de existência do pai VLAN | vlan-rejected=yes |
| QinQ create-only (pai ausente) | armazena config, create-no-exec=yes |
| Comprimento do nome qinq2 16 | if-namesize-block=yes antes do exec |
| Não autenticado / CSRF sem token | guiconfig + CSRF-magic |
Regex de nome GIF/GRE, membros LAGG does_interface_exist + escapeshellarg | outras páginas |
| Exclusão na lista QinQ de um pai nunca criado | does_interface_exist($vlanif) |
| Diagnostics: Command | permanece fechado a menos que também concedido |
Sem Diagnostics: Command. Sem não autenticado. A classe histórica é CVE-2023-42326 GIF/GRE, página diferente.
cd lab
./run.sh
Loopback 127.0.0.1:18810. Projeto Compose pfsense-qinq-parent-if. Tag da imagem pfsense-qinq-parent-if:2.9.0-dev. Witness PFSENSE-QINQ-PARENT-IF-WITNESS. Última linha:
SUCCESS PFSENSE-QINQ-PARENT-IF vlan-rejected=yes create-no-exec=yes member-sink=yes if-namesize-block=yes PFSENSE-QINQ-PARENT-IF-WITNESS
Edição QinQ: rejeitar um pai que não seja uma interface ativa, assim como a edição VLAN. Verificações de inteiro nas tags de membro já existem; ainda assim, aplicar escapeshellarg no vlanif armazenado antes de cada ifconfig. Limitar o destroy de remoção de membro da mesma forma que interface_qinq2_configure limita IF_NAMESIZE.
9363ac5b8651a1c7a333180425ce7719070f95f9interfaces_qinq_edit.phpinterfaces.inc interface_qinq2_configureinterfaces_vlan_edit.php