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
ShellcodeFluctuation — Una técnica avanzada de evasión en memoria que alterna la protección de memoria del shellcode entre RW/NoAccess y RX, y luego cifra/descifra su contenido. | Kitploit
Herramientas/GitHubGitHub/mgeeky/shellcodefluctuation
ShellcodePost-ExplotaciónRed TeamingDesarrollo de PayloadsAtaque Adversario
GitHubmgeeky/shellcodefluctuation

ShellcodeFluctuation

Una técnica avanzada de evasión en memoria que alterna la protección de memoria del shellcode entre RW/NoAccess y RX, y luego cifra/descifra su contenido.

Ver Repositorio
1.1k163hace 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

Shellcode Fluctuation PoC

Una implementación de prueba de concepto para otra técnica de evasión en memoria que cifra y descifra cíclicamente el contenido del shellcode para luego hacerlo fluctuar entre la protección de memoria RW (o NoAccess) y RX. Cuando nuestro shellcode reside en páginas de memoria RW o NoAccess, escáneres como Moneta o pe-sieve no podrán localizarlo y volcarlo para su posterior análisis.

Introducción

Después de publicar ThreadStackSpoofer recibí algunas preguntas sobre el siguiente punto del README:

Cambia la protección de las páginas de memoria de tu Beacon a RW (desde RX/RWX) y cifra su contenido antes de dormir (eso podría evadir escáneres como Moneta o pe-sieve)

Antes estaba bastante seguro de que la comunidad ya sabía cómo cifrar/descifrar sus payloads y cambiar sus protecciones de memoria para simplemente evadir los escáneres de memoria que buscan regiones ejecutables anómalas. Las preguntas demostraron lo contrario, así que decidí publicar esta PoC no armada para documentar otra estrategia de evasión y ofrecer una implementación de muestra con la que la comunidad pueda trabajar.

Esta PoC es una demostración de una técnica bastante simple, ya conocida por la comunidad ofensiva (así que realmente no estoy aportando nada nuevo aquí) con la esperanza de revelar el secreto detrás de la magia mostrada por algunos frameworks comerciales que demuestran sus capacidades de evasión apuntando a ambos escáneres de memoria mencionados anteriormente.

Aquí hay una comparación cuando se fluctúa a RW (otra opción es fluctuar a PAGE_NOACCESS - descrito más abajo):

  1. Beacon sin cifrar
  2. Beacon cifrado (fluctuando)

comparison

Esta implementación, junto con mi ThreadStackSpoofer, ofrece a la comunidad de Seguridad Ofensiva implementaciones de muestra para ponerse al día con lo que ofrecen los productos C2 comerciales, para que no podamos hacer nada peor en nuestras herramientas de Red Team. 💪


¿Cómo funciona?

Este programa realiza auto-inyección de shellcode (aproximadamente mediante el clásico VirtualAlloc + memcpy + CreateThread). Cuando el shellcode se ejecuta (esta implementación apunta específicamente a implantes Cobalt Strike Beacon), se enganchará una función de Windows para interceptar el momento en que Beacon se duerme, kernel32!Sleep. Cada vez que se invoca la función enganchada MySleep, localizará los límites de su asignación de memoria, cambiará su protección a RW y aplicará xor32 a todos los bytes almacenados allí. Tras esperar la cantidad de tiempo esperada, cuando el shellcode regrese a nuestro manejador MySleep, descifraremos los datos del shellcode y devolveremos la protección a RX.

La fluctuación a PAGE_READWRITE funciona de la siguiente manera

  1. Leer el contenido del shellcode desde un archivo.
  2. Enganchar kernel32!Sleep apuntando de vuelta a nuestro callback.
  3. Inyectar y lanzar el shellcode mediante VirtualAlloc + memcpy + CreateThread. Al contrario de lo que teníamos en ThreadStackSpoofer, aquí no enganchamos nada en ntdll para lanzar nuestro shellcode, sino que saltamos a él desde nuestra propia función. Esto intenta evitar dejar IOCs simples en memoria que apunten a memoria de ntdll modificada.
  4. En cuanto Beacon intenta dormir, nuestro callback MySleep es invocado.
  5. La asignación de memoria de Beacon se cifra y su protección se cambia a RW
  6. Luego desenganchamos el kernel32!Sleep original para evitar dejar un IOC simple en memoria que indique que Sleep ha sido modificado con trampolín (enganche en línea).
  7. Se realiza una llamada al ::Sleep original para permitir que Beacon duerma mientras espera más comunicación.
  8. Después de que Sleep termina, desciframos los datos de nuestro shellcode, devolvemos sus protecciones de memoria a RX y luego re-enganchamos para asegurar la intercepción del siguiente sueño.

La fluctuación a PAGE_NOACCESS funciona de la siguiente manera

  1. Leer el contenido del shellcode desde un archivo.
  2. Enganchar kernel32!Sleep apuntando de vuelta a nuestro callback.
  3. Inyectar y lanzar el shellcode mediante VirtualAlloc + memcpy + CreateThread ...
  4. Inicializar un Vectored Exception Handler (VEH) para configurar nuestro propio manejador que capturará las excepciones de Access Violation.
  5. En cuanto Beacon intenta dormir, nuestro callback MySleep es invocado.
  6. La asignación de memoria de Beacon se cifra y su protección se cambia a PAGE_NOACCESS
  7. Luego desenganchamos el kernel32!Sleep original para evitar dejar un IOC simple en memoria que indique que Sleep ha sido modificado con trampolín (enganche en línea).
  8. Se realiza una llamada al ::Sleep original para permitir que Beacon duerma mientras espera más comunicación.
  9. Después de que Sleep termina, re-enganchamos kernel32!Sleep para asegurar la intercepción del siguiente sueño.
  10. El shellcode entonces intenta reanudar su ejecución, lo que resulta en un Access Violation ya que sus páginas están marcadas como NoAccess.

No es una técnica novedosa

La técnica no es nueva, no es algo que haya ideado yo mismo. Meramente una implementación que muestra el concepto y su utilización práctica para permitir que nuestra comunidad de Seguridad Ofensiva se ponga al día con lo que ofrecen los frameworks C2 comerciales.

De hecho, me introdujeron a la idea de cambiar la protección de memoria del shellcode hace un par de años a través del trabajo de Josh Lospinoso en su increíble Gargoyle.

Aquí hay más contexto:

  • gargoyle, una técnica de evasión de escaneo de memoria
  • Bypassing Memory Scanners with Cobalt Strike and Gargoyle

Gargoyle lleva el concepto de shellcode auto-consciente y auto-fluctuante mucho más lejos, aprovechando una secuencia ROP que llama a VirtualProtect. Sin embargo, la técnica es impresionante, pero es igualmente difícil aprovecharla con Cobalt Strike's Beacon sin tener que matar su hilo y mantener la reinicialización de Beacon en memoria.

Eso está lejos de ser perfecto, sin embargo, ya que operamos desde el terreno de nuestro propio proceso cargador de auto-inyección, podemos hacer lo que queramos con el entorno en el que opera el shellcode y ocultarlo como nos plazca. Esta técnica (y la anterior, ThreadStackSpoofer) muestra las ventajas de ejecutar nuestros shellcodes de esta manera.

La implementación de la fluctuación a PAGE_NOACCESS está inspirada en el trabajo de ORCA666 presentado en su https://github.com/ORCA666/0x41 inyector. Él demostró que:

  1. podemos inicializar un manejador de excepciones vectorizado (VEH),
  2. cambiar las páginas del shellcode a sin acceso
  3. y luego capturar las excepciones de Access Violation que ocurrirán tan pronto como el shellcode quiera reanudar su ejecución y descifrar + devolver sus páginas de memoria a Lectura+Ejecución.

Esta implementación contiene esta idea implementada, disponible con la opción 2 en <fluctuate>. Asegúrate de revisar también sus otros proyectos.


Demo

La herramienta ShellcodeFluctuation acepta tres parámetros: el primero es la ruta al shellcode y el segundo es el modificador de nuestra funcionalidad.``` Usage: ShellcodeFluctuation.exe : -1 - Read shellcode but dont inject it. Run in an infinite loop. 0 - Inject the shellcode but don't hook kernel32!Sleep and don't encrypt anything 1 - Inject shellcode and start fluctuating its memory with standard PAGE_READWRITE. 2 - Inject shellcode and start fluctuating its memory with ORCA666's PAGE_NOACCESS.

root@kitploit:~
### Moneta (aparentemente) falso positivo```
C:\> ShellcodeFluctuation.exe beacon64.bin -1

Entonces primero veremos qué piensa el escáner Moneta64 sobre el proceso que no hace nada sospechoso y simplemente recurre a ejecutar un bucle infinito:

moneta false positive

Como podemos ver, hay algún falso positivo (al menos así lo considero yo) que supuestamente detecta Mismatching PEB module / Phantom image. Los límites de memoria apuntan al propio módulo ShellcodeFluctuate.exe y podrían indicar que este módulo, aunque sea de tipo MEM_IMAGE, no está enlazado en el PEB del proceso, lo cual es inusual y suena bastante extraño. La razón de este IOC no me consta y no intenté entenderla mejor, pero no es algo que debamos preocuparnos realmente.

Si alguien sabe cuál es el motivo de esta detección, ¡me encantaría saberlo! Por favor, no dudes en contactar.

Beacon no cifrado```

C:> ShellcodeFluctuation.exe beacon64.bin 0

root@kitploit:~
El segundo caso de uso presenta los IOCs de memoria de un Beacon operando dentro de nuestro proceso, que no utiliza ningún tipo de `Artifact Kits` personalizados, `User-Defined Reflective Loaders` (como mi [`ElusiveMice`](https://github.com/mgeeky/ElusiveMice)), ni ninguna acción inicial que pudiera estropear nuestros resultados.

![moneta not encrypted](https://assets.kitploit.com/production/public/readmes/50718/6a4e3a230a362c25da6f4aa6955b822d2a83215848c1bc09566a27ea9db653c9/dd2e0560a688886c0fe06debe92f153e129daa6654cb17c2976edee8661e3bd3-display-v1.webp)

Podemos ver que `Moneta64` reconoce correctamente `Abnormal private executable memory` apuntando a la ubicación donde reside nuestro shellcode.
Ese es un IOC de memoria realmente fuerte que expone nuestro shellcode para que sea volcado y analizado por escáneres automatizados. No es nada bueno.

### Beacon cifrado con protecciones RW```
C:\> ShellcodeFluctuation.exe beacon64.bin 1

Ahora el tercer caso de uso, el más interesante desde la perspectiva de esta implementación, es el Beacon fluctuante.

moneta encrypted

Aparte del primer IOC, considerado un tanto falso positivo, vemos uno nuevo que indica que la memoria de kernel32.dll fue modificada. Sin embargo, esta vez no hay ningún IOC Abnormal private executable memory. Nuestra fluctuación (cifrado/descifrado repetido y alternancia de protecciones de memoria) está activa.

Y para que conste, pe-sieve también detecta PE implantado cuando se usa con la opción /data 3 (a menos que se dé esta opción, no se realizará ninguna detección):

pe-sieve

Mi suposición actual es que PE-Sieve está detectando los mismos rasgos que Moneta (descritos más abajo en Código modificado en kernel32.dll) - el hecho de que el módulo PE mapeado tiene un Working set no vacío, siendo una evidencia clara de inyección de código de algún tipo. Eso se etiqueta como Implanted PE / Implanted. Si ese es el caso, la conclusión es similar a la observación de Moneta. No creo que debamos preocuparnos demasiado por ese IOC en cuanto a detección.

Actualmente no se me ocurre mejor opción para interceptar la ejecución del shellcode en medio (hablando ahora de Cobalt Strike), que enganchar kernel32!Sleep. Por lo tanto, estamos obligados a dejar este tipo de IOCs.

Pero oye, todavía ninguno de los bytes difiere en comparación con lo que hay en el sistema de archivos (C:\Windows\System32\kernel32.dll) y ninguna función está enganchada, ¿qué pasa? 😉

Beacon cifrado con protecciones PAGE_NOACCESS```

C:> ShellcodeFluctuation.exe beacon64.bin 2

root@kitploit:~
![no-access](https://assets.kitploit.com/production/public/readmes/50718/03f80df765f37efb3242dce12c613091ab79896e584fbfc2a309a1295c4544c6/327fe5cc3e3ebe6db8277bd091361f7ae42ee4925e21aa87cfa9287b404a1ab5-display-v1.webp)

Eso hará que el shellcode fluctúe entre páginas `RX` y `NA` de manera efectiva.

Por el momento no estoy seguro de los beneficios de cambiar a `PAGE_NOACCESS` en lugar de `PAGE_READWRITE`.

### Código modificado en kernel32.dll

Entonces, ¿qué hay de ese IOC `kernel32` modificado?

Ahora, intentemos llegar al fondo de este IOC y veamos de qué se trata.

En primer lugar, volcaremos la región de memoria mencionada: la sección `.text` (código) de `kernel32.dll`. Usemos `ProcessHacker` para ese propósito a fin de utilizar herramientas públicas conocidas y estables:

![dump-kernel](https://assets.kitploit.com/production/public/readmes/50718/0b1a4700514b15ec5199ead8f09ccd7c4e5fefc2302a9a9eee0d4e6d77ea48b4/bae9be0ce4bdcede99f235f42431b159bbbf35539f36fe58906fe991e4aacdb4-display-v1.webp)

Volcamos la sección de código del kernel32 supuestamente modificado y luego hacemos lo mismo con el kernel32 que se ejecuta en el proceso que no modificó esa área.

Una vez obtenidos los dos volcados, podemos compararlos byte a byte (usando mi [expdevBadChars](https://github.com/mgeeky/expdevBadChars)) para buscar cualquier inconsistencia:

![bindiff](https://assets.kitploit.com/production/public/readmes/50718/4df33e426c7d23554953e2117e3706ee9af1b53b3dd4a60f7b05bcabb988bc85/3db05a8375ded834d576d29083dab9b646cbd83b791a591717fbe0e56ca9a64e-display-v1.webp)

Solo para ver que coinciden entre sí. Claramente no hay ni un solo byte modificado en `kernel32.dll`, y la razón es que estamos desenganchando `kernel32!Sleep` antes de invocarlo:

`main.cpp:31:````
    HookTrampolineBuffers buffers = { 0 };
    buffers.originalBytes = g_hookedSleep.sleepStub;
    buffers.originalBytesSize = sizeof(g_hookedSleep.sleepStub);

    //
    // Unhook kernel32!Sleep to evade hooked Sleep IOC. 
    // We leverage the fact that the return address left on the stack will make the thread
    // get back to our handler anyway.
    //
    fastTrampoline(false, (BYTE*)::Sleep, &MySleep, &buffers);

    // Perform sleep emulating originally hooked functionality.
    ::Sleep(dwMilliseconds);

Entonces, ¿qué está causando que se active el IOC? Inspeccionemos Moneta más de cerca:

moneta

Entrando en el Ioc.cpp de Moneta, justo alrededor de la línea 104 donde reporta el IOC MODIFIED_CODE, podemos modificar un poco el código para exponer mejor el momento exacto en que analiza el pool de kernel32. Ahora:

  1. Se realiza la comprobación para asegurar que la región de kernel32 es ejecutable. Vemos que, de hecho, esa región es ejecutable a = true
  2. Se obtiene la cantidad de memoria privada de ese módulo. Aquí vemos que kernel32 tiene b = 0x1000 bytes privados. ¿Cómo es posible? Debería haber 0.
  3. Si la asignación ejecutable tiene más de 0 bytes de memoria privada (a && b), se reporta el IOC
  4. Y eso es una prueba de que estábamos examinando kernel32 en ese momento.

Cuando el cargador de imágenes de Windows asigna un módulo DLL en el espacio de memoria del proceso, las páginas de memoria subyacentes se etiquetarán como MEM_MAPPED o MEM_IMAGE dependiendo del escenario. Cada vez que modificamos aunque sea un solo byte de la asignación MEM_MAPPED/MEM_IMAGE, el sistema separará una única página de memoria (asumiendo que modificamos menos de PAGE_SIZE bytes y no cruzamos el límite de página) para indicar un fragmento que no se corresponde con la imagen original.

Esta observación se utiliza entonces como un IOC: una imagen no debería tener asignaciones MEM_PRIVATE dentro de su región de memoria (en su interior), porque eso indicaría que algunos bytes fueron modificados en algún momento dentro de esa región. Moneta está detectando correctamente la modificación de código, aunque los bytes coincidieran con los del módulo original en el momento de la comparación.

Para una explicación exhaustiva de cómo funcionan internamente Moneta, la implementación de inyección de procesos y el IOC relacionado, lee los siguientes artículos de gran calidad de Forrest Orr:

  1. Masking Malicious Memory Artifacts – Part I: Phantom DLL Hollowing
  2. Masking Malicious Memory Artifacts – Part II: Blending in with False Positives
  3. Masking Malicious Memory Artifacts – Part III: Bypassing Defensive Scanners

Esa es una investigación y documentación realmente sobresaliente hecha por Forrest, ¡gran trabajo, colega!

Especialmente el segundo artículo describe la justificación de esta detección, tal y como leemos lo que Forrest nos enseña:

En el caso de que el módulo hubiera sido cargado legítimamente y añadido al PEB, el implante de shellcode habría sido detectado igualmente debido a los 0x1000 bytes (1 página) de memoria mapeada de forma privada en el espacio de direcciones y recuperados por Moneta consultando su working set, lo que resulta en un IOC de código modificado como se ve arriba.

En resumen, estamos dejando un IOC detrás, pero ¿deberíamos preocuparnos por eso? Incluso si hay un IOC, no hay bytes robados visibles, por lo que no hay una referencia inmediata que apunte de vuelta a nuestro shellcode ni que distinga la técnica de nuestro shellcode de otras.

En resumen, no deberíamos preocuparnos realmente por ese IOC. :-)

Pero los frameworks comerciales no dejan IOCs

Se podría decir que esta implementación está lejos de ser perfecta porque deja algo, todavía hay IOCs y los productos comerciales demuestran que no tienen características similares.

Cuando ese argumento está sobre la mesa, debo recordar que los frameworks comerciales tienen control total sobre el código fuente de sus implantes y cargadores de shellcode, por lo que pueden integrarlos bien entre sí para evitar la necesidad de hookear y manipular su propio shellcode. Aquí, necesitamos hookear kernel32!Sleep para interceptar la ejecución del Beacon de Cobalt Strike justo antes de que se duerma, y así continuar con nuestras tareas de mantenimiento. Si hubiera un mecanismo mejor para intervenir sin tener que hookear Sleep, sería perfecto.

Sin embargo, existe el concepto de Sleep Mask introducido en Cobalt Strike; las restricciones de tamaño, al ser de cientos de bytes, nos impiden totalmente introducir esta lógica en la propia máscara (de lo contrario, tampoco tendríamos que hookear Sleep, sin dejar IOCs, igual que hacen los productos comerciales).

Otro argumento podría ser que los frameworks comerciales integran este tipo de lógica en sus Reflective Loaders, mientras que aquí la dejamos en el harness EXE. Eso es cierto, pero la razón de esta decisión es doble:

  1. Necesito ser muy cuidadoso al publicar este tipo de tecnología para evitar el riesgo de ayudar a criminales del mundo real a convertir en arma una implementación que nos persiga de nuevo con otro Petya. Por eso, decidí omitir algunos de los detalles más crudos que uso en mis herramientas profesionales para llevar a cabo ejercicios comerciales contratados de Adversary Simulation. Al entregar la semilla, espero que se encuentre con profesionales de la comunidad capaces de hacer crecer el concepto en sus propias herramientas, asumiendo que tengan las habilidades apropiadas.

  2. Preferiría con creces mover toda esta lógica al User-Defined Reflective Loader de Cobalt Strike, facilitando a los grupos de Red Team mayores probabilidades en su fase de entrega. Pero en primer lugar, véase el punto (1); en segundo lugar, esa tecnología está actualmente limitada a 5 KB para sus RDLL, lo que me impide por completo implementarla también ahí. Para aquellos de nosotros que construimos C2 e implantes personalizados para ejercicios internos de Adversary Simulation, ahora han recibido una implementación de muestra que sin duda les ayudará a embellecer sus herramientas en consecuencia.


¿Cómo lo uso?

Mira el código y su implementación, comprende el concepto y re-implementa el concepto dentro de tus propios Shellcode Loaders que utilizas para llevar a cabo tus compromisos de Red Team. Esta es otra técnica más de evasión avanzada en memoria que aumenta las probabilidades de que tu equipo no sea detectado por antivirus, EDRs y analistas de malware que examinan tus implantes.

Mientras desarrollas tu cargador de shellcode avanzado, también podrías querer implementar:

  • Cifrado del Heap del Proceso - inspírate en esta entrada de blog: Hook Heaps and Live Free - que puede permitirte evadir extractores de configuración de Beacon como BeaconEye
  • Spoofea la pila de llamadas de tu hilo antes de dormir (eso podría evadir escáneres que intentan examinar los hilos del proceso y sus pilas de llamadas en un intento de cazar asignaciones de memoria MEM_PRIVATE referenciadas por estos hilos)
  • Elimina cualquier resto del Reflective Loader para evitar detecciones por firmas en memoria
  • Desengancha todo lo que puedas haber enganchado (como AMSI, ETW, WLDP) antes de dormir y vuelve a engancharlo después.

Ejemplo de ejecución

Caso de uso:``` Usage: ShellcodeFluctuation.exe : -1 - Read shellcode but dont inject it. Run in an infinite loop. 0 - Inject the shellcode but don't hook kernel32!Sleep and don't encrypt anything 1 - Inject shellcode and start fluctuating its memory with standard PAGE_READWRITE. 2 - Inject shellcode and start fluctuating its memory with ORCA666's PAGE_NOACCESS.

root@kitploit:~
Donde:
- `<shellcode>` es una ruta al archivo de shellcode
- `<fluctuate>` como se describió anteriormente, toma `-1`, `0` o `1`


Ejemplo de ejecución que falsifica la pila de llamadas del hilo del beacon:```
C:\> ShellcodeFluctuation.exe ..\..\tests\beacon64.bin 1

[.] Reading shellcode bytes...
[.] Hooking kernel32!Sleep...
[.] Injecting shellcode...
[+] Shellcode is now running. PID = 9456
[+] Fluctuation initialized.
    Shellcode resides at 0x000002210C091000 and occupies 176128 bytes. XOR32 key: 0x1e602f0d
[>] Flipped to RW. Encoding...

===> MySleep(5000)

[.] Decoding...
[>] Flipped to RX.
[>] Flipped to RW. Encoding...

===> MySleep(5000)

Advertencia

Si planeas añadir esta funcionalidad a tus propios cargadores de shellcode / herramientas, asegúrate de EVITAR desenganchar kernel32.dll. Un intento de desenganchar kernel32 restaurará la funcionalidad original de Sleep, impidiendo que se llame a nuestro callback. Si nuestro callback no se llama, el hilo no podrá falsificar su propia pila de llamadas por sí mismo.

Si eso es lo que quieres, entonces podrías necesitar ejecutar otro hilo de vigilancia (watchdog), asegurándote de que el hilo de Beacons se falsifique cada vez que duerme.

Si estás usando Cobalt Strike y un BOF unhook-bof de Raphael's Mudge, asegúrate de revisar mi Pull Request que añade un parámetro opcional al BOF que especifica las bibliotecas que no deben desengancharse.

De esta manera puedes mantener tus hooks en kernel32:

---``` beacon> unhook kernel32 [*] Running unhook. Will skip these modules: wmp.dll, kernel32.dll [+] host called home, sent: 9475 bytes [+] received output: ntdll.dll <.text> Unhook is done.

root@kitploit:~
[Modificado `unhook-bof` con opción para ignorar módulos especificados](https://github.com/mgeeky/unhook-bof)

---

## Nota final

Este PoC fue diseñado para funcionar con los shellcodes de Beacon de Cobalt Strike. Se sabe que Beacon llama a `kernel32!Sleep` para esperar más instrucciones de su C2. 
Este loader aprovecha ese hecho enganchando `Sleep` para realizar su mantenimiento interno. 

Esta implementación podría no funcionar con otros shellcodes del mercado (como _Meterpreter_) si no usan `Sleep` para hacer una pausa. 
Dado que esto es meramente una _Prueba de Concepto_ que muestra la técnica, no tengo intención de añadir soporte para ningún otro framework C2.

Cuando entiendas el concepto, seguramente podrás trasladarlo a los requisitos de tu shellcode y adaptar la solución en tu beneficio.

Por favor, no abras issues de Github relacionadas con "este código no funciona con el shellcode XYZ", se cerrarán de inmediato.

---

### ☕ Muestra tu apoyo ☕

Este y otros proyectos son el resultado de noches en vela y **mucho trabajo duro**. Si te gusta lo que hago y aprecias que siempre devuelvo algo a la comunidad,
[Considera invitarme a un café](https://github.com/sponsors/mgeeky) _(o mejor una cerveza)_ ¡solo para decirte gracias! 💪 

---

## Autor```   
   Mariusz Banach / mgeeky, 21
   <mb [at] binary-offensive.com>
   (https://github.com/mgeeky)
Descargar herramienta
kernel32!Sleep
  • Nuestro manejador VEH captura la excepción, descifra y devuelve las protecciones de memoria a RX y el shellcode se reanuda.