/
Ciberresiliencia

Cargas útiles y balizas de malware: tipos de cargas maliciosas

En el Entrada anterior del blog, discutimos cómo las cargas útiles facilitan las comunicaciones maliciosas y cómo un atacante puede obtener el control de un sistema después de ejecutar con éxito las cargas útiles y las balizas. Se utilizó un canal de comunicaciones reverse_tcp facilitado por la carga útil Meterpreter (del Metasploit Framework).

Esta publicación se centrará en comprender más sobre los distintos tipos de cargas útiles y ejemplos de las técnicas de manipulación de memoria que pueden emplear.

Malware se ha vuelto más sofisticada en composición y ejecución, especialmente en contraste con los días de virus más simples, como el Enredadera programa a principios de los setenta. Para los actores de amenazas motivados principalmente por objetivos clandestinos, permanecer bajo el radar para persistir en una red sin ser detectados durante un período prolongado suele ser un enfoque principal. Por lo tanto, emplearán técnicas correspondientes como señuelos, codificación, ofuscación, encriptación e imitación para lograr el nivel deseado de seguridad operacional.

Hay varios formatos ejecutables disponibles para un actor de amenazas. La elección del atacante depende de los vectores de ataque iniciales y de las acciones posteriores a la explotación. Éstos son algunos de Metasploit Formatos ejecutables y transformados de Framework.

Metasploit executable

Como se demuestra en primera parte, la baliza o carga útil es el implante en una máquina o red víctima que le da a un atacante una entrada y luego un punto de apoyo. Es una parte importante del arsenal de malware y del ciclo de vida general del ataque, lo que permite que el actor de amenazas tenga acceso práctico para realizar más actividades maliciosas.

Cuando se trata de la categorización amplia real, una carga útil puede estar “escalonada” o estar “sin etapas”. Un actor de amenaza puede elegir uno sobre el otro dependiendo de varios factores, los principales de los cuales pueden ser las consideraciones de seguridad operacional.

¿Qué son las cargas útiles por etapas?

Las cargas útiles por etapas desglosan las distintas fases de un ataque, a menudo utilizando múltiples fases de cargas útiles que una sola carga útil habría realizado de otro modo. Estas cargas útiles generalmente se dividen en un ejecutable “stager” (carga útil inicial o baliza) y un ejecutable de “etapa” (carga útil principal).

Un stager es un ejecutable pequeño que es una carga útil inicial. Es una pieza de código relativamente pequeña que se ejecuta para prepararse para una carga útil mucho mayor y más capaz conocida como la carga útil de etapa. Esto significa que “el stager prepara el escenario”. Por lo general, un stager formará parte de algún código de explotación cuando la entrada inicial aproveche una vulnerabilidad. Aquí, el código de explotación explotará con éxito la vulnerabilidad de destino y luego ejecutará el código de etapa (carga útil). El escenario entonces entra en acción.

La tarea principal del stager es ejecutar con éxito sin detección, volver a la infraestructura del atacante para descargar la carga útil principal deseada y luego configurar el sistema para ejecutar esa carga útil. La etapa descargada o la carga útil principal más grande pueden ser una o más cargas útiles dependiendo de la capacidad requerida por el atacante. Una vez que se descarga la etapa, el stager pasa el control de ejecución para continuar con la actividad maliciosa.

En el caso de un exploit de vulnerabilidad, el programa de exploit inicial hace algo similar para el stager como lo hace el stager para la carga útil de la etapa principal, en términos de asignación de recursos en el sistema comprometido. Seguirá un patrón similar a este:

stager pattern

El siguiente ejemplo muestra una carga útil por etapas como un ejecutable de Windows.

staged payload Windows executable

Las cargas útiles por etapas se adaptan a escenarios en los que puede haber restricciones relacionadas con el sistema, como espacio en disco y memoria, cuando se trata de la entrega y ejecución de la carga útil, como en el caso del shellcode utilizado para explotar una vulnerabilidad de desbordamiento de búfer.

¿Qué son las cargas útiles sin etapas?

Lo opuesto a las cargas útiles por etapas son las cargas útiles sin etapas. Las cargas útiles sin etapas son autónomas y, por lo general, mucho más grandes que las cargas útiles en etapas. Por lo general, combinan todas las capacidades requeridas de un atacante en un ejecutable.

Aquí, por lo general, no hay necesidad de una carga útil inicial (stager) que descargue la carga útil principal (stager). Una vez que se ejecuta la carga útil sin etapas, tendrá todas las capacidades necesarias para realizar acciones maliciosas, como inyección de memoria, volver a llamar a la infraestructura del atacante y entregar un shell para el atacante.

