Reversing Malware Rust Basic 1

3xploit
5 min readJan 29, 2024

En el mundo de la ciberseguridad, una de las batallas más intensas se libra en el campo del malware. Los atacantes, constantemente, desarrollan nuevas técnicas para evadir la detección y el análisis de sus creaciones maliciosas. En este artículo, profundizaremos en cómo los atacantes utilizan técnicas anti-debug en el malware, centrándonos en el lado técnico de este cat-and-mouse game.

¿Qué es Anti-Debugging?

El anti-debugging es un conjunto de técnicas utilizadas para evitar o dificultar la depuración de un programa. Estas técnicas son comúnmente utilizadas en software malicioso (malware) para evadir la detección y el análisis por parte de investigadores de seguridad y herramientas de análisis automático.

NtQueryInformationProcess

NtQueryInformationProcess es una función del sistema operativo Windows que proporciona información detallada sobre los procesos. En nuestro caso, se utiliza para indagar si el proceso actual está siendo depurado. Esto se logra consultando el "manejador del objeto de depuración" del proceso.

Uso de NtQueryInformationProcess en Anti-Debugging

En el código proporcionado, se utiliza la función NtQueryInformationProcess para detectar la presencia de un depurador. Esta función es parte de la API de Windows y permite obtener información detallada sobre un proceso. En particular, se usa para consultar el manejador del objeto de depuración asociado con el proceso actual.

¿Cómo se Realiza la Detección?

  1. Consulta del Manejador de Objeto de Depuración: El código llama a NtQueryInformationProcess, pasando GetCurrentProcess() (que devuelve el manejador del proceso actual), la constante PROCESS_DEBUG_OBJECT_HANDLE, y una variable para almacenar el manejador de objeto de depuración. La constante PROCESS_DEBUG_OBJECT_HANDLE instruye a la función para que devuelva el manejador del objeto de depuración asociado con el proceso.
  2. Análisis del Resultado: Si el manejador devuelto es distinto de null, se asume que existe un depurador asociado con el proceso. Esto se debe a que en un entorno de depuración, el sistema operativo asocia un objeto de depuración con el proceso para permitir la comunicación y control por parte del depurador.

Propósito de la Función

La función is_debugger_present está diseñada para determinar si el proceso actual está siendo depurado. Esta verificación es un aspecto crucial en el desarrollo de malware, ya que permite al software malicioso cambiar su comportamiento o desactivarse para evitar ser analizado en entornos de depuración.

Inicialización de Variables:

  • debug_object_handle: Un manejador que almacenará el manejador del objeto de depuración si existe. Se inicializa como un puntero nulo.
  • return_length: Almacena la longitud de los datos retornados por la función NtQueryInformationProcess. Se inicializa en 0.

Bloque unsafe:

  • La llamada a NtQueryInformationProcess requiere un bloque unsafe porque involucra operaciones a bajo nivel con la memoria y manejadores del sistema operativo, que pueden resultar en comportamiento no seguro si se usan incorrectamente.

Llamada a NtQueryInformationProcess:

  • GetCurrentProcess(): Obtiene el manejador del proceso actual.
  • PROCESS_DEBUG_OBJECT_HANDLE: Especifica que queremos obtener información sobre el manejador del objeto de depuración del proceso.
  • &mut debug_object_handle: Puntero al manejador del objeto de depuración que se actualizará si hay un depurador presente.
  • std::mem::size_of::<HANDLE>() as u32: Especifica el tamaño del manejador del objeto esperado.
  • &mut return_length: Puntero a la variable que almacenará la longitud de los datos retornados.
  • Evaluación del Resultado:
  • NT_SUCCESS(status): Verifica si la llamada a NtQueryInformationProcess fue exitosa.
  • !debug_object_handle.is_null(): Comprueba si el manejador del objeto de depuración es no nulo, lo que indicaría la presencia de un depurador.

PRUEBA DE CONCEPTO

La prueba de concepto tiene como objetivo demostrar cómo un programa malicioso puede utilizar técnicas anti-debugging para evadir la detección y luego ejecutar código arbitrario (en este caso, un shellcode) si determina que no se encuentra en un entorno de depuración.

Se realiza el analisis de la muestra en x64dbg pero no se logra correr el shellcode. debido a que detecta la presencia del depurador.

Por Qué No Se Ejecuta el Shellcode

Si la función antidebugavan__is_debugger_present detecta un depurador, devuelve un valor que resulta en que al sea 1. La instrucción test al, 1 establecerá los flags de resultado de manera que la instrucción jnz realice el salto, evitando así la ejecución del shellcode. Este comportamiento es típico de las técnicas anti-debugging, donde el malware altera su flujo de ejecución para evadir el análisis en presencia de un depurador.

Bypass

Para evadir esta detección en IDA , puedes modificar el salto condicional que sigue a la llamada de la función.

  • Puedes cambiar el jnz a un salto incondicional (jmp) para evitar completamente la sección de código que se ejecuta si se detecta un depurador.
  • Alternativamente, puedes invertir la condición del salto (por ejemplo, cambiando jnz a jz) si quieres que el programa se comporte como si no hubiera detectado un depurador.
  • Aplicar el parche

Despues de aplicar el patch sobre el binario se ejecuta el debbuger y se logra generar la ejecucion del shellcode (calc.exe) generando un bypass sobre la implementacion de la tecnica antidebugging.

shellcode calc
ejecucion finalizada.

--

--

3xploit

Ethical Hacker | Pentester Cloud | Red Team | Offensive Developer | Adversary Simulation | Golang Developer