28 mayo 2012

En el post Seguridad en componentes cliente de aplicaciones web basadas en DNIe: Parte 1/3 hicimos un repaso a los tipos más importantes de componentes para el navegador, ActiveX y Applets Java, así como diferentes herramientas que podríamos utilizar para su análisis exhaustivo. En Seguridad en componentes cliente de aplicaciones web basadas en DNIe: Parte 2/3 echamos un vistazo a vulnerabilidades típicas que nos podríamos encontrar en este tipo de software. En esta última parte, aplicaremos todo lo explicado a componentes de aplicaciones web basadas en DNIe, utilizados para la autenticación, firma y cifrado.

Basándonos en diferentes fuentes y recopilatorios (como las de Inteco y ZonaTIC), se ha creado un listado con componentes cliente (ActiveX, Java Applet o ambos) utilizados en aplicaciones web que utilizan el DNIe u otro tipo de certificado para la realización de diferentes gestiones telemáticas. Dicho listado se puede encontrar dentro de la sección 3 (DNIe-3) del proyecto DNIe dentro de la página del capítulo español de OWASP.

Listado de componentes encontrados en aplicaciones Web que utilizan DNI-e
De todos ellos, se han seleccionado tres para su análisis en profundidad y búsqueda de vulnerabilidades típicas presentadas en el anterior post:
  • Componente de la AEAT CActiveX.cab - ActiveX
  • @firma (versión completa y Mini) del Centro de Transferencia Tecnológica - Applet Java
  • WebSigner de TB-Solutions - ActiveX y Applet Java
Componente de la AEAT CActiveX
Mucho se ha hablado ya de este componente, obviamente por su extendida utilidad y necesidad para realizar trámites con la Agencia Tributaria. Alex ya escribió en abril del 2009 "AEAT, Renta 2008, tarde y mal", en la que describe las problemáticas encontradas para la campaña de la Renta 2008 debido sobretodo a que el certificado del componente era inválido por su caducidad demasiado temprana.

Caducidad del certificado del componente para la campaña Renta 2008

Para la instalación de este componente, salvo que cambiásemos la fecha, tendríamos que configurar el navegador para eliminar restricciones de seguridad, que podrían ser aprovechadas por componentes no legítimos y dañinos para comprometer nuestro PC.

Para lo que son los entresijos del componente en sí, Ruben Santamarta en 48Bits con "Weaponized XSS – El caso de la Agencia Tributaria" también dedicó un post a lo que podríamos ser capaces de hacer, mediante un Cross-Site Scripting y una vulnerabilidad encontrada en una de las funciones del ActiveX, como por ejemplo, sobre-escribir ficheros del directorio  donde se instala el componente en nuestro disco duro local.

Post en 48Bits de Ruben Santamarta "Weaponized XSS – El caso de la Agencia Tributaria"

Procedemos a descargar el componente de la AEAT que encontraremos en la página https://aeat.es/instalar.html, para analizar y revisar las funciones y parámetros que contiene actualmente, así como sus comportamientos (el certificado de este componente caducó el 24 de Mayo de 2011...)




Descargamos el .cab (ActiveX clsid={B785FA3C-1DE9-4D20-8396-613C486FE95E}) que podemos encontrar en el código fuente HTML de la página instalar.html y lo abrimos con la herramienta COMRaider, de la que hablamos en la primera parte de esta serie de artículos.

Funciones del componente AEAT.dll (CActiveX)

Realizamos una simple prueba de concepto en HTML, que, instancie el componente ActiveX mediante su clsid y utilice cualquier de sus funciones disponibles. Se comprueba como, al utilizar cualquier función, se avisa al usuario de posibles errores por su uso incorrecto de parámetros, o si pretendemos realizar gestiones de ficheros fuera del directorio C:\aeat:

Aviso de intento de acceso a ficheros fuera del directorio aeat del disco raíz

Por lo que, con este componente no podremos realizar lectura, escritura o eliminación de ficheros arbitrarios del sistema, sólo del directorio reservado para la utilización del componente.


Cliente de firma electrónica de @firma
Tal y como se indica en el portal de la administración electrónica, el cliente @firma permite la firma electrónica de documentos por parte de los ciudadanos empleando los certificados digitales de usuario o disponibles a través de un módulo PKCS#11, todo desde el navegador. Este componente únicamente se distribuye en formato Applet Java.

