De cómo el malware modifica ejecutables sin alterar su firma

viernes, 24 de enero de 2014

Microsoft acaba de arreglar (a medias) un método que permitía alterar un fichero firmado con Authenticode. Aunque el método fue descubierto en 2009, no ha sido  hasta ahora, cuando se ha observado que ciertos programas han comenzado a usar la fórmula, que ha introducido una corrección (que todavía no se activa por defecto). Se trataba de aprovechar un fallo de diseño de Authenticode. Veamos cómo funcionaba.

Varios métodos para cambiar la integridad sin alterar la firma

Existían varios métodos para alterar una imagen de un binario firmado sin que el sistema se quejase de que la firma era incorrecta (de que se había alterado su integridad). El parche MS12-024, de abril de 2012, corrige algunos. Tiene el CVE-2012-015 y lo descubrieron Robert Zacek e Igor Glucksmann, de Avast. No se había observado en malware aún.  Pero sí que existía un problema pendiente de arreglar. El truco era muy sencillo.

Ya hemos hablado en varias ocasiones de Authenticode en este blog. Fundamentalmente, cuando se firma un binario, se calcula el hash de todo el flujo de datos del menos algunos pequeños huecos que "se salta": La cabecera del fichero llamada "Security directory RVA" (también llamada Certificate Table RVA) y el checksum del fichero completo.

En 2009 se comprobó que era posible además añadir código al final de un ejecutable, sin alterar la firma. Aunque publicaron herramientas para conseguirlo, se demuestra manualmente de manera muy sencilla, con cualquier editor hexadecimal. El truco consiste en que se puede añadir código más allá del final del fichero y modificar las cabeceras correspondientes de tamaño. La última parte del fichero (entre 1 y 4 kbs), cuando se firma, corresponde a la estructura PKCS que contiene la firma en sí. En esta estructura se encuentra el certificado y toda la información criptográfica de la firma. Para engañar a Authenticode, se le puede simplemente indicar al fichero en su cabecera que la estructura PKCS es un poco más larga (cambiar el valor del tamaño) y que abarque la parte añadida. Así de simple.

Cómo conseguirlo

Es necesario modificar el valor "Security Directory Size". En el ejemplo usado, el tamaño del directorio (de la estructura PKCS) es 0x1918 bytes. Si se van a añadir, por ejemplo, 16 bytes (0x10), se modifica el valor de 0x1918 a 0x1928 en el valor de la cabecera correspondiente. 
Un fichero cualquiera firmado, y las cabeceras correspondientes. Se ha modificado el tamaño de 1918 a 1928
 Este valor se repite más abajo en el fichero, en la estructura PKCS1_MODULE_SIGN.dwLength, que está dentro del PKCS. Encontrarlo es de nuevo muy sencillo. Se halla justo donde indique el offset de la cabecera Security Directory RVA. Se modifica ahí de nuevo el valor del tamaño. Pasa de de 0x1918 a 0x1928.

En ese mismo archivo (offset 0046c858 indicado por Security Directory RVA) se modifica el valor del tamaño PKCS
Luego, al final del fichero, se añaden los bytes necesarios con el texto o datos que se desee. En este caso, hemos añadido 16 bytes, comenzando por la palabra "ElevenPaths".

Datos añadidos justo al final del fichero, con un editor hexadecimal
Para comprobar que el tamaño del PKCS calculado es correcto, podemos simplemente restar el tamaño final del fichero (hasta dónde llegan nuestros datos añadidos) y el del offset donde comienza el PKCS (el valor de la cabecera). En el ejemplo, 0x46e180 - 0x46c858 = 0x1928. Este resultado debe corresponder con el dato que hemos modificado.

Al comprobar la firma, dirá que todo está correcto, y que no se ha perdido la integridad del binario, aunque lo hemos modificado hasta en tres puntos. Por completar, se podría modificar y actualizar la cabecera del checksum, pero no es imprescindible (Authenticode no lo tiene en cuenta).

Firma correcta del fichero de prueba, aun habiendo modificado hasta tres puntos diferentes.
¿De qué sirve añadir código ahí y por qué lo han corregido?
Esquema de cómo el malware se aprovechaba
de instaladores que acudían al Payload para descargar

Microsoft ha reaccionado a este problema cuando se ha encontrado malware (o al menos, pruebas de concepto) aprovechando el problema. De hecho, parece que fue Didier Stevens quien dio la voz de alarma este año. Encontró instaladores firmados válidos, cuyo código acudía a esa parte extra del fichero no firmado. Ahí habían añadido una URL de la que descargaba otro ejecutable. Este ejecutable descargado ya no estaba firmado.

Así, firmaban una sola vez un ejecutable, pero conseguían que sirviera para muchas instalaciones diferentes. Solo había que cambiar la parte añadida del binario, una URL en el payload, sin volver a firmar (la integridad se mantenía) y apuntar a otra URL donde se descargaba otro código. Firma una vez, instala cualquier cosa. Cómodo... pero peligroso.

El malware, sin embargo, ha visto en este método del instalador una oportunidad de pasar como instalador válido de un tercero, firmado, y descargar malware a su gusto. Ingenioso.

¿Cómo lo han corregido?

El parche MS13-098 comprueba que, tras el bloque PKCS propiamente, no se encuentran datos que no sean diferentes de cero. Si es así, la firma no será válida. Deja abierta la puerta a otros ataques, como reconoce la propia Microsoft, pero dependen ya de una muy mala práctica de los desarrolladores (introduciendo datos no firmados en la propia estructura PKCS...)

Pero este parche no estará activo hasta junio de 2014. Si se quiera activar ya, es necesario realizar un cambio en el registro (añadiendo un REG_SZ en la ruta adecuada con el valor indicado).

Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\Software\Microsoft\Cryptography\Wintrust\Config] "EnableCertPaddingCheck"="1"

En los sitemas de 64 bits, modificar además para binarios compilados nativamente en este arquitectura.

[HKEY_LOCAL_MACHINE\Software\Wow6432Node\Microsoft\Cryptography\Wintrust\Config] "EnableCertPaddingCheck"="1"

Y reiniciar. Teniendo en cuenta los problemas criptográficos que tuvo Microsoft con TheFlame a causa de una cadena de errores simples,... debería haber reaccionado antes a este problema y no tardar casi 5 años en solucionarlo.

Sergio de los Santos
ssantos@11paths.com

No hay comentarios:

Publicar un comentario