Skip to content
KitploitKITPLOIT
HerramientasBlog
Enviar
HerramientasBlog
Enviar

¡Herramientas de Hacking, PenTest y Ciberseguridad para tu Arsenal de Seguridad!

Kitploit es un directorio de herramientas de hacking, ciberseguridad y pentesting. Descubre las últimas actualizaciones de proyectos para encontrar vulnerabilidades, analizar sistemas, automatizar pruebas y fortalecer tu seguridad.

··Feeds·Contacto·Privacidad·© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
BeatRev — PoC para frustrar/derrotar a los analistas de malware | Kitploit
Herramientas/GitHubGitHub/octoberfest7/beatrev
Ingeniería InversaAnálisis de MalwareAprendizaje y EducaciónDesarrollo de Payloads
GitHuboctoberfest7/beatrev

BeatRev

PoC para frustrar/derrotar a los analistas de malware

Ver Repositorio
154221hace 4 añosRevisado por Kitploit

Más Populares

Ver todos →

Descubre las herramientas más usadas por nuestra comunidad.

Explora todas las herramientas

Explora nuestra colección de herramientas

Ver todas las herramientas →
Compartir

BeatRev Versión 2

Descargo de responsabilidad / Responsabilidad

El trabajo que sigue es un POC para permitir que el malware se "vincule" a una víctima particular con el fin de frustrar los esfuerzos de los analistas de malware.

No asumo ninguna responsabilidad por el uso malicioso de cualquier idea o código contenido en este proyecto. Proporciono esta investigación para seguir educando a los profesionales de la seguridad informática y ofrecer formación adicional / material de reflexión para analistas de malware, ingenieros inversos y el equipo azul en general.

TLDR

La primera vez que el malware se ejecuta en una víctima, cifra con AES la carga útil real (un RDLL) utilizando datos ambientales de esa víctima. Cada vez subsiguiente que se ejecuta el malware, recopila la misma información ambiental, descifra con AES la carga útil almacenada como un arreglo de bytes dentro del malware y la ejecuta. Si falla el descifrado / la carga útil no se ejecuta, el malware se elimina a sí mismo. Protección contra ingenieros inversos y analistas de malware.

Actualizado el 6 de junio de 2022

image

No sentí que hubiera terminado con este proyecto, así que volví e hice una reescritura bastante sustancial. La investigación original y las técnicas se pueden encontrar aquí.

Los cambios principales son los siguientes:

  1. He publicado todo el código fuente
  2. Integré el ReflectiveDLL de Stephen Fewer en el proyecto para reemplazar Stage2
  3. Formateé algunos de los arreglos de bytes de este proyecto en formato de cadena y los analizo con UuidFromStringA. Se usó Este Repo como plantilla. Esto se hizo para reducir la entropía de Stage0 y Stage1
  4. Stage0 ha incorporado una buena cantidad de evasión de AV. Gracias al Proyecto Ares de Cerbersec por la inspiración
  5. Se ha incluido la aplicación constructora para producir Stage0

Hay bastantes cosas diferentes que se pueden tomar del código fuente de este proyecto para usar en otros lugares. Espero que sea útil para alguien.

Problemas con la versión original y mitigaciones

Hubo algunas deficiencias con la versión original de BeatRev que decidí intentar solucionar.

Stage2 era anteriormente un ejecutable independiente que se almacenaba como el flujo de datos alternativo (ADS) de Stage1. Para lograr el cifrado AES por víctima y el posterior descifrado y ejecución, cada vez que se ejecutaba Stage1, leía el ADS, lo descifraba, volvía a escribir en el ADS, llamaba a CreateProcess y luego volvía a cifrar Stage2 y lo escribía en el disco en el ADS. Esto era una gran cantidad de operaciones de E/S y, por supuesto, la llamada a CreateProcess no era ideal.