Existen dos variantes para poder hacer uso de este cliente:
  • El Cliente de Firma es una herramienta de Firma Electrónica que soporta los siguientes formatos de firma: PAdES-BES / EPES, XAdES-BES / EPES, CAdES-BES / EPES, ODF, OOXML, CMS y XMLDsig.
  • El MiniApplet de @firma es mucho más ligero que el actual Cliente de Firma dado que soporta un conjunto limitado de métodos NUEVOS para operaciones tipo de firma electrónica y que permite generar firmas en los siguientes formatos: CAdES, XAdES PAdES y ODF.
Analizaremos los applets de java de ambas variantes.

@firma versión Mini
Actualmente se encuentra publicada la versión 1.0.1 del MiniApplet de @firma, que se puede encontrar en este enlace (MCFv1.0.1_EjemploDEMO_despliegue_MiniApplet.zip).

Preparamos una prueba de concepto aprovechando el ejemplo de despliegue incluido en el fichero, que ejecute el applet MiniApplet:


Cuando el applet se cargue, se dispondrá de la variable "clienteFirma" para poder llamar cualquier funcionalidad marcada como pública. Para obtener dicho dato podemos, o bien analizar el código fuente y obtener el identificador que se asigna al componente cargado o bien mediante la Consola web (Control+Mayus+K), dentro de Herramientas -> Desarrollador web, tendremos acceso completo a todos los elementos cargados en la página actualmente, y así poder interactuar con ellos sin necesidad de crear funciones javascript y botones para llamar a funciones del Applet:


Para acceder a los applets cargados dentro de la capa "document", ejecutamos documents.applets en la consola, se devolverá el array de applets cargados, y obtendremos más información accediendo a cada elemento del array, por ejemplo, el primero con document.applets[0]:


Revisamos por tanto el contenido de la clase correspondiente con el MiniApplet que se cargará en el navegador, que se encuentra en miniapplet-full\es\gob\afirma\miniapplet\MiniAfirmaApplet.class:


Conjunto de funciones y procedimientos disponibles en el applet, con parámetros permitidos y código fuente decompilado mediante JD-GUI.


Probamos, mediante la consola Web, a obtener la versión del entorno Java que estamos ejecutando, aprovechando la función getEcoJava(), y lo mostramos mediante un pop-up (alert):


Por tanto, si la página en la que se encuentra cargado el applet, resultase vulnerable a Cross-Site Scripting, podríamos realizar otro tipo de peticiones diferentes a los típicos document.cookie o mostrar mensajes "prueba xss", dependiendo de las funciones que el applet nos deje disponibles.

Probemos las funciones que gestionan ficheros, como son por ejemplo loadFilePath, saveDataToFile, y getFileNameContentText, cuyos nombres lo dicen todo:
  • loadFilePath (3 parámetros de entrada, devuelve cadena de texto) de MiniApplet @firma
Al ejecutar la función mediante loadFilePath("param1","param2","param3"), se abre un cuadro de diálogo (con título param1) para la selección de un fichero con extensión "param3", por lo que esta funcionalidad avisa al usuario de la acción. No nos permitiría la obtención de información sin que un posible usuario víctima se enterase de que está recibiendo un ataque de Cross-Site Scripting.

Resultado de ejecución de loadFilePath de MiniApplet

La función devuelve la ruta completa de un fichero seleccionado mediante el cuadro de diálogo.
  • getFileNameContentText (3 parámetros de entrada, devuelve cadena de texto) de MiniApplet @firma
Ídem que en el caso anterior, utilizando los mismos parámetros de prueba para comprobar el funcionamiento, se ejecuta un cuadro de diálogo para que el usuario introduzca el fichero del que obtener el contenido. Tampoco nos vale y no es posible abusar de esta funcionalidad sin que un usuario se percate.
  • saveDataToFile (5 parámetros de entrada, devuelve cadena de texto) de MiniApplet @firma
Mismo comportamiento, la ejecución completa de la funcionalidad de guardar datos en un fichero, requiere interacción con el usuario.

Resultado de ejecución de funcionalidad saveDataToFile de MiniApplet