El siguiente ejemplo muestra una carga útil tcp inversa Meterpreter sin etapas como un ejecutable de Windows.

stageless Meterpreter reverse tcp payload

La decisión sobre qué tipo de carga útil usar como parte de una campaña maliciosa se conoce como las “consideraciones de seguridad operacional” para ese actor de amenazas. El tipo de infraestructura de atacante correspondiente que soporta la campaña maliciosa está parcialmente influenciado por estas consideraciones.

Cargas útiles por etapas frente a cargas sin etapas

Las cargas útiles por etapas de Metasploit tienen el símbolo de barra inclinada hacia adelante (/) después de la palabra Meterpreter. La siguiente captura de pantalla muestra ejemplos de cargas útiles de Meterpreter montadas por Windows.

Windows staged Meterpreter payloads

Las cargas útiles sin etapas emplean el símbolo de subrayado (_) después de la palabra Meterpreter. La siguiente captura de pantalla muestra ejemplos de cargas útiles sin etapas de Windows Meterpreter.

Windows Meterpreter stageless payloads

Y el siguiente ejemplo muestra ambas categorías de cargas útiles.

Windows Meterpreter payloads

Las cargas útiles sin etapas son autónomas y no requieren el paso adicional de enviar una etapa (carga útil principal) a la máquina víctima una vez que el malware realiza una llamada a la infraestructura del atacante. Observe en la captura de pantalla a continuación que después de que se inicie el controlador TCP inverso, el siguiente paso es abrir una sesión práctica del shell remoto de Meterpreter a la máquina víctima de inmediato, sin la necesidad de enviar más cargas útiles, como una etapa.

Meterpreter remote shell session

En la captura de pantalla a continuación, podemos ver que existe el paso extra de enviar la etapa después de que el stager haga una llamada a la infraestructura del atacante: “enviar etapa (175174) a 203.0.113.1”.

Sending stage

Otra diferencia entre etapas y sin etapas es el tamaño de las cargas útiles. En la captura de pantalla siguiente, la carga útil sin etapas (meeting_update_stageless.exe) es mucho mayor con 245 KB en comparación con la carga útil inicial por etapas (web1_meeting_update.exe) en 73 KB.

Stageless payload size

¿Qué es shellcode?

Shellcode es un código malicioso que intenta secuestrar el flujo normal de un programa en ejecución en la memoria de la computadora. Luego redirige el flujo para que se ejecute el código malicioso, en lugar del programa normal, dando al atacante un shell o acceso práctico. A menudo se trata de balizas o cargas útiles en forma de código de programación de bajo nivel o un código de máquina combinado con un exploit. Los exploits son piezas de código nativo o de bajo nivel que aprovechan con éxito una vulnerabilidad.

Las vulnerabilidades explotadas a menudo implican un desbordamiento de búfer en la memoria de una aplicación donde el atacante ha sobrepasado la memoria asignada para redirigir el flujo normal del programa. Un exploit exitoso conducirá entonces a la ejecución de una carga útil, que es el malware.

En sus formas más puras, Shellcode será código nativo o ensamblador comúnmente utilizado en exploits relacionados con la memoria.

El siguiente ejemplo muestra el código de shell de Powershell (ps1).

Powershell shellcode

En este ejemplo particular se utiliza un Biblioteca de vínculos dinámicos de Windows (DLL) inyectado en la memoria a través de un cargador reflectante. El código shell se genera en forma alfanumérica. Una vez ejecutado con éxito, puede volver a conectarse con el atacante a través de una sesión TCP DNS inversa generada desde Metasploit Framework.

La elección del mecanismo de entrega, el tipo de exploit y el sistema objetivo vulnerable van a determinar la elección de baliza o carga útil vinculada al ataque. El exploit se utiliza para aprovechar una aplicación vulnerable antes de obtener acceso al sistema operativo subyacente. En tal caso, se puede usar código específico para la aplicación correspondiente (por ejemplo, PHP o ASP para aplicaciones front-end de servidor web).

Características de Shellcode

Existen algunas consideraciones y características importantes para garantizar una ejecución exitosa de Shellcode y mantener una alta seguridad operacional.

El código debe:

  • Tener todas las instrucciones necesarias para ejecutar el shell deseado sin dejar de ser de tamaño relativamente pequeño.
  • Ser “independiente de la posición” en la memoria: esto es crucial ya que a menudo no es posible saber de antemano dónde se cargará en la memoria del proceso vulnerable de destino.
  • No contener nada que pueda causar errores potenciales o causar que todo el proceso se bloquee; por ejemplo, debido a caracteres nulos (0x00).
  • Ser capaz de aprovechar alguna asignación de memoria existente utilizando algunas técnicas de inyección: inyección de código o reflexión.