Me topé con la investigación de Steven Fewer sobre las DLL reflectantes y parecía encajar bien. Stage2 ahora es un RDLL; nuestro malware / ejecutor de shellcode / lo que sea que queramos proteger se puede portar al formato RDLL y almacenar como un arreglo de bytes dentro de Stage1 que luego se descifra en tiempo de ejecución y Stage1 lo ejecuta. Esto elimina todas las operaciones de E/S y la llamada a CreateProcess de la Versión 1 y es un cambio bienvenido.

Stage1 no tenía ningún tipo de medidas reales de evasión de AV programadas; esto fue intencional, ya que es trabajo extra y no era realmente el objetivo de esta investigación. Durante la reescritura, lo tomé como un desafío adicional y agregué hashing de API para eliminar funciones de la Tabla de Direcciones de Importación de Stage1. Esto ha ayudado con la detección y Stage1 tiene una tasa de detección de 4/66 en VirusTotal. Me sentí cómodo subiendo Stage1 dado que ya está vinculado a la máquina original en la que se ejecutó y la firma del archivo cambia constantemente debido al cifrado AES que ocurre.

Recientemente comencé a prestar atención a la entropía como medio para detectar malware; para intentar reducir la entropía, que de otra manera es muy alta, que un blob binario enorme cifrado con AES le da a un ejecutable, investigué la integración de shellcode almacenado como UUID. Debido a que el binario se almacena en representación de cadena, hay una entropía general más baja en el ejecutable. Usando esta técnica, la entropía de Stage0 ahora es ~6.8 y la de Stage1 ~4.5 (en una escala máxima de 8).

Finalmente, es una tarea enorme integrar y producir un Stage0 completo debido a todas las piezas que deben manipularse. Para facilitar esto, hice una aplicación constructora que ingiere un archivo de plantilla Stage0.c, un stub de Stage1, un stub de Stage2 y un archivo de shellcode sin procesar (esto se construyó pensando en que Stage2 es un ejecutor de shellcode que contiene shellcode de CobaltStrike) y produce un payload Stage0 compilado para usar en el objetivo.

Detalles técnicos

El código de DLL reflectante de Stephen Fewer contiene algunas instrucciones específicas del compilador de Visual Studio; estoy seguro de que es posible portar la técnica a MingW, pero no tengo las habilidades para hacerlo. El problema principal aquí es que el shellcode de CobaltStrike (sin estado es ~265K) debe ir dentro del RDLL y ser compilado. Para solucionar esto e integrarlo bien con el resto del proceso, escribí mi RDLL Stage2 para que contenga un bloque de memoria de variable global del tamaño del shellcode de CS; este bloque de memoria de ~265K tiene un marcador de posición pequeño que se puede localizar en el binario compilado. El código en src/Stage2 ya tiene esto agregado.

Una vez compilado, este Stage2stub se transfiere a Kali donde se puede realizar un parche binario para colocar el shellcode real de CS en el lugar de la memoria que le corresponde. Esto produce el Stage2 completo.

Para evitar el desastre de E/S y CreateProcess descrito anteriormente, Stage0 también debe parchear el Stage2 completo en el Stage1 compilado; esto es necesario para permitir que Stage2 se cifre una vez en el objetivo, además de evitar que Stage2 se almacene por separado en el disco. El mismo concepto descrito anteriormente para Stage2 es realizado por Stage0 en el objetivo para ensamblar el payload final de Stage1. Cabe señalar que se usa la función memmem para localizar el marcador de posición dentro de cada stub; esta función no está disponible en Windows, por lo que se utilizó una implementación personalizada. Gracias a Foxik384 por su código.

Para realizar un parche binario, debemos asignar la memoria necesaria de antemano; esto tiene un efecto compuesto, ya que Stage1 ahora debe ser lo suficientemente grande como para contener también a Stage2. Con el paso adicional de convertir Stage2 a una cadena UUID, Stage2 se infla en tamaño, al igual que Stage1 para contenerlo. Un RDLL de Stage2 con un tamaño compilado de ~290K resulta en un payload de Stage0 de ~1.38M y un payload de Stage1 de ~700K.

