Skip to content
KitploitKITPLOIT
HerramientasExploitsBlog
Log in
Enviar
HerramientasExploitsBlog
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
ThreadStackSpoofer — Thread Stack Spoofing - PoC de una técnica avanzada de evasión en memoria que permite ocultar mejor la asignación de memoria del shellcode inyectado de los escáneres y analistas. | Kitploit
Herramientas/GitHubGitHub/mgeeky/threadstackspoofer
Frameworks de Pruebas de PenetraciónFrameworks de ExploitsForensia de MemoriaShellcodeAnálisis de MalwareRed TeamingDesarrollo de Payloads
GitHubmgeeky/threadstackspoofer

ThreadStackSpoofer

Thread Stack Spoofing - PoC de una técnica avanzada de evasión en memoria que permite ocultar mejor la asignación de memoria del shellcode inyectado de los escáneres y analistas.

Ver Repositorio
1.2k19219hace 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

Thread Stack Spoofing / Call Stack Spoofing PoC

Una implementación PoC para una técnica avanzada de evasión en memoria que suplanta la pila de llamadas de un hilo. Esta técnica permite eludir reglas de examen de memoria basadas en hilos y ocultar mejor los shellcodes mientras están en memoria del proceso.

Introducción

Esta es una implementación de ejemplo para la técnica Thread Stack Spoofing con el objetivo de evadir analistas de malware, AV y EDR que buscan referencias a los marcos del shellcode en la pila de llamadas de un hilo examinado. La idea es ocultar las referencias al shellcode en la pila de llamadas del hilo, disfrazando así las asignaciones que contienen el código del malware.

Esta implementación, junto con mi ShellcodeFluctuation, ofrece a la comunidad de Seguridad Ofensiva implementaciones de ejemplo para ponerse al día con lo que ofrecen los productos C2 comerciales, para que podamos hacerlo igual de bien en nuestras herramientas de Red Team. 💪

La implementación ha cambiado

La implementación actual difiere mucho de lo publicado originalmente. Esto se debe a que me di cuenta de que existe una forma mucho más simple de terminar el procesamiento de la pila de llamadas del hilo y ocultar los marcos relacionados con el shellcode simplemente escribiendo 0 en la dirección de retorno del primer marco que controlamos:

void WINAPI MySleep(DWORD _dwMilliseconds)
{
    [...]
    auto overwrite = (PULONG_PTR)_AddressOfReturnAddress();
    const auto origReturnAddress = *overwrite;
    *overwrite = 0;

    [...]
    *overwrite = origReturnAddress;
}

La implementación anterior, que utilizaba StackWalk64, se puede consultar en este commit c250724.

Esta implementación es mucho más estable y funciona bien tanto en Debug como en Release bajo las dos arquitecturas: x64 y x86.

Demo

Así es como se puede ver una pila de llamadas cuando NO está suplantada:

no suplantada

Y así, cuando la suplantación de la pila del hilo está activada:

suplantada

Arriba podemos ver que el último marco en nuestra pila de llamadas es nuestro callback MySleep. Cabe preguntarse si esto ofrece inmediatamente nuevas oportunidades de IOCs. Las reglas de caza pueden buscar hilos cuyas pilas de llamadas no se desenrollen hasta los siguientes puntos de entrada de hilo esperados que se encuentran en las bibliotecas del sistema:

kernel32!BaseThreadInitThunk+0x14
ntdll!RtlUserThreadStart+0x21

Sin embargo, la pila de llamadas del hilo suplantado puede parecer extraña al principio; un breve examen de mi sistema mostró que también hay otros hilos que no se desenrollan hasta los puntos de entrada anteriores:

pila de llamadas legítima

La captura de pantalla anterior muestra un hilo de Total Commander x64 sin modificar. Como podemos ver, su pila de llamadas se asemeja bastante a la nuestra en términos de los marcos iniciales de la pila de llamadas.

¿Por qué deberíamos preocuparnos por falsificar cuidadosamente nuestra pila de llamadas cuando hay procesos que muestran características que simplemente podemos imitar?

¿Cómo funciona?

El algoritmo aproximado es el siguiente:

  1. Leer el contenido del shellcode desde un archivo.
  2. Obtener todos los punteros de función necesarios de dbghelp.dll, llamar a SymInitialize.
  3. Enganchar kernel32!Sleep apuntando de vuelta a nuestro callback.
  4. Inyectar y lanzar el shellcode mediante VirtualAlloc + memcpy + CreateThread. El hilo debe comenzar desde nuestra función runShellcode para evitar que la StartAddress del hilo apunte a algún lugar inesperado y anómalo (como ntdll!RtlUserThreadStart+0x21).
  5. Tan pronto como Beacon intente dormir, se invoca nuestro callback MySleep.
  6. Luego sobrescribimos la última dirección de retorno en la pila con 0, lo que efectivamente debería finalizar la pila de llamadas.
  7. Finalmente, se realiza una llamada a ::SleepEx para permitir que Beacon duerma mientras espera más comunicaciones.
  8. Después de que Sleep termina, restauramos las direcciones de retorno originales de la función previamente guardadas y se reanuda la ejecución.

Las direcciones de retorno de las funciones están dispersas por toda el área de memoria de la pila del hilo, apuntadas por el registro RBP/EBP. Para encontrarlas en la pila, primero necesitamos recolectar los punteros de marco y luego desreferenciarlos para sobrescribirlos:

marco de pila

(la imagen anterior fue tomada del artículo de Eli Bendersky titulado Stack frame layout on x86-64)

	*(PULONG_PTR)(frameAddr + sizeof(void*)) = Fake_Return_Address;

La implementación inicial de ThreadStackSpoofer hacía esto en las funciones walkCallStack y spoofCallStack, pero la implementación actual muestra que estos esfuerzos no son necesarios para mantener una pila de llamadas sigilosa.

Ejemplo de ejecución

Uso:

C:\> ThreadStackSpoofer.exe <shellcode> <spoof>

Donde:

  • <shellcode> es una ruta al archivo shellcode
  • <spoof> cuando sea 1 o true habilitará la suplantación de la pila del hilo, cualquier otra cosa la deshabilita.

Ejemplo de ejecución que suplanta la pila de llamadas del hilo de beacon:

PS D:\dev2\ThreadStackSpoofer> .\x64\Release\ThreadStackSpoofer.exe .\tests\beacon64.bin 1
[.] Leyendo bytes del shellcode...
[.] Enganchando kernel32!Sleep...
[.] Inyectando shellcode...
[+] El shellcode ahora se está ejecutando.
[>] Dirección de retorno original: 0x1926747bd51. Finalizando la pila de llamadas...

===> MySleep(5000)

[<] Restaurando dirección de retorno original...
[>] Dirección de retorno original: 0x1926747bd51. Finalizando la pila de llamadas...

===> MySleep(5000)

[<] Restaurando dirección de retorno original...
[>] Dirección de retorno original: 0x1926747bd51. Finalizando la pila de llamadas...

¿Cómo lo uso?

Mira el código y su implementación, comprende el concepto y vuelve a implementar el concepto dentro de tus propios cargadores de shellcode que utilizas para llevar a cabo tus compromisos de Red Team. Esta es otra técnica para la evasión avanzada en memoria que aumenta las posibilidades de tu equipo de no ser detectado por antivirus, EDR y analistas de malware que examinan tus implantes.

Al desarrollar tu cargador de shellcode avanzado, también podrías querer implementar:

  • Cifrado del Heap del Proceso - inspírate en esta publicación de blog: Hook Heaps and Live Free - que puede permitirte evadir extractores de configuración de Beacon como BeaconEye
  • Cambiar la protección de las páginas de memoria de tu Beacon a RW (desde RX/RWX) y cifrar su contenido - utilizando la técnica de Shellcode Fluctuation - justo antes de dormir (lo que podría evadir escáneres como Moneta o pe-sieve)
  • Limpiar cualquier sobrante del cargador reflectante para evitar detecciones de firmas en memoria
  • Desenganchar todo lo que hayas enganchado (como AMSI, ETW, WLDP) antes de dormir y luego volver a enganchar después.

Descargar herramienta