Para las funciones más importantes de gestión de ficheros, este applet requiere siempre de interacción con el usuario cuyo navegador ejecuta el applet.

@firma versión Completa
La última versión, correspondiente con la 3.3 de este cliente, fue publicada el 20 de Abril de 2012, más de un mes después de la charla en Rooted CON 2012. El análisis presentado se realizó de versiones anteriores.

Para este componente, se realizarán las mismas pruebas que se realizaron sobre la versión Mini, y como podréis observar a continuación, los resultados son completamente opuestos. Para el ejemplo, se realizará el análisis sobre una web que contiene instalada la versión completa del componente Cliente @firma. A la web a llamaremos "SedeChachi", y podremos acceder mediante la URL https://sedechachi.gob.es. Ejecutamos documents.applets en la consola para comprobar la carga correcta del applet de @firma y utilizaremos el identificador clienteFirma por comodidad para evitar el uso de documents.applets[0] cada vez que queramos llamar a cualquier de sus funciones:

Acceso al applet mediante el identificador clienteFirma

Revisamos el contenido de la clase correspondiente con el applet cargado en el navegador, que se encuentra en es/gob/afirma/cliente/SignApplet.class:

Funciones disponibles de la clase SignApplet.class del applet Cliente @firma
Probemos de nuevo aquellas funciones cuyo nombre indican que pudieran ser necesarias para gestión de ficheros, como por ejemplo loadFilePath, getTextFileContent y savePlainDataToFile:
  • loadFilePath (3 parámetros de entrada, devuelve cadena de texto) del Cliente @firma
Carga de loadFilePath del cliente @firma

El comportamiento es el mismo que el de la misma función en la versión Mini del applet.

  • getTextFileContent (1 parámetro de entrada, devuelve cadena de texto) del Cliente @firma

Probemos a ejecutar getTextFileContent del fichero C:\boot.ini típico de sistemas Microsoft Windows y mostremos la cadena de texto que devuelve la función mediante un popup (alert):

Obtenemos el contenido del fichero boot.ini del sistema
¡Bingo! Podríamos obtener cualquier fichero del sistema de un usuario víctima, si le proporcionásemos un enlace especialmente modificado como payload de un ataque Cross-Site Scripting, lejos del típico document.cookie o "prueba XSS" como se comentó anteriormente. Y todo ello sin que el usuario se percate de la petición. En linux obviamente, también funciona, y ¿qué fichero vamos a probar para su lectura, pudiendo obtener su contenido sin que el usuario se entere?

Leyendo el fichero /etc/passwd mediante la función de lectura del applet

  • savePlainDataToFile (1 parámetro de entrada, devuelve booleano) de MiniApplet @firma
Teniendo en cuenta que es un parámetro, y en una función de guardar debería haber una para los datos y otra para el fichero destino, comprobamos como hay otra función llamada setPlainData que recibe un parámetro, que será la que guarde en el objeto el texto, y después utilizaremos savePlainDataToFile para guardar en un fichero dichos datos. Ejecutaremos setPlainData("contenido del fichero") y savePlainDataToFile("C:\\pruebafichero.txt"):

Ejecución de la función de guardar fichero con contenido establecido previamente
Al igual que en el caso anterior, hemos conseguido escribir un fichero sin que el usuario tenga constancia de ello, en la raíz del disco duro local. También sería posible añadir nuevo contenido a un fichero (sobreescritura) sin aviso previo. En este caso, se ha almacenado información en texto, pero también es posible mediante otro par de funciones, el almacenar contenido binario en ficheros.

Tras hacerse públicas estas vulnerabilidades en el congreso, se lanzó la versión 3.3 del applet, en la cual se incluyeron avisos al usuario por parte del applet de la utilización de determinadas funciones, como son la carga o guardado de ficheros, evitando poder abusar de estas funciones sin contar con autorización previa:

Aviso de la nueva versión del applet para la utilización de la función de carga
 
Aviso de la nueva versión del applet para la utilización de la función de guardar fichero

WebSigner2 (suite ASF-Firma) de TB-Solutions

