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
cve-2023-41564-research — Análisis detallado y prueba de concepto para CVE-2023-41564, una vulnerabilidad XSS almacenada en Cockpit CMS <=2.6.3, con causa raíz a nivel de código y guía de mitigación. | Kitploit
Herramientas/GitHubGitHub/sota70/cve-2023-41564-research
Análisis de VulnerabilidadesExplotaciónExplotación de Aplicaciones WebSeguridad WebPruebas de PenetraciónAprendizaje y Educación
GitHubsota70/cve-2023-41564-research

cve-2023-41564-research

Análisis detallado y prueba de concepto para CVE-2023-41564, una vulnerabilidad XSS almacenada en Cockpit CMS <=2.6.3, con causa raíz a nivel de código y guía de mitigación.

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
hace 1 añoAún no revisado

Resumen de la vulnerabilidad CVE-2023-41564

CVE-2023-415641 es una vulnerabilidad de XSS almacenado presente en el CMS Cockpit (<= v2.6.3).
Al cargar un archivo HTML con extensión .shtml durante la subida de archivos, el JavaScript se ejecuta en el momento en que se abre el archivo subido.

1: https://nvd.nist.gov/vuln/detail/CVE-2023-41564

Flujo del ataque

Primero, explicaremos el método de ataque basado en el PoC2 publicado por quien parece ser el reportador de la vulnerabilidad.
Primero, inicia sesión en el sitio con una cuenta que tenga permisos para subir archivos.
cms login cms assets Luego, sube un archivo shtml como el siguiente:

root@kitploit:~

Copia la URL del archivo (Asset) subido. cms link Al acceder al enlace copiado, se ejecuta el script descrito en el HTML anterior. cms xss
2: https://github.com/LongHair00/Mitre_opensource_report/blob/main/CockpitCMS-StoredXSS.md

Detalle de la causa

A partir de aquí, explico los resultados de mi investigación más profunda.
El proceso de carga de Assets comienza con una solicitud POST a la ruta /assets/upload.
El manejo de la solicitud de carga está definido en la línea 513 de modules/Assets/bootstrap.php.
A continuación se muestra el código.

root@kitploit:~
// assets api
$this->module('assets')->extend([

    // 省略
    'upload' => function(string|array $param = 'files', array $meta = [], bool $isUpload = true) {

        $files = [];

        if (is_string($param) && isset($this->app->request->files[$param])) {
            $files = $this->app->request->files[$param];
        } elseif (is_array($param) && isset($param['name'], $param['error'], $param['tmp_name'])) {
            $files = $param;
        }

        $finfo      = finfo_open(FILEINFO_MIME_TYPE);
        $uploaded  = [];
        $failed    = [];
        $_files     = [];
        $assets    = [];

        $allowed   = $this->app->retrieve('assets/allowed_uploads', '*');
        $allowed   = $allowed == '*' ? true : str_replace([' ', ','], ['', '|'], preg_quote(is_array($allowed) ? implode(',', $allowed) : $allowed));
        $max_size  = $this->app->retrieve('assets/max_upload_size', 0);

        $forbiddenExtension = ['bat', 'exe', 'sh', 'php', 'phar', 'phtml', 'phps', 'htm', 'html', 'xhtml', 'htaccess'];
        $forbiddenMime = [
            'application/x-httpd-php', 'application/x-php', 'text/x-php',
            'text/html', 'application/xhtml+xml'
        ];

        if (isset($files['name']) && is_array($files['name'])) {

            $cnt = count($files['name']);

            for ($i = 0; $i < $cnt; $i++) {

                $_file  = $this->app->path('#tmp:').'/'.$files['name'][$i];
                $_mime = $finfo->file($files['tmp_name'][$i]);
                $_isAllowed = $allowed === true ? true : preg_match("/\.({$allowed})$/i", $_file);
                $_sizeAllowed = $max_size ? filesize($files['tmp_name'][$i]) < $max_size : true;

                $extension = strtolower(pathinfo(parse_url($_file, PHP_URL_PATH), PATHINFO_EXTENSION));

                if (!$extension) {
                    $_isAllowed = false;
                }

                // prevent uploading php / html files
                if ($_isAllowed && (
                    in_array($extension, $forbiddenExtension) ||
                    in_array(strtolower($_mime), $forbiddenMime)
                )) {
                    $_isAllowed = false;
                }

                if (!$files['error'][$i] && $_isAllowed && $_sizeAllowed && ($isUpload ? move_uploaded_file($files['tmp_name'][$i], $_file) : rename($files['tmp_name'][$i], $_file))) {

                    $_files[]   = $_file;
                    $uploaded[] = $files['name'][$i];

                    if (\preg_match('/\.(svg|xml)$/i', $_file)) {
                        file_put_contents($_file, \SVGSanitizer::clean(\file_get_contents($_file)));
                    }

                } else {
                    $failed[] = $files['name'][$i];
                }
            }
        }

        if (count($_files)) {

            $assets = $this->add($_files, $meta, isset($meta['_id']));

            foreach ($_files as $file) {
                unlink($file);
            }
        }

        return ['uploaded' => $uploaded, 'failed' => $failed, 'assets' => $assets];
    },
    // 省略
]);

La función upload se almacena en la variable miembro registry['modules']['assets'] de la clase App, que contiene las funciones del módulo Assets.
Por lo tanto, al llamar a la función upload, se invoca como $this->module('assets')->upload('file', $file);
La función upload registrada aquí es llamada por la clase Assets4.

root@kitploit:~
public function upload() {
    this->helper('session')->close();
    this->hasValidCsrfToken(true);
    if (!this->isAllowed('assets/upload')) {
        return $this->stop(['error' => 'Upload not allowed'], 401);
    }
    $meta = ['folder' => $this->param('folder', '')];
    return $this->module('assets')->upload('files', $meta);
}

Puede ver que se está llamando a la función upload registrada en registry['modules']['assets'].
Ahora, veamos la función upload definida en bootstrap.php.
Aquí se definen las extensiones prohibidas en la variable $forbiddenExtension.
Sin embargo, falta la extensión shtml.
Por lo tanto, esto es un defecto que permite la subida de archivos shtml.

3: https://github.com/Cockpit-HQ/Cockpit/blob/2.6.3/modules/Assets/bootstrap.php#L51
4: https://github.com/Cockpit-HQ/Cockpit/blob/2.6.3/modules/Assets/Controller/Assets.php#L140

Mitigación

Dado que la causa es que shtml no está prohibido, se puede mitigar agregando shtml a forbiddenExtension.

root@kitploit:~
$forbiddenExtension = ['bat', 'exe', 'sh', 'php', 'phar', 'phtml', 'phps', 'htm', 'html', 'xhtml', 'htaccess', 'shtml'];
Descargar herramienta