Inspección de rutinas de cifrado en Malware.

En el post anterior había comentado acerca de la metodología del análisis estático, ésta tomó lugar cuando se inspeccionó/examinó el código de la muestra de malware con la que se trabajó (Remcos RAT), a lo largo de ese análisis se hallaron múltiples anomalías o indicios sospechosos de que el código que constituía a ese binario realizaba tareas comunes en cuanto a software malicioso.

Esto se hace mediante la inspección del código recurriendo a la metodología del análisis estático, usando diferentes técnicas, herramientas, métodos, formas, etc. Para esto, se requiere algo de reversing, ya que habrá descompilar y examinar el código en su lenguaje nativo o en lenguaje máquina/ensamblador (Assembler), puesto a que en muchos casos, se necesita examinar instrucción por instrucción, como en los casos en los que cierto software malicioso contiene información oculta o rutinas de cifrado, que van tomando lugar a lo largo de su ejecución, esto podemos estudiarlo mediante el uso de un buen Debugger como lo es OllyDbg.

Para esta demostración, nuestra aproximación será mediante un análisis estático, similar al que se vio en el post anterior, la diferencia aquí es que trabajaremos usando un depurador de código ensamblador.

Es un hábito común que por cuestiones de seguridad los analistas primero hagan un análisis estático que uno dinámico, para llevar a cabo un análisis estático se necesitarán fuertes conocimientos o bases bien establecidas en programación y  conceptos de lenguaje de ensamblador (Assembler). Durante el proceso de análisis estático, no es necesario ejecutar el malware, generalmente, el código fuente de las muestras de malware no de fácil acceso, el reto principal de este tipo de análisis reside en la complejidad que existe en el malware, por ello,  primero se debe finalizar con éxito el proceso de ingeniería inversa o “Reversing” en donde se llevan a cabo tareas de des ensamblaje y debugging para así  poder analizar el código a un bajo nivel.

Se puede hacer esto de diferentes formas, con diferentes herramientas, para este ejemplo se usará OllyDbg.

