/ 4 min de lectura
CVE-2019-14670 - RCE en LimeSurvey vía deserialización PHAR en TCPDF

Durante nuestra investigación de seguridad sobre LimeSurvey, descubrimos una vulnerabilidad crítica que permite ejecución remota de código explotando una falla de deserialización en la librería TCPDF.
El vector de ataque que presentamos acá aprovecha la técnica de “Deserialización vía el stream wrapper phar://”, investigada originalmente por Sam Thomas y presentada en Black Hat USA 2018. El método demuestra cómo disparar inyección de objetos PHP sin controlar directamente una llamada a unserialize().
Contexto técnico
Entendiendo TCPDF
TCPDF es una librería PHP open source para generar documentos PDF a partir de código HTML. Al generar un documento PDF desde contenido HTML, es posible controlar el input de funciones vulnerables a través de tags como <img>.

Deserialización vía el stream wrapper phar://
Esta técnica de explotación se llama deserialización vía el stream wrapper phar://. Un archivo PHAR puede contener metadata, que a su vez puede incluir objetos PHP serializados.
Funciones de PHP como:
file_exists()fopen()filesize()copy()include()
Soportan el uso del wrapper phar://. Cuando estas funciones hacen una llamada a un archivo PHAR a través de este wrapper, la metadata del archivo se deserializa automáticamente, permitiendo la inyección de objetos maliciosos sin necesidad de controlar una llamada a unserialize().
Análisis de la vulnerabilidad
Requisitos para la explotación
- Controlar el input de alguna de las funciones vulnerables mencionadas
- Poder subir un archivo PHAR al servidor
- Acceso de administrador en LimeSurvey para la funcionalidad de exportación de PDF
LimeSurvey y TCPDF
LimeSurvey < 3.17 usa una versión desactualizada (6.2.13) de la librería TCPDF, vulnerable a ataques de deserialización a través del wrapper phar://.
Explotación paso a paso
La vulnerabilidad se puede explotar a través de la funcionalidad de exportación PDF queXML de LimeSurvey, inyectando un archivo PHAR malicioso vía la configuración de estilo.
Paso 1: Generar y subir el archivo PHAR malicioso
Primero, generamos el archivo PHAR malicioso usando PHPGGC con la cadena de gadgets del framework Yii:
$ ./phpggc Yii/RCE1 system "ls" -p phar -o /tmp/exploit.jpgEste comando va a:
- Usar la cadena de gadgets Yii/RCE1 (ya que LimeSurvey usa el framework Yii)
- Ejecutar el comando
lsen el servidor remoto - Generar un archivo PHAR (
-p phar) - Guardar el archivo malicioso como
/tmp/exploit.jpg(-o)
El archivo exploit.jpg generado es en realidad un archivo PHAR que contiene objetos PHP serializados, que van a ejecutar el comando ls al ser deserializados.
Después navegamos a la sección Email templates y subimos el archivo PHAR malicioso (exploit.jpg).

Paso 2: Navegar a la exportación PDF de queXML
Vamos a Overview > Display/Export > queXML PDF export > Export.
Paso 3: Inyectar el wrapper PHAR
Insertamos el siguiente código HTML en el campo “Style”:
<h1>pwned</h1><img src="phar://./upload/surveys/{SURVEYID}/files/exploit.jpg">Importante: Reemplazar {SURVEYID} con el ID real de la encuesta de tu instalación de LimeSurvey.

Paso 4: Disparar la explotación
Hacemos clic en el botón “queXML PDF export” para disparar la vulnerabilidad.
Cuando TCPDF procesa el contenido HTML, va a intentar cargar la imagen vía el wrapper phar://, deserializando automáticamente la metadata maliciosa y ejecutando el payload embebido (en este caso, el comando ls).

Evaluación de impacto
Consecuencias potenciales
- Compromiso completo del servidor: acceso completo al sistema a través de una web shell
- Exfiltración de datos: acceso a respuestas de encuestas y datos de usuarios
- Escalación de privilegios: potencial movimiento lateral en la red
- Acceso persistente: posibilidad de instalar backdoors para acceso continuo
- Manipulación de encuestas: posibilidad de modificar datos y resultados de encuestas
Pasos de remediación
Acciones inmediatas
- Actualizar LimeSurvey: subir a la versión 3.17 o posterior
- Actualizar TCPDF: mantener la librería TCPDF actualizada a su última versión segura
- Deshabilitar PHAR: agregar
phar.readonly = Onal php.ini si no se necesita la funcionalidad de PHAR - Validación de input: implementar validación estricta para contenido provisto por usuarios
Medidas de seguridad a largo plazo
# Apache .htaccess protection<IfModule mod_rewrite.c> RewriteEngine On
# Block PHAR wrapper in requests RewriteCond %{QUERY_STRING} phar:// [NC,OR] RewriteCond %{REQUEST_URI} phar:// [NC,OR] RewriteCond %{HTTP_REFERER} phar:// [NC] RewriteRule .* - [F,L]
# Block other dangerous wrappers RewriteCond %{QUERY_STRING} (php|file|data):// [NC] RewriteRule .* - [F,L]</IfModule>
# Block PHAR file uploads<FilesMatch "\.(phar|pht)$"> Order allow,deny Deny from all</FilesMatch>Protección en Nginx
location ~ ^.*(phar|php|file|data):// { return 403;}
# Block PHAR file accesslocation ~* \.(phar|pht)$ { deny all;}
# Filter dangerous content in POST dataif ($request_body ~ "phar://") { return 403;}