Hoy os voy a contar la historia por la que la curiosidad, en lugar de matar al gato, me acabó llevando a terminar haciendo algo de ingeniería inversa al software de control de un almacén. La aventura comenzó cuando me topé con un sistema similar al que puede verse en la imagen siguiente:
|
Figura 1: La máquina almacén automatizado |
Como se puede apreciar, se trata de un almacén automatizado compuesto por una serie de bandejas para guardar elementos varios, junto con un sistema de traslación que nos acerca la plataforma de trabajo a la zona deseada del almacén. La idea es que por medio de una buena catalogación de los elementos, el sistema los localiza de forma automática.
El manejo del sistema de almacenaje automatizado se hace completamente desde un terminal táctil que además está conectado a un software de gestión de almacén que permite controlar las entradas y salidas de elementos. Algo fundamental en almacenes de grandes empresas que tienen que controlar dónde está lo que guardan. El terminal táctil en cuestión es un equipo
PC con una versión de
Microsoft Windows CE como sistema operativo.
Para cambiar algunos de los parámetros de la configuración del sistema, el software de control tiene un sistema de seguridad que no deja entrar en el modo "
Support" y remite directamente al servicio técnico del fabricante para solicitar un código temporal de acceso. Cuando se llama por teléfono al servicio técnico es necesario que indicar el código que aparece en pantalla, además de la fecha y la hora que aparecen en pantalla.
|
Figura 2: El código temporal para conseguir el método de acceso al modo Support |
Una vez que se llama al servicio técnico con los datos adecuados, se obtiene un código de
8 caracteres, que hay que introducir en la siguiente pantalla para que se pueda proceder a realizar la operación sobre el sistema de almacenaje.
|
Figura 3: Lugar de introducción del código que libera el modo "Support" |
El objetivo de esta contraseña está pensado más para tener controlado cuando un cliente accede a parámetros que pueden causar errores en el funcionamiento de la máquina y para evitar que alguien toque la configuración "
por error" o "
sin querer" que por otra causa.
Como no puede ser de otra manera, me picó la curiosidad por saber de qué forma se genera esta clave temporal y decidí investigar un poco. Al fin y al cabo esta validación vía teléfono, utiliza un esquema de seguridad similar al que utilizaban los juegos antiguos en los que no había ninguna conexión a
Internet para validar los códigos, así que seguro que habría unos códigos maestros o un algoritmo que descubrir entre el código. ¿Quién no recuerda los
Generadores de Claves o
KeyGen de aquella época con su
ASCII ART?
El primer paso fue hacer una imagen del disco duro del equipo con
Microsoft Windows CE usando una distribución de
BackTrack que suelo llevar conmigo por si acaso en un pendrive de esos que se llevan en el llavero. Así podría analizar el programa en detalle después.
|
Figura 4: Clonado de disco con BackTrack |
Tras ver los discos que hay en el sistema y hacer un clonado con
dd tenemos la imagen binaria, lista para ser montada y analizada en nuestro propio sistema.
|
Figura 5: Montaje del disco clonado con PassMark OSFMount |
Rebuscando un poco por el disco es fácil localizar el ejecutable que controla todo el sistema. El siguiente paso es ver el código e intentar localizar la parte en la que se genera el código temporal para luego seguir el flujo y ver dónde se comprueba. La aplicación está escrita en
.NET así que el lenguaje en el que está escrita es el
IL (Intermediate Languaje).
Este código puede analizarse cómodamente con el debugger
ILSpy que nos mostrará el código mucho más legible. Haciendo un poco de búsqueda, es posible ver dónde se muestra el teclado y donde se llama a la función de generación
MakeTempPwdKey(), que es la sospechosa de generar la clave temporal.
|
Figura 6: Función que muestra el código temporal por pantalla y pide su generación |
Echándole un ojo a la función sospechosa se puede ver que devuelve una cadena aleatoria con cuatro caracteres del patrón
“ABCDEFGHJKLMNPQRSTWXYZ123456789”. Evidentemente tiene pinta de ser la función que genera el código temporal, pero no parece demasiado elaborado.
|
Figura 7: Función que genera el código temporal aleatorio de 4 caracteres de longitud |
Por otro lado está la función que teniendo como parámetros de entrada una cadena y una fecha, retorna una cadena de
8 caracteres. Además esta función hace uso de clases de servicios criptográficos, y si miramos el código se puede ver cómo genera una clave a partir de la fecha, hora y la clave temporal generada anteriormente.
|
Figura 8: Clave de 8 caracteres que se calcula a partir del código temporal y la fecha. |
Es curioso ver cómo para hacer más aleatorio aún este proceso hay una semilla
hardcodeada en código que se usa para hacer único este proceso por instalación. Mirando las variables estáticas del código es posible ver como se usa como semilla, así que hay que suponer que en el momento en que se genera la licencia para un cliente se compila el código con esta semilla. Esto haría que la generación y validación de claves solo sirviera para un cliente.
|
Figura 9: Código que comprueba las passwords |
Obviamente, aunque no se trata de algo que afecte demasiado a la seguridad del sistema completo he reportado al fabricante de la máquina esta pequeña investigación de seguridad, recomendándole algún tipo de ofuscación extra que complique el análisis, cambiar a un sistema de verificación online o añadir alguna protección extra.
|
Figura 10: La contestación de la empresa detrás del sistema |
Por supuesto, el sistema de seguridad, tal y como está diseñado, cumple su función en la mayoría de los casos, pero aún así el fabricante contestó, cosa que dice cosas buenas de ellos. Yo mientras, voy a extraer las función de la
Figura 8 y hacerme mi
KeyGen en
.NET para poder entrar en modo "
Support" cuando sea necesario por si un día la empresa cierra o nos quedamos sin soporte.
Saludos,
Autor: Juan Luis Valverde Padilla
jl.valverde@jvalverde.es
1 comentario:
lamentablemente al tratarse de un .NET es muy facil descifrarlos aun teniendo packers como themida
Publicar un comentario