A partir de este punto, el atacante deberá seleccionar el tipo de ejecutable posterior al exploit apropiado para ejecutarlo en el sistema de destino, como EXE o DLL para Windows, ELF para Linux y APKs para Android. Nuevamente, se prefieren las técnicas posteriores a la explotación de memoria solamente para aumentar la seguridad operacional.

¿Qué es la inyección de código y la inyección de DLL?

La inyección DLL es el proceso de ejecutar código (DLL) en el contexto de otro proceso. Las cargas útiles de Meterpreter utilizan técnicas de inyección DLL para mecanismos de sigilo y evasión.

En Windows, una biblioteca de vínculos dinámicos o DLL (“Biblioteca compartida” en Linux) es una pieza de código almacenada como un archivo de biblioteca compartida. Esto significa que puede ser utilizado por diferentes programas de computadora según y cuando lo necesiten. El sistema operativo (en este caso, Windows) maneja la escritura y carga de la biblioteca, lo que se realiza en tiempo de ejecución. Un programa puede simplemente llamar o hacer referencia al archivo DLL requerido para usar el código contenido en él.

Esto es útil para los programadores porque solo escriben código una vez, lo compilan y lo almacenan como una biblioteca compartida o DLL, luego lo usan siempre que sea necesario y por múltiples programas.

La principal diferencia entre una DLL y un archivo EXE es que una DLL no puede ejecutarse de forma independiente. Necesita un programa como un EXE para llamar o hacer referencia y luego ejecutarlo. El siguiente ejemplo muestra los archivos DLL en un sistema operativo Windows, que normalmente se almacenan en la carpeta C:\Windows\ WinSxs (WinSxS significa Windows Sideby-Side).

DLL files Windows

Las capacidades de las DLL también las hacen muy útiles para los actores de amenazas. La inyección de código en el nivel básico implica un intento de un proceso (malicioso) de adjuntar (u obtener un manejador) a un proceso remoto (proceso víctima). A continuación, asigna suficiente memoria o cambios de permisos de página en el proceso de la víctima para ejecutar código nuevo, como una DLL, después de lo cual copia (inyecta) el código malicioso DLL en el espacio de memoria del proceso de la víctima nuevo o que ya se está ejecutando.

A continuación, se inicia un nuevo subproceso, que es la forma en que los procesos ejecutan tareas específicas, en el proceso de la víctima para ejecutar las instrucciones contenidas en el código inyectado o DLL.

Un hilo comparte el mismo espacio de memoria que el proceso que lo inició, mientras que diferentes procesos tienen distintos espacios de memoria asignados, especialmente en los casos en que no comparten ninguna variable. Esto es impuesto por el sistema operativo. Sin embargo, los sistemas operativos proporcionan mecanismos para que los procesos se comuniquen cuando sea necesario mediante la comunicación entre procesos (IPC), como tuberías (nombradas o anónimas), sockets, semáforos, memoria compartida y colas de mensajes.

En los sistemas operativos Windows, la inyección de código implica el uso de API y funciones legítimas de Windows para fines maliciosos. Por ejemplo:

  • Proceso abierto se utiliza para obtener un manejo en un proceso,
  • VirtualAlloceX luego facilita la asignación de memoria suficiente en ese proceso remoto o,
  • VirtualProtecteX se puede usar para anular los permisos de memoria (página) y, a continuación
  • Memoria de proceso de escritura escribe el código malicioso, como una DLL en el proceso de la víctima.
  • CreateRemoteThread, RtlCreateUserThread o ntCreateThreadEx se utiliza para crear un nuevo hilo (que es la forma en que los procesos ejecutan tareas específicas) y ejecutar la capacidad maliciosa, como robar credenciales o ejecutar ransomware.

La carga de una DLL en Windows requiere llamar a las funciones LoadLibraryA o LoadLibraryEXA, que forma parte de libloaderapi.h. Estas funciones, como dice Microsoft, “cargan el módulo especificado en el espacio de direcciones del proceso de llamada”. El uso de LoadLibrary para cargar una DLL significa que las DLL deben cargarse desde el disco.