La aplicación constructora solo admite la creación de EXE x64. Sin embargo, con un poco más de trabajo, en teoría se podría hacer que Stage0 sea una DLL, así como Stage1, y que todo el ciclo de vida exista como un secuestro de DLL en lugar de un ejecutable independiente.

Instrucciones

Estas instrucciones te pondrán en camino para usar este POC.

  1. Compila Builder usando gcc -o builder src/Builder/BeatRevV2Builder.c
  2. Modifica la variable sc_length en src/Stage2/dll/src/ReflectiveDLL.c para que coincida con la longitud del archivo de shellcode sin procesar utilizado con el builder (he incluido fakesc.bin como ejemplo)
  3. Compila Stage2 (en Visual Studio, el proyecto ReflectiveDLL usa algunas instrucciones específicas del compilador de VS)
  4. Mueve el stage2stub.dll compilado de vuelta a Kali, modifica src/Stage1/newstage1.c y define stage2size como el tamaño de stage2stub
  5. Compila stage1stub usando x86_64-w64-mingw32-gcc newstage1.c -o stage1stub.exe -s -DUNICODE -Os -L /usr/x86_64-w64-mingw32/lib -l:librpcrt4.a
  6. Ejecuta el builder usando la sintaxis: ./builder src/Stage0/newstage0_exe.c x64 stage1stub.exe stage2stub.dll shellcode.bin
  7. El builder producirá dropper.exe. Este es un payload Stage0 formateado y compilado para usar en el objetivo.

BeatRev Versión Original

Introducción

Hace unos 6 meses se me ocurrió que, si bien había aprendido y hecho mucho con el malware en lo que respecta a la evasión de AV/EDR, había dedicado muy poco tiempo a tratar de evadir o derrotar la ingeniería inversa / el análisis de malware. Esto se debió a algunas buenas razones:

  1. No sé nada sobre análisis de malware ni ingeniería inversa
  2. Cuando se habla de trabajo de Red Team legal y autorizado, realmente no hay necesidad de intentar frustrar o derrotar a un ingeniero inverso porque la actividad debería haber sido desconflictada mucho antes de llegar a esa etapa.

Sin embargo, fue un experimento mental interesante y tenía algunos colegas que SÍ saben sobre análisis de malware con quienes podía intercambiar ideas. Parecía un desafío de una magnitud completamente diferente en comparación con la evasión de AV/EDR y decidí intentarlo.

Premisa

Mi premisa inicial era que el malware, la primera vez que se ejecuta, de alguna manera se "vinculara" a esa máquina víctima; cualquier intento posterior de ejecutarlo evaluaría algo en el entorno objetivo y lo compararía para ver si coincide con algo en el malware. Si esos dos factores coinciden, se ejecuta como se espera. Si no coinciden (como en el caso de que la muestra se haya transferido al sandbox de un analista de malware), el malware se elimina a sí mismo (una vez más, apoyándome en el trabajo de LloydLabs y su delete-self-poc).

Esta "clave" debe ser algo "único" de la computadora víctima. Idealmente, será una combinación de varias piezas de información, y luego se ofuscará aún más. Como ejemplo, podríamos recopilar el nombre de host de la computadora, así como la cantidad de RAM instalada; estos dos valores se pueden concatenar (por ejemplo, Client018192MB) y luego aplicar un hash usando una función definida por el usuario para producir un número (por ejemplo, 5343823956).

Hay muchas opciones sobre qué información recopilar, pero se debe pensar en qué valores un miembro del equipo azul podría falsificar fácilmente; una dirección MAC, por ejemplo, puede parecer un identificador "único" atractivo para una víctima, sin embargo, las direcciones MAC se pueden configurar manualmente fácilmente para que un ingeniero inverso pueda hacer coincidir su sandbox con la víctima original. Idealmente, los valores elegidos y enumerados serán aquellos que sean difíciles de replicar para un ingeniero inverso en su entorno.

