Skip to content
KitploitKITPLOIT
HerramientasBlog
Enviar
HerramientasBlog
Enviar

¡Herramientas de Hacking, PenTest y Ciberseguridad para tu Arsenal de Seguridad!

Kitploit es un directorio de herramientas de hacking, ciberseguridad y pentesting. Descubre las últimas actualizaciones de proyectos para encontrar vulnerabilidades, analizar sistemas, automatizar pruebas y fortalecer tu seguridad.

··Feeds·Contacto·Privacidad·© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
nifi-CVE-2026-39816-poc — POC para CVE-2026-39816 que permite a usuarios de NiFi sin permisos de ejecución de código ejecutar scripts arbitrarios | Kitploit
Herramientas/GitHubGitHub/zeropathai/nifi-cve-2026-39816-poc
Escalada de PrivilegiosAnálisis de VulnerabilidadesExplotaciónExplotación de Aplicaciones WebPruebas de PenetraciónRed Teaming
GitHubzeropathai/nifi-cve-2026-39816-poc

nifi-CVE-2026-39816-poc

POC para CVE-2026-39816 que permite a usuarios de NiFi sin permisos de ejecución de código ejecutar scripts arbitrarios

Más Populares

Ver todos →

Descubre las herramientas más usadas por nuestra comunidad.

Explora todas las herramientas

Explora nuestra colección de herramientas

Ver todas las herramientas →
Compartir
Ver Repositorio
11hace 3 mesesAún no revisado

Apache NiFi CVE-2026-39816 POC

Demostración de prueba de concepto para CVE-2026-39816, una omisión del permiso EXECUTE_CODE en Apache NiFi 2.8.0 que permite a un diseñador de flujos al que se le han denegado deliberadamente los privilegios de ejecución de código ejecutar Groovy arbitrario en la JVM de NiFi a través del procesador ExecuteGraphQuery del graph bundle.

  • Corregido en NiFi 2.9.0
  • Descubierto por ZeroPath -- artículo técnico completo disponible aquí.

Vulnerabilidad

Anotación @Restricted faltante en TinkerpopClientService (CVE-2026-39816, CWE-95)

NiFi restringe los procesadores que ejecutan código detrás del permiso EXECUTE_CODE mediante la anotación @Restricted(requiredPermission = RequiredPermission.EXECUTE_CODE). Los 16 componentes de scripting dedicados en NiFi — ExecuteScript, InvokeScriptedProcessor, ExecuteGroovyScript, ScriptedTransformRecord, etc. — llevan esta anotación, por lo que un diseñador de flujos debe tener el permiso explícito EXECUTE_CODE antes de que la capa de autorización le permita crear o configurar estos procesadores.

El graph bundle (nifi-graph-nar + nifi-other-graph-services-nar) incluye una tercera vía de ejecución de código que carece de esta anotación:

