pfSense Plus MIM API toolkit b4acd7ca - Alta - Remoto - Privilegio residual - example-add-devices.py JSON a SSH
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · pfsense-api-enroll-json-ssh
Clase: Privilegio residual Alcance: Remoto
pfSense Plus MIM API toolkit (b4acd7ca) - Netgate
example-add-devices.py es la forma documentada de registrar el controlador Nexus en cada dispositivo pfSense Plus a través de SSH. Aplica json.dumps a GET /mim/controller/identity, reemplaza solo ", y luego aplica .format a ese blob dos veces dentro de un script POSIX curl -d entre comillas dobles. Paramiko exec_command ejecuta el script como SSHUSER (valor predeterminado de ejemplo admin) en cada dirección de pfsense_addresses.
json.dumps más replace('"', '\\"') mantiene las comillas cerradas. $(), las comillas invertidas y ${...} no son metacaracteres de JSON. Permanecen activos dentro de la cadena -d entre comillas dobles que sigue abierta. OpenSSH exec es un shell. Eso es lo residual.
Este no es el paquete REST CE de terceros. Es el cliente OpenAPI oficial y los ejemplos para el controlador pfSense Plus Nexus Multi-instance Management. No compuse Plus. El laboratorio es la interpolación fijada más un mock de /var/run/pfnet-controller.sock.
| ID | sin CVE todavía |
| Clase | Privilegio residual (JSON del controlador hacia el SSH de enrolamiento) |
| Alcance | Remoto (en la ruta hacia CONTROLLER_URL mientras el ejemplo establece verify_ssl=False, o un escritor de campos de cadena de ControllerSummary) |
| CWE | CWE-78 |
| CVSS | Alto: 8.1 CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H |
| Producto | Netgate/pfsense-api (Plus MIM toolkit) |
| Afectado | main público b4acd7ca21dbca739a530403a1f62a7440f7726f example-add-devices.py |
| Autenticación | el operador ejecuta el ejemplo documentado. El atacante está en la ruta, o puede escribir cadenas de resumen. El inicio de sesión en el controlador sigue ocurriendo primero. |
| Licencia | GNU Affero GPL v3.0 |
| Laboratorio | solo 127.0.0.1:19101. Sin imagen de Plus. |
Parte 1 de la serie de residuos de Nexus MIM. Relacionados: enroll-autoadd, unix-sock-noauth, example-ssl-verify (G9 es cómo un par en la ruta da forma a este JSON), fleet-jwt, export-key-get.
Lo residual es la sustitución de comandos dentro de la cadena -d entre comillas dobles que sigue abierta. json.dumps más el paso de comillas mantienen la cadena cerrada. $(), las comillas invertidas y ${...} sobreviven y se ejecutan como SSHUSER cuando OpenSSH hace exec del script.
| Método | Sink | Privilegio | Probado en laboratorio o inferido |
|---|---|---|---|
Poner $() (o backticks / ${...}) en un campo de cadena de ControllerSummary, luego dejar que el operador ejecute example-add-devices.py | controller_info.replace('"', '\\"') luego device_script.format(...) luego sshclient.exec_command(device_script) (example-add-devices.py ~104-161) | Shell como SSHUSER (muestra por defecto admin; el SSH de admin de pfSense suele ser equivalente a root) en cada dirección de pfsense_addresses | Probado en laboratorio en la interpolación: INJECT vpn_listenaddr=$(printf %s PFSENSE-API-ENROLL-JSON-SSH-WITNESS >/oracle/witness) sobrevivió al escape solo de comillas (dollar-paren-survived=yes) y escribió el witness (inject-oracle=yes). Paramiko/SSH en sí no está en este compose. |
MITM de TLS de GET /api/mim/controller/identity mientras la muestra usa verify_ssl=False | El mismo parseo de ControllerSummary y luego el mismo script | El mismo shell. Todos los campos de ControllerSummary son str o Unset, así que un cuerpo JSON de MITM que parsee por tipo es suficiente. | Inferido de la muestra (example-add-devices.py login Client y AuthenticatedClient ambos establecen verify_ssl=False). El laboratorio publica el objeto summary directamente. Hermano: example-ssl-verify. |
Escribir caracteres de sustitución en name o vpn_listenaddr en el controlador, esperar el siguiente enroll | El mismo sink | El mismo shell cuando un operador ejecute la muestra a continuación | Inferido. Requiere una escritura previa de esos campos (ya sea admin del controlador, o el hermano unix-sock-noauth). |
El mismo shell, claves extra vía ControllerSummary.additional_properties | El mismo dump incluye claves MITM extra (to_dict copia los sobrantes después de from_dict) | Los campos extra viajan hacia -d y hacia el shell | Inferido de to_dict. El laboratorio inyecta solo a través de vpn_listenaddr. |
| Método | Sink | Privilegio | Probado en laboratorio o inferido |
|---|---|---|---|
| Leer el stdout de la estación de trabajo de enrollment | print("CONTROLLER_SUMMARY:", controller_info) | Identidad del controlador key, vpn_pubkey / vpn_netkey / direcciones de escucha de Netgard | Inferido del print de la muestra. El laboratorio no imprime un blob de controlador en vivo. |
| Sniffing o MITM del canal exec de SSH | El payload de exec_command(device_script) es el JSON -d de curl | La misma identidad de controlador en el cable hacia cada dispositivo | Inferido. AutoAddPolicy en ese canal es un reporte hermano. |
| Caso CONTROL en el gadget | POST /case name=control | El vpn_listenaddr honesto llega al unix socket sin cambios | Probado en laboratorio. 192.0.2.10:51820 publicado tal cual, sin oracle (control-clean=yes). |
| Método | Sink | Privilegio | Probado en laboratorio o inferido |
|---|---|---|---|
Comando inyectado como SSHUSER | El mismo exec_command | Detener pfnet-controller, borrar el enrollment, reiniciar, o de otro modo sacar el dispositivo de MIM | Inferido como efecto secundario del shell. El laboratorio solo escribe el archivo witness. |
Requiere: la ruta de la muestra oficial (enroll del operador). UI:N para el peer on-path una vez que esa muestra está en ejecución. El login al controlador sigue ocurriendo primero.