Sin embargo, utilizando la técnica de inyección DLL reflexiva, una DLL se puede cargar directamente desde la memoria, una capacidad que actualmente no ofrece LoadLibrary. Un actor de amenazas puede usar la inyección DLL reflexiva para autocargar su código malicioso completamente en la memoria sin necesidad de invocar el cargador nativo de Windows en el disco. Aquí, utilizan un cargador personalizado en lugar de Windows LoadLibrary.

Los atacantes también pueden usar otras técnicas de inyección y manipulación de procesos, tales como:

  • Proceso de ahueado — Donde el malware iniciará un proceso de víctima en un estado suspendido. Luego ahuecará la memoria para dejar espacio para nuevo código, cambia los permisos de página, inyecta código malicioso y reanuda el proceso para ejecutar el código malicioso inyectado.
  • Carga lateral de DLL — Cuando un programa Windows legítimo y a menudo más antiguo vulnerable (proceso de víctima) se ve obligado a cargar una DLL maliciosa, que deliberadamente se nombra como una legítima esperada por la víctima y se coloca en el mismo directorio (lado a lado) que el programa vulnerable. El proceso del programa de la víctima buscará primero en su carpeta inmediata para localizar la DLL maliciosa renombrada (suplantada). Esta técnica aprovecha el orden de búsqueda DLL utilizado por el cargador de Windows para tener éxito.

Estas técnicas intentan hacer que la actividad maliciosa parezca legítima, evitando así la detección para persistir en un sistema comprometido.

A partir de las técnicas de manipulación de procesos discutidas en primera parte de esta serie, podemos ver a continuación que la migración del web1_meeting_update.exe malicioso original implicó alguna inyección de código.

En este ejemplo, la carga maliciosa inició (generó) un proceso notepad.exe completamente nuevo como el proceso de víctima deseado para inyectar código. El proceso malicioso original (PID 2472) se inyecta o migra al nuevo proceso de víctima notepad.exe (PID 1768).

notepad.exe victim process

Notepad.exe es un proceso confiable de Microsoft y, como tal, esto le da al atacante la capacidad de disfrazar el proceso original de aspecto malicioso a uno más confiable. Notepad.exe es un editor de texto básico de Windows que no necesita llamar (hacer referencia) a ninguna API, función o DLL de Windows requerida para la conexión de red, que en nuestro ejemplo, se ejecutó el proceso malicioso.

Se requiere un análisis dinámico para detectar la inyección que ocurre en la memoria. Mapeo de dependencias de aplicaciones también es necesario para detectar las comunicaciones de red sospechosas del editor de texto, en este caso proceso notepad.exe, haciendo una conexión de red.

Conclusión

Siguiendo desde primera parte de esta serie de blogs, hemos buscado algunas de las categorías y tipos de cargas útiles que puede usar un actor de amenazas y por qué pueden decidir usar un tipo sobre otro.

La mayoría de los atacantes de amenazas harán todo lo posible para garantizar que tengan una entrada inicial exitosa, mantengan la persistencia y eviten la detección. Hasta ahora hemos visto que la combinación de herramientas, técnicas y procedimientos significa que se necesita una combinación igualmente capaz de herramientas y procedimientos de seguridad para evitar un ataque exitoso, o más probable asumir una violación y evitar que un incidente cibernético inicial se convierta en una violación importante.

En la parte final de esta serie, discutiremos algunas técnicas y capacidades más importantes y, lo más importante, exploraremos el análisis y la mitigación.

Temas relacionados

Artículos relacionados

3 maneras en que Illumio lideró la innovación en ciberseguridad en septiembre de 2023
Ciberresiliencia

3 maneras en que Illumio lideró la innovación en ciberseguridad en septiembre de 2023

Conozca lo que los líderes empresariales de Illumio y los principales expertos en seguridad tenían que decir sobre el firewall, la seguridad en la nube y la innovación de IA parte por Illumio este mes.

Illumio Autorizado como Autoridad de Numeración CVE (CNA)
Ciberresiliencia

Illumio Autorizado como Autoridad de Numeración CVE (CNA)

Descubra cómo la designación CNA de Illumio nos ayuda a proteger mejor a nuestros clientes.

Más lecciones de seguridad empresarial de Steph Curry: Cuando algo sale mal
Ciberresiliencia

Más lecciones de seguridad empresarial de Steph Curry: Cuando algo sale mal

Los equipos de seguridad tienen que tomar decisiones como esta sobre la marcha todo el tiempo, y cuantos más datos tengan acceso sobre la situación, mejores decisiones podrán tomar.

No se han encontrado artículos.

Assume Breach.
Minimize Impact.
Increase Resilience.

Ready to learn more about Zero Trust Segmentation?