¿Que se necesitará?

  • VM de Windows (Puedes intentarlo en otra en la que funcione «OllyDbg»
  • OllyDbg
  • Muestra de malware (Se te proporcionará en el enlace referente a esta).

OllyDbg es un depurador de código ensamblador de 32 bits para sistemas operativos Microsoft Windows. Pone especial énfasis en el análisis del código binario, esto lo hace muy útil cuando no está disponible el código fuente del programa. Traza registros, reconoce procedimientos, llamadas a las API, swiches, tablas, constantes y strings, así como localiza rutinas de archivos objeto.

OllyDbg es frecuentemente usado para la ingeniería inversa de programas. Es frecuentemente usado por Crackers para crackear software hecho por otros desarrolladores. Es a menudo la herramienta primaria para cracking e ingeniería inversa debido a su facilidad de uso y disponibilidad. Es también útil para que los programadores se aseguren de que su programa está corriendo según lo previsto.

NOTA: Durante el modulo de cracking software de nuestro curso COISP 1, viene mucha más información a detalle sobre el uso de “OllyDbg” para tareas de reversing.

Los proveedores de los antivirus no proporcionan mucha información sobre este troyano y parecen asignar diferentes nombres a sus variantes (Malware), algo que hay que tener en cuenta es que vendedores de antivirus no tienen una nomenclatura común para nombrar al malware, por lo que los nombres diferentes entre los proveedores no representan necesariamente una variante de troyano diferente. Consulta la tabla de variantes de “srvpc.exe” proporcionada por el instituto SANS:

(Precaución, muestra real de malware): srvcp

Teniendo entendido lo anterior, comenzaremos con la demostración.

Al abrirse, seleccionaremos en el menú “File” la opción “Open” y desde ahí cargaremos nuestro binario “srvcp.exe

Al abrir la muestra, se hará un Debugging del binario y se mostrará lo que la imagen debajo, el panel de trabo de OllyDbg consta de 4 partes, al igual que con Immunity Debugger:

  • Esta parte está dividida en 4 columnas, en la primera se puede ver la dirección de memoria o “Memory address”, en la segunda se muestra el código de operación de la instrucción que se halla en esa dirección, el lenguaje máquina está hecho con estos códigos de operación, que son lo que el CPU está ejecutando en realidad. En la tercera columna se encuentra el código ensamblador, y la cuarta es la que contiene comentarios, estos los produce el Debugger, sin embargo, tú puedes cambiarlos.
  • Registers (Registros): Aquí se pueden visualizar todos los registros del CPU y sus valores, se pueden ver registros de propósito general (General Purpose) los cuales contienen valores temporales, y también se ven registros para controlar el flujo del programa, también se pueden ver registros bandera, los cuales el CPU cambia cuando ha ocurrido algo importante o notorio (como un Overflow).
  • Dump (Volcado): Esta ventana muestra la vista hexadecimal del programa completo, dividida en 3 columnas, la primera muestra la dirección, la segunda los valores que se hallan en esa dirección, y la última muestra comentarios.
  • Stack (Pila): Muestra la locación de memoria a la que apunta el registro “ESP”.

Bajemos un poco más hasta donde nos ubiquemos en la parte donde se encuentra una rutina de “Push & Calls”:

Aquí hay algo importante que recalcar, puesto a que cada columna sobresaliente tiene su finalidad o función en lo que haremos (aquí y con otro programa que vayas a descompilar).

  • Offsets o dirección de memoria: Hace referencia a la dirección de un valor.
  • Opcodes: Siendo parte del lenguaje máquina, proporciona la instrucción operación a ser realizada.
  • Código ensamblador: Son las instrucciones de ensamblaje.

Entendido lo anterior, vemos que hay una rutina de “Pushs & Calls”, en donde los valores “Push” están siendo arrojados a la pila o “Stack” y enseguida ocurre una llamada hacia una rutina, apuntando a “004012C6”,  y de nuevo el valor en ASCII está siendo llevado a la pila con “PUSH” y llama de nuevo a la rutina con la dirección “004012C6”:

Lo que parece ser con esto, es que el binario trae consigo una rutina de descifrado, ya que es común que operen de esta manera en muestras de malware un tanto sofisticado o complejo, por lo que puede ser posible que el software use una funcionalidad de este tipo.
Analicemos más a detalle cómo es que funciona esta rutina del proceso de descifrado, una forma de conseguirlo es colocando un Breakpoint justo en donde comienza esta rutina, colocar un punto de ruptura (BreakPoint) sobre una instrucción nos es útil para que cuando el programa pase por ella o por alguna de esas instrucciones detenga su ejecución en su totalidad y podamos analizar su comportamiento.

Para colocarlo basta con seleccionar la instrucción, hacer clic derecho, usar la función “Breakpoint” y seleccionar la opción “Toggle”:


Al hacerlo, se sombreará con color rojo el Offset, ya teniendo el punto de ruptura colocado, reiniciaremos el programa con el siguiente botón, por lo que nos aparecerá un mensaje de advertencia por reiniciar el programa, presionaremos en el “Si”.

Seguido de eso, aparecerá como al comienzo, sobre la misma instrucción inicial, como colocamos el punto de ruptura más adelante después de muchas instrucciones, este se detendrá sobre la que lo hayamos colocado, para hacer esto habrá que correr el programa, esto se consigue con el siguiente botón:

Al hacerlo, como es un programa pequeño, no tomará un parpadear para que ocurra la detención justo en donde la colocamos y llevarnos allá en donde se ubica:

Hasta este punto nos ubicamos en la instrucción con el Breakpoint, por lo que es momento de analizar las demás instrucciones que hay debajo de esta y como es que funcionan e interactúan con el programa, veamos si realmente se trata de una rutina de descifrado. Para ello usaremos el botón “Step Over” para iniciar o correr instrucción por instrucción:

Al hacerlo vemos que se recorre la instrucción por haber sido ejecutada, mientras que del lado inferior derecho se ve en el “Stack” o pila que se ha descifrado el contenido y se muestra el valor “gus.ini”:

Continuemos, con el mismo proceso para descifrar el siguiente valor, como podrás ir viendo, se hace y se seguirá haciendo un “CALL” hacia “004012C6”, por cada rutina de “Push & Calls” que finaliza, obtenemos un resultado como vemos el siguen valor descifrado es “mickey”:

Continuemos con el siguiente valor, vemos que es el mismo proceso, ahora el  siguiente valor es “setpr”:

Ya hemos entendido como funciona el patrón, si seguimos los pasos hasta que termines con el bloque en donde se encuentra esta rutina de “Push & Calls”, en donde al final los valores en la pila serán estos:


Si prestas atención cuando los valores en ASCII son descifrados y arrojados a la pila, también se muestra su valor ya descifrado en el área de Disassembler:

Al finalizar este proceso podemos que tanto lo que está en la zona del “Disassembler” como lo que está en el “Stack” o Pila, son valores idénticos:

Con esta tercera demostración en cuanto al tópico de análisis de malware, se ha ejemplificado el uso de diferentes herramientas para hacer tanto análisis dinámico o análisis del comportamiento, como análisis estático, en este caso, en donde se hizo uso de un depurador de código o “Debugger”,  “OllyDbg” para éste ejemplo, en donde se descompiló el código mostrándolo en lenguaje máquina o ensamblador para entenderlo más a detalle, en donde se demostró el ir en busca de rutinas de descifrado de código ASCII para averiguar qué es lo que resguarda, ejemplificando así como es usada una rutina de “PUSHS & CALLS” para hacer este cometido.

NOTA: Durante los módulos de Exploit Development (Desarrollo de exploits), Modding y Análisis de Malware del nuestro libro y  curso COISP Nivel 2 «Blackhat» se hacen demostraciones y ejercicios de este tipo/similares y de mayor complejidad, así como también realizamos constantes investigaciones para mantener estos tópicos lo más diversos posibles, añadiendo cada vez más y más contenido.

Deja un comentario

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