La suite ASF-Firma de la compañía TB-Solutions se utiliza en la amplia mayoría de empresas para la realización tareas de firma y certificación. Dicha suite fue certificada CC EAL3+ en el 2007, y entre el inventario de componentes de la solución, se encuentra WebSigner2, que corresponde con un ActiveX para realizar tareas de firma y autenticación en el lado cliente desde navegadores Internet Explorer. También cuenta con una versión applet Java del mismo.

El componente analizado es el ActiveX WebSigner2.cab (versión 6.2.0.2). Podréis saber dónde se utiliza buscando dicho archivo en Google, dónde saldrán manuales de como configurar el navegador para su uso correcto y sin problemas. Para el análisis se creará una prueba de concepto en HTML con Javascript que ejecute el ActiveX, y mediante una serie de botones se intentará la ejecución de sus funciones con parámetros de ejemplo. El contenido del fichero .cab es el siguiente:

Contenido del ActiveX WebSigner2

Abrimos la librería WebSigner2.dll para la obtención de las funciones disponibles con COMRaider:

Obtención de funciones disponibles en el componente WebSigner2

Al igual que en anteriores ocasiones, los nombres de las funciones hablan por si solas. Probemos la función loadFileWithPath, que acepta un parámetro de tipo String, realizando la petición loadFileWithPath("C:\\boot.ini"). El contenido del fichero se queda en la variable ContentString del objeto, la cual mostraremos mediante un popup (alert):

Código JavaScript para llamar a la función loadFileWithPath del componente WebSigner2

Obtención del fichero boot.ini mediante la función loadFileWithPath

También se incluyen funciones de guardar ficheros, que además de contenido en texto plano, también es posible crear binarios (al aceptar contenido en base64) y dejarlos en cualquier localización del sistema.

Se permite sobreescribir por ejemplo, ficheros como el hosts. Recordemos que el ActiveX debe ejecutarse con usuario con privilegios máximos, como bien dice la documentación de cualquier sede que haga uso del componente...

Código para sobreescribir el fichero hosts del sistema, añadiendo una nueva ruta
Fichero hosts del sistema sobre escrito con una nueva ruta para la cual al introducir phishing se redirigirá la conexión a 000.000.000.000
Para el siguiente ejemplo, y tras obtener el base64 del fichero binario del cmd.exe, guardaremos otro cmd.exe con otro nombre (secret1.exe), en el raíz del disco.

En la variable cmd se encuentra el base64 del binario cmd.exe de Windows
Hemos "plantado" un binario como el cmd.exe dentro del raíz del disco
Todas las acciones realizadas anteriormente se ejecutan sin requerir interacción por parte del usuario ni avisos previos.

Ídem que para el caso de @firma, tras contactar con TB-Solutions, se encuentra disponible la versión WebSignerPlus 6.2.0.3 en la que, para cada una de las funcionalidades de gestión de ficheros, se avisa al usuario del posible acceso a recursos del disco duro:
Aviso de WebSignerPlus al intentar consultar el fichero boot.ini
Aviso de WebSignerPlus al intentar obtener el fichero hosts del sistema
Se asignado el CVE CVE-2012-1267 para las vulnerabilidades encontradas en WebSigner2, por el uso inseguro de los métodos de lectura y escritura de ficheros sin aviso previo al usuario, afectando a las versiones 6.2.0.2 y anteriores del componente.

------------------------------

En los próximos días, se incluirá la información de esta serie de posts en la página OWASP del proyecto DNI-e que podréis encontrar en la URL https://www.owasp.org/index.php/Spain/Projects/DNIe. Esperamos poder concienciar tanto a fabricantes como usuarios de la importancia de proteger este tipo de componentes y desarrollos asociados.

[Referencias]
- Seguridad en componentes cliente de aplicaciones web basadas en DNIe [Parte 1][Parte 2][Parte 3]

2 comments :

Madrikeka dijo...

Que genial me van a venir las 3 partes para imprimirlas y leerlas en el bus!!

Javier Tallón dijo...

La verdad es que esta serie de post está siendo de lo más interesante para todos aquellos que hemos trabajado con el DNIe!

Sólo una pequeña corrección respecto a ASF y la certificación: el ámbito de la certificación viene determinado por la declaración de seguridad (documento que es posible encontrar en el enlace que refieres), y en ella excluye explícitamente el componente WebSigner de la certificación y por tanto del análisis de seguridad hecho sobre el producto...

¡Un saludo!