jueves, 16 de julio de 2015

Hashes: md5sum, sha256sum, sha512sum, etc, con semilla, desde la consola


Los hashes checksum se han vuelto muy populares para validar la integridad de los archivos que descargamos por Internet. Sobre todo por ejemplo para las diferentes distribuciones de Linux.

Sin embargo la seguridad de esos hashes ha sido cuestionada, es cuestionable o al menos deja ciertas dudas. Dado que simplemente es un hash si existe algún archivo que lo tenga, existirán infinitos archivos que tendrían ese mismo hash. De hecho es posible, al menos en teoria, descargar una iso de alguna distribución linux con un determinado hash, modificarla a nuestro gusto, insertarle por ejemplo algún rootkit y luego agregarle unos bytes adicionales que nos de el mismo hash que el archivo original. Dado que se asume que los valores de la función hash están uniformemente distribuidos (eso seria lo más lógico) la cadena de bytes que habría que agregarle no debería ser mayor a los numeros de bytes que componen el hash.

De hecho seria teoricamente posible que descargar una iso de Linux y modificar su código sin aumentar su tamaño y cambiar ciertos bytes basura (que no se usen o sean invisibles para el usuario) de manera que el código modificado nos de el mismo hash.

Uno podría creer todavía que existe una brecha práctica para hacer estos crack de hash al menos para los algoritmos más populares: md5, sha1, etc. En la actualidad es difícil permitirse ser tan ignorante. Desde el año 2004 se han descubierto brechas en esos algoritmos [1], que generarían hashes idénticos con un poder de computo muy inferior para el que se asumió que fueron generados los hashes [2].

Otro problema con los hashes md5 es que en el caso de tener un rootkit instalado en el kernel este puede alterar el código de un archivo dado y generar como salida el hash md5 original del código original cuando ejecutemos la utilidad destinada por el sistema operativo para ello.

Se me ha ocurrido sin embargo una forma de hacer mucho más dificil la vulneración por medio de ambos métodos. Se basa en la idea de tener más de un hash para un archivo sin utilizar más de un algoritmo.

Es muy sencillo. Se escribe en un archivo una cadena arbitraria que servira a manera de clave para nuestro hash. Luego se concatena dicha cadena con el archivo al cual se le quiere generar el hash  y finalmente se hace calcula del hash con el algoritmo o la utilida destinada para ello.

Lo bueno de la consola de linux es que la concatenación de los archivos puede hacerse al vuelo (on the fly) y no se requiere para nada modificar el archivo original. Esto con la función cat. Si usaremos MD5, los comandos en la consola podrían ser como se vera a continuación:

$ cat archivo_a_generar_hash archivo_clave | md5sum

De esta forma para distintas claves se tendrá un distinto hash. ¿Por qué es tan ingenioso esto?. Porque hasta ahora la metodología es publicar un hash por archivo, en cambio de esta forma podría publicarse más de un hash para un archivo con una clave distinta por hash. De hecho el servidor desde el que descarguemos el archivo podría generar una clave aleatoria cada cierto tiempo con un distinto hash, de forma tal que no se sobrecargue generando los hash. De esta forma se podría verificar la integridad de un archivo para más de un hash. Lo que nos daria una seguridad  casi infinitamente mucho más alta de la que tenemos al descargar un archivo de la forma en como lo hacemos actualmente. Un rootkit, por ejemplo tendría que que estar conectado online exactamente en la sesion tcp que conectemos al momento para saber el hash que consultamos. Simplemente no seria viable, tendría que mantener una copia exacta del archivo para mantener la consistencia con los hash generados. Si el archivo es muy extenso podría notarse que decrementa mucho más de lo que debería el tamaño del disco duro, así que el rootkit también tendría que disimular esto. Esto sin duda haría más difícil su trabajo.  

Esto desde luego no es algo nuevo. Es lo que se usa en el archivo de claves de /etc/shadow para que claves iguales tengan hashes distintos de forma que viendo el shadow no se sepa que son iguales, para ello se le agrega varios bytes que se conocen como salt o semilla. Es sorprendente que los utilidades de hash que vienen con Linux o que se pueden descargar no hayan tomado en cuenta en su línea de comando este sencilllo y elemental caso de uso.

De momento este método podría servirnos para generar nuestros propias hashs ... por si acaso.


Referencias:

[1] http://merlot.usc.edu/csac-f06/papers/Wang05a.pdf

[2] MD5: vulnerabilidades y evoluciones (y II)