root@kitploit:~
// nifi-extension-bundles/nifi-graph-bundle/nifi-other-graph-services/
//   src/main/java/org/apache/nifi/graph/TinkerpopClientService.java:451
protected Map<String, String> bytecodeSubmission(
        String s, Map<String, Object> map, GraphQueryResultCallback cb) {
    ...
    compiled = groovyShell.parse(s);     // línea 463 — compila la cadena del atacante
    compiledCode.put(s, compiled);
    ...
    compiled.setBinding(bindings);
    Object result = compiled.run();      // línea 477 — ejecuta en la JVM de NiFi

El parámetro s es la cadena de consulta de la propiedad "Graph Query" del procesador ExecuteGraphQuery, pasada sin cambios. No hay saneamiento, ni lista blanca, ni sandbox — cualquier Groovy válido se compila y ejecuta con todos los privilegios del proceso de NiFi.

Ni TinkerpopClientService ni los procesadores ExecuteGraphQuery / ExecuteGraphQueryRecord que lo utilizan llevan la anotación @Restricted. Por lo tanto, la capa de autorización de NiFi los trata como componentes ordinarios, y un diseñador de flujos al que se le ha denegado explícitamente EXECUTE_CODE aún puede crearlos.

¿Cuándo es explotable un servidor?

Un servidor NiFi 2.8.0 es explotable cuando ambas de las siguientes condiciones son verdaderas:

  1. El graph bundle opcional está instalado. Específicamente el NAR nifi-other-graph-services-nar — este es el bundle que incluye TinkerpopClientService. Los servidores sin este NAR no se ven afectados.

  2. Al menos un usuario tiene permisos de diseñador de flujos (read/write en un grupo de procesos y en /controller) sin EXECUTE_CODE. Esta es una forma de política común: una organización quiere que los usuarios puedan construir y modificar pipelines, pero no ejecutar código arbitrario. El permiso EXECUTE_CODE es precisamente el límite de seguridad que esa política pretende hacer cumplir.

Si ambas condiciones se cumplen, el usuario puede configurar un TinkerpopClientService en modo "ByteCode Submission", apuntarlo a cualquier servidor Gremlin alcanzable (el servidor Gremlin solo se usa para la inicialización del servicio — la ejecución ocurre localmente), y crear un procesador ExecuteGraphQuery con código Groovy en la propiedad "Graph Query". Iniciar el procesador compila y ejecuta el Groovy en la JVM de NiFi.

¿Qué puede hacer un atacante?

Ejecución de código arbitrario como la cuenta de servicio de NiFi. Desde ahí:

  • Leer y modificar todo en el sistema de archivos del host de NiFi, incluyendo el keystore, la clave de propiedades sensibles y cualquier secreto cifrado del flujo.
  • Alcanzar todos los sistemas internos que NiFi puede alcanzar. NiFi típicamente se encuentra junto a credenciales de data warehouse, bus de mensajes, almacenamiento de objetos y bases de datos en sus Contextos de Parámetros y Servicios de Control — el payload Groovy puede leerlos todos y pivotar.
  • Establecer persistencia escribiendo en flow.json.gz, colocando un NAR en el directorio de autocarga, o modificando un servicio de control.

El exploit omite el permiso EXECUTE_CODE, por lo que funciona incluso cuando el operador ha eliminado explícitamente los derechos de ejecución de código del usuario — exactamente el escenario que el permiso existe para prevenir.

Alcance del POC

Este repositorio incluye un POC, que cubre el desencadenante más directo: Groovy controlado por el atacante colocado directamente en la propiedad del procesador Graph Query. Sin conexión ascendente, sin Expression Language, sin necesidad de contenido FlowFile — solo el procesador ejecutándose en su propio temporizador.

Existen dos vías de código adicionales (contenido del cuerpo del FlowFile usado como consulta cuando Graph Query está vacío, e interpolación de Expression Language de atributos FlowFile influenciados por el atacante en la plantilla de consulta). No se demuestran aquí porque alcanzan el mismo destino con condiciones previas adicionales; la vía directa es suficiente para probar la omisión de EXECUTE_CODE.

Contenido del repositorio

  • setup/ — Entorno Docker Compose. Levanta una instancia de NiFi 2.8.0 (imagen oficial apache/nifi:2.8.0) con los NAR del graph bundle autocargados, un servidor LDAP que proporciona dos usuarios de prueba (admin y flow_designer), y un servidor Gremlin para que TinkerpopClientService apunte a él. setup.sh inicializa las políticas para que flow_designer tenga derechos de edición de flujos pero no EXECUTE_CODE, y luego verifica la configuración.

  • pocs/flow_designer_groovy_rce.py — Exploit autocontenido. Se autentica como flow_designer, demuestra que ExecuteScript está denegado (la barrera de EXECUTE_CODE funciona), luego crea un + con un payload Groovy que lanza un reverse shell de bash a un listener que el POC inicia localmente. Una vez establecida la conexión, el POC mejora el shell a un bash completamente interactivo con soporte PTY mediante util-linux , con puente stdio en modo raw y redimensionamiento de ventana en vivo — el operador obtiene una terminal real dentro del contenedor de NiFi.

Instrucciones

Requisitos previos: Docker, Python 3.10+, y uv.

root@kitploit:~
cd setup
./setup.sh

La primera ejecución descarga los NAR del graph bundle desde Maven Central y extrae las imágenes de Docker (~2-3 min). Cuando el setup se completa, imprime la invocación del POC lista para pegar.

Ejecutar el POC:

root@kitploit:~
uv run --no-project --with requests \
    pocs/flow_designer_groovy_rce.py \
    --base-url https://localhost:8443 \
    --username flow_designer \
    --password 'flowDesigner123!' \
    --gremlin-host gremlin-server

El POC lleva al operador a una sesión bash interactiva dentro del contenedor de NiFi ejecutándose como la cuenta de servicio nifi. Escriba exit o presione Ctrl-D para desconectarse — el POC luego limpiará el procesador y el servicio de control que creó.

En Docker para Linux (donde host.docker.internal no se resuelve por defecto), pase --shell-host <host-bridge-ip> o agregue extra_hosts: ["host.docker.internal:host-gateway"] al servicio nifi en setup/docker-compose.yml.

Desmontaje:

root@kitploit:~
cd setup
./teardown.sh
Descargar herramienta
TinkerpopClientService
ExecuteGraphQuery
script