Con algo de magia de autoeliminación, el malware podría leerse a sí mismo en un búfer, localizar una variable marcador de posición y reemplazarla con este número, eliminarse a sí mismo y luego escribir el malware modificado de vuelta al disco en la misma ubicación. Combinado con una declaración if/else en Main, la próxima vez que se ejecute el malware, detectará que ya se ha ejecutado anteriormente y luego irá a recopilar el nombre de host y la cantidad de RAM nuevamente para producir el número hash. Esto luego se evaluaría contra el número almacenado en el malware durante la primera ejecución (5343823956). Si coincide (como es el caso si el malware se ejecuta en la misma máquina que originalmente), se ejecuta como se espera; sin embargo, si se devuelve un valor diferente, volverá a llamar a la función de autoeliminación para eliminarse del disco y proteger al autor del analista de malware.

Esta parecía una buena idea en teoría hasta que hablé con un colega que tiene experiencia real en análisis de malware e ingeniería inversa. Me dijeron que un ingeniero inverso podría observar la declaración condicional en el malware (si ValorDelPrimerEjecución != ObtenerNombreHostYRAM()), y dado que el valor esperado está codificado en un lado de la declaración condicional, simplemente modificar los registros para que contengan el valor esperado, evitando así por completo todo el mecanismo de protección.

Este nuevo conocimiento descarriló por completo el experimento mental y, como realmente no tenía un uso para una capacidad como esta en primer lugar, aquí es donde el proyecto se detuvo durante ~6 meses.

Resumen

Este proyecto resurgió algunas veces durante los 6 meses siguientes, pero cada vez fue poco más que un pensamiento pasajero, ya que no había adquirido nuevos conocimientos sobre ingeniería inversa / análisis de malware y, nuevamente, no tenía necesidad de tal capacidad. Hace unos días, la idea surgió de nuevo y, aunque ninguno de esos factores ha cambiado realmente, supongo que tenía un poco más de conocimientos y esta vez no pude dejar pasar la idea.

Teniendo en cuenta el problema mencionado anteriormente con respecto a los valores codificados, finalmente decidí optar por un diseño de múltiples etapas. Me referiré a ellas como Stage0, Stage1 y Stage2.

Stage0: Configuración. Se ejecuta en la infección inicial y se elimina después.

Stage1: Ejecutor. Se ejecuta cada vez que el malware se ejecuta posteriormente.

Stage2: Carga útil. El malware que te importa proteger. Genera un proceso e inyecta shellcode para devolver un Beacon.

Ciclo de vida

Stage0

Stage0 es el ejecutable nuevo entregado al objetivo por el atacante. Contiene Stage1 y Stage2 como arreglos de bytes cifrados con AES; esto se hace para proteger el malware en tránsito, o en caso de que un defensor de alguna manera obtenga una copia de Stage0 (lo que no debería suceder). La clave AES y el IV están contenidos dentro de Stage0, por lo que en realidad esto no protegerá a Stage1 o Stage2 de un miembro competente del equipo azul.

Stage0 realiza las siguientes acciones:

  1. Evasión de sandbox.
  2. Se elimina a sí mismo del disco. Todavía se está ejecutando en memoria.
  3. Descifra Stage1 usando la clave AES/IV almacenada y lo escribe en el disco en lugar de Stage0.
  4. Recopila el nombre del procesador y el ProductID de Microsoft.
  5. Aplica hash a este valor y luego lo rellena para que se ajuste a una longitud de clave AES de 16 bytes. Este valor invertido sirve como el IV AES.
  6. Descifra Stage2 usando la clave AES/IV almacenada.
  7. Cifra Stage2 usando la nueva clave AES/IV específica de la víctima.
  8. Escribe Stage2 en el disco como un flujo de datos alternativo de Stage1.

Al final de esta secuencia de eventos, Stage0 finaliza. Debido a que se eliminó del disco en el paso 2 y ya no se ejecuta en memoria, Stage0 efectivamente ha desaparecido; Sin conocimiento previo de esta técnica, el resto del ciclo de vida del malware será mucho más confuso de lo que ya es.

En el paso 4, se recopilan el nombre del procesador y el ProductID de Microsoft; el ProductID se obtiene del Registro, y este valor se puede modificar manualmente, lo que presenta una oportunidad fácil para que un miembro del equipo azul haga coincidir su sandbox con el entorno objetivo. Dependiendo de qué información ambiental se recopile, esto puede volverse más fácil o más difícil.

Stage1

Stage1 fue colocado por Stage0 y existe exactamente en la misma ubicación que Stage0 (incluyendo el nombre). Stage2 se almacena como un ADS de Stage1. Cuando el atacante / la persistencia ejecuta posteriormente el malware, está ejecutando Stage1.

Stage1 realiza las siguientes acciones:

  1. Evasión de sandbox.
  2. Recopila el nombre del procesador y el ProductID de Microsoft.
  3. Aplica hash a este valor y luego lo rellena para que se ajuste a una longitud de clave AES de 16 bytes. Este valor invertido sirve como el IV AES.
  4. Lee Stage2 del ADS de Stage1 en la memoria.
  5. Descifra Stage2 usando la clave AES/IV específica de la víctima.
  6. Verifica los primeros dos bytes del búfer de Stage2 descifrado; si no es MZ (descifrado fallido), elimina Stage1/Stage2, sale.
  7. Escribe Stage2 descifrado de vuelta al disco como ADS de Stage1.
  8. Llama a CreateProcess en Stage2. Si esto falla (descifrado fallido), elimina Stage1/Stage2, sale.
  9. Espera 5 segundos para permitir que Stage2 se ejecute + salga para que pueda sobrescribirse.
  10. Cifra Stage2 usando la clave AES/IV específica de la víctima.
  11. Escribe Stage2 cifrado de vuelta al disco como ADS de Stage1.

Ten en cuenta que Stage2 DEBE salir para que pueda sobrescribirse; el truco de autoeliminación no parece funcionar en archivos que ya son ADS, ya que la técnica de autoeliminación se basa en renombrar el flujo de datos principal del ejecutable. Idealmente, Stage2 será un ejecutable de inyección o generación+inyección.

Hay dos puntos en los que Stage1 podría detectar que no se está ejecutando desde la misma víctima y eliminarse a sí mismo / Stage2 para proteger al actor de amenazas. El primero es la verificación del encabezado ejecutable después de descifrar Stage2 usando la información ambiental recopilada; en teoría, un ingeniero inverso podría eludir este paso, pero es un primer buen control. El segundo punto de protección es el resultado de la llamada a CreateProcess: si falla porque Stage2 no se descifró correctamente, el malware se elimina de manera similar. El resultado de esta llamada también podría modificarse para evitar la eliminación por parte del ingeniero inverso, sin embargo, esto no cambia el hecho de que Stage2 está cifrado e inaccesible.

Stage2

Stage2 es el núcleo de la cadena de malware; es un ejecutor de shellcode / pieza de malware completamente funcional en sí mismo. Al cifrarlo y protegerlo de la manera que lo hemos hecho, las acciones del malware de estado final están mucho mejor ofuscadas y protegidas de los ingenieros inversos y analistas de malware. Durante el desarrollo, utilicé uno de mis ejecutores de shellcode existentes que contenía shellcode de CobaltStrike, pero esto podría ser cualquier cosa que el atacante quiera ejecutar y proteger.

Impacto, mitigación y trabajo futuro

Entonces, ¿qué se logra realmente con un ciclo de vida de malware como este? Hay algunas características interesantes de las que hablar.

Los flujos de datos alternativos son una característica exclusiva de los sistemas de archivos NTFS; esto significa que la mayoría de las formas de transferir el malware después de la infección inicial eliminarán y perderán Stage2 porque es un ADS de Stage1. Se debe tener especial cuidado para transferir la muestra a fin de preservar Stage2, ya que sin él, muchos ingenieros inversos y analistas de malware estarán muy confundidos sobre lo que está sucediendo. Los archivos RAR pueden preservar los ADS, y herramientas como 7Z y Peazip pueden extraer archivos y sus ADS.

Como se mencionó anteriormente, cuando el malware que usa este ciclo de vida llega a un miembro del equipo azul, debería estar en Stage1; Stage0 ha ido y venido, y Stage2 ya está cifrado con la información ambiental recopilada por Stage0. No saber que Stage0 existió agregará una incertidumbre considerable para comprender el ciclo de vida y descifrar Stage2.

En teoría (porque, nuevamente, no tengo experiencia en ingeniería inversa), Stage1 debería poder ser sometido a ingeniería inversa (después de que el equipo azul revise algunas copias porque se sigue eliminando a sí mismo) y la información que Stage1 recopila del sistema objetivo debería poder ser identificada. Con una respuesta bien coordinada, el equipo azul debería poder identificar la víctima de la que provino el malware e ir a recopilar esa información de ella e introducirla en el programa para que pueda transformarse adecuadamente en la clave AES/IV que descifra Stage2. Sin embargo, hay muchos "si" en relación con la habilidad relativa del ingeniero inverso, así como la disponibilidad de la máquina víctima para que se pueda recuperar esa información.

La lista blanca de aplicaciones frustraría significativamente este ciclo de vida. Stage0/Stage1 podrían cargarse lateralmente como una DLL, sin embargo, sospecho que Stage2 como ADS presentaría algunos problemas. No tengo un entorno para probar malware contra AWL ni me he molestado en portar todo esto al formato DLL, así que no puedo decirlo. Estoy seguro de que hay formas creativas de sortear estos problemas.

También estoy bastante seguro de que hay formas más inteligentes de ejecutar Stage2 que dejarlo caer al disco y llamar a CreateProcess; ya sea mapear manualmente el ejecutable o usar una herramienta como Donut para convertirlo en shellcode parecen ideas razonables.

Código y binario

Durante el desarrollo, creé una aplicación constructora a la que se pueden alimentar Stage1 y Stage2 para producir un Stage0 funcional; sin embargo, esto no se proporcionará, aunque proporcionaré la mayor parte del código fuente de stage1, ya que es la pieza que sería más visible para un miembro del equipo azul. Stage0 será excluido como ejercicio para el lector, y stage2 es cualquier ejecutable independiente que quieras ejecutar y proteger. Este POC puede ser investigado más a fondo a discreción y esfuerzo de los lectores capaces.Proporcionaré una copia compilada de este malware como Dropper64.exe. Dropper64.exe está compilado para x64. Dropper64.exe es Stage0; contiene Stage1 y Stage2. Al ejecutarse, Stage1 y Stage2 se guardarán en disco pero NO se ejecutarán automáticamente, debes ejecutar Dropper64.exe (ahora Stage1) nuevamente. Stage2 es una versión x64 de calc.exe. Incluyo esto para cualquier miembro del equipo azul que quiera echarle un vistazo, pero ten en cuenta que en un escenario de respuesta a incidentes el 99% de las veces obtendrás Stage1/Stage2, Stage0 habrá desaparecido.

Conclusión

Este fue un proyecto personal interesante que me consumió un fin de semana largo. Estoy seguro de que sería mucho más avanzado/completo si tuviera experiencia en un depurador y desensamblador, pero haces lo mejor con lo que tienes. Estoy ansioso por escuchar lo que piensan los miembros del equipo azul y otros desarrolladores de malware. Estoy seguro de que he reinventado la rueda de manera demasiado complicada en comparación con lo que hacen los APT reales, pero aprendí algunas cosas en el camino. ¡Gracias por leer!

Descargar herramienta