Una mirada técnica (y curiosa) al sistema Authenticode (II)

Sergio De Los Santos  11 julio, 2013

En esta segunda parte
seguiremos viendo cómo se firma realmente un archivo, y la (poca) documentación existente. También
comprobaremos que si bien se especifica que sólo se puede usar el algoritmo
SHA1 para firmar, no es difícil encontrar ficheros firmados con MD5 e incluso
SHA256

¿Cómo calcular el
hash Aunthenticode?

Se supone que el hash Authenticode no es más que un SHA-1
selectivo sobre algunas partes del binario.
Está documentado (de aquella manera) por Microsoft, sin
embargo no hay muchas herramientas que lo calculen y muestren. Existen varias formas de saber el hash Authenticode de un
binario. Una fórmula sencilla es mirándolo en el propio código, puesto que está
incrustado. Normalmente en el offset 0x85 de la dirección virtual
relativa marcada por Security Directory
(en la cabecera). Por ejemplo el programa PE
Explorer lo toma de ahí para mostrarlo. Por supuesto es modificable… a costa
de la validez de la firma. Tomamos de nuevo el ejemplo del binario de Opera.
Mirando las cabeceras y haciendo una pequeña suma, sacamos su hash SHA1
Autenticode.

El SHA1 Authenticode incrustado en una dirección relativa y cómo calcularlo
Podemos confirmar que es correcto con otros programas, como
PE Explorer.

PE Explorer muestra el hash correctamente. Es más, lo toma directamente del binario de la dirección anteriormente descrita

También se puede calcular con cathash.exe. Esta pequeña herramienta calcula
tanto el hash “normal” como el SHA1 de Authenticode especial (sin
algunas cabeceras). 

Esta herramienta muestra los dos hashes, el “real” y el de Authenticode

Para implementarlo nosotros mismos, deberíamos usar la
función CryptCATAdminCalcHashFromFileHandle de la DLL Wintrust.dll, que
devuelve ese SHA1 especial. Pero existe también CryptCATAdminCalcHashFromFileHandle2, que
permite especificar qué hash usar: SHA1 o SHA2 (256 bits). Esta función solo es
válida en Windows 8 y 2012. Existen por tanto programas ya firmados con SHA2 y lo
veremos en las siguiente entrada. Incluso con MD5. El problema con este último algoritmo es que ya se han hecho experimentos para intercambiar la firma entre binarios con colisiones.

¿Se puede “desfirmar” un binario?

Para estos experimentos con colisiones, es necesario “arrancar”
la firma de un binario. ¿Se puede eliminar la firma electrónica? Sí. Se han desarrollado varias herramientas sencillas que
permiten “desfirmar” un binario. Por ejemplo, delcert.exe. O un script
en Python (solo funciona con la rama 2.7) de Didier Stevens mucho más completo que permite otras acciones sobre los ficheros. Eliminar la firma, extraerla, ponérsela
a otro binario… etc
. El resultado de eliminar una firma no suele ser
exactamente igual al fichero original firmado, por una sencilla razón. Estas
herramientas que eliminan certificados también machacan las cabeceras. Por ejemplo, ponen a cero la cabecera
“Security Directory RVA” (dirección virtual relativa) y elimina el
resto de bytes (unos 4k). Dejan el ejecutable “útil” pero no
coincidirá exactamente byte por byte con el original. Lo que sí seguirá
coincidiendo, lógicamente, es el hash Autenticode. En la siguiente imagen se
observa cómo he arrancado el certificado a Opera, (y lo he convertido en
Opera15unsig.exe) con la herramienta de Didier.

Se elimina la firma con disitool y luego se calcula el hash Authenticode del original y del sin firmar. Coinciden.

Al pasarle luego la herramienta cathash tanto al original
como al nuevo, el hash oficial cambia, pero el hash SHA1 usado para Authenticode,
no.

En la siguiente entrega, veremos cuántos ficheros firmados con MD5, SHA1 y SHA256 hay en un Windows XP, 7 y 8, gracias a un pequeño programa que hemos desarrollado.

* Una mirada técnica (y curiosa) al sistema Authenticode (I)
* Una mirada técnica (y curiosa) al sistema Authenticode (y III)

Sergio de los Santos
ssantos@11paths.com
@ssantosv

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *