Skip to content
KitploitKITPLOIT
StrumentiExploitsBlog
Log in
Invia
StrumentiExploitsBlog
Invia

Strumenti di Hacking, PenTest e Cybersecurity per il tuo Arsenale di Sicurezza!

Kitploit è una directory di strumenti di hacking, cybersecurity e pentesting. Scopri gli ultimi aggiornamenti dei progetti per trovare vulnerabilità, analizzare sistemi, automatizzare i test e rafforzare la tua sicurezza.

··Feed·Contatto·Privacy·© 2026 Kitploit

Directory degli strumenti

Categorie

Vedi tutte le categorie
Loading categories
ThreadStackSpoofer — Thread Stack Spoofing - PoC per una tecnica avanzata di evasione in-memory che permette di nascondere meglio l'allocazione di memoria dello shellcode iniettato da scanner e analisti. | Kitploit
Strumenti/GitHubGitHub/mgeeky/threadstackspoofer
Frameworks per Penetration TestingFramework di ExploitMemory ForensicsShellcodeAnalisi MalwareRed TeamingSviluppo Payload
GitHubmgeeky/threadstackspoofer

ThreadStackSpoofer

Thread Stack Spoofing - PoC per una tecnica avanzata di evasione in-memory che permette di nascondere meglio l'allocazione di memoria dello shellcode iniettato da scanner e analisti.

Vedi Repository
1.2k192194 anni faRevisionato da Kitploit

Più Popolari

Vedi tutti →

Scopri gli strumenti più utilizzati dalla nostra community.

Esplora tutti gli strumenti

Sfoglia la nostra collezione di strumenti

Vedi tutti gli strumenti →
Condividi

Thread Stack Spoofing / Call Stack Spoofing PoC

Una implementazione PoC per una tecnica avanzata di evasione in-memory che falsifica lo Stack dei Thread. Questa tecnica permette di bypassare le regole di esame della memoria basate sui thread e nascondere meglio gli shellcode mentre sono in memoria di processo.

Introduzione

Questa è un'implementazione d'esempio per la tecnica Thread Stack Spoofing che mira a eludere Analisti Malware, AV e EDR che cercano riferimenti ai frame dello shellcode nella call stack di un thread esaminato. L'idea è nascondere i riferimenti allo shellcode sulla call stack del thread, mascherando così le allocazioni che contengono il codice del malware.

Questa implementazione, insieme al mio ShellcodeFluctuation, fornisce alla comunità Offensive Security implementazioni di esempio per recuperare il terreno rispetto all'offerta dei prodotti C2 commerciali, in modo da non essere da meno nei nostri tooling Red Team. 💪

L'implementazione è cambiata

L'implementazione attuale differisce pesantemente da quella originariamente pubblicata. Questo perché ho realizzato che esiste un approccio molto più semplice per terminare l'elaborazione della call stack del thread e nascondere i frame relativi allo shellcode, semplicemente scrivendo 0 all'indirizzo di ritorno del primo frame che controlliamo:

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

    [...]
    *overwrite = origReturnAddress;
}

La precedente implementazione, che utilizzava StackWalk64, è accessibile in questo commit c250724.

Questa implementazione è molto più stabile e funziona bene sia in Debug che in Release su due architetture - x64 e x86.

Demo

Ecco come potrebbe apparire una call stack quando NON è falsificata:

not-spoofed

Questa, invece, quando la falsificazione dello stack del thread è abilitata:

spoofed

Sopra possiamo vedere che l'ultimo frame sulla nostra call stack è la nostra callback MySleep. Ci si potrebbe chiedere se ciò porti immediatamente a nuovi IOC? Le regole di caccia possono cercare thread con call stack che non si srotolano nei seguenti punti di ingresso attesi del thread, situati nelle librerie di sistema:

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

Tuttavia la call stack del thread falsificato potrebbe sembrare strana a prima vista; un breve esame del mio sistema ha mostrato che ci sono anche altri thread che non si srotolano fino ai punti di ingresso sopra:

legit call stack

Lo screenshot sopra mostra un thread di Total Commander x64 non modificato. Come possiamo vedere, la sua call stack assomiglia molto alla nostra in termini di frame iniziali della call stack.

Perché dovremmo preoccuparci di falsificare attentamente la nostra call stack quando ci sono processi che mostrano tratti che possiamo semplicemente imitare?

Come funziona?

L'algoritmo approssimativo è il seguente:

  1. Leggere il contenuto dello shellcode dal file.
  2. Acquisire tutti i puntatori a funzione necessari da dbghelp.dll, chiamare SymInitialize
  3. Agganciare kernel32!Sleep puntando alla nostra callback.
  4. Iniettare e lanciare lo shellcode tramite VirtualAlloc + memcpy + CreateThread. Il thread dovrebbe partire dalla nostra funzione runShellcode per evitare che l'Indirizzo di Inizio del Thread punti in un luogo inaspettato e anomalo (come ntdll!RtlUserThreadStart+0x21).
  5. Non appena Beacon tenta di dormire, la nostra callback MySleep viene invocata.
  6. Quindi sovrascriviamo l'ultimo indirizzo di ritorno sullo stack con 0, che dovrebbe effettivamente terminare la call stack.
  7. Infine viene effettuata una chiamata a ::SleepEx per permettere al Beacon di dormire mentre attende ulteriori comunicazioni.
  8. Dopo che Sleep è terminato, ripristiniamo gli indirizzi di ritorno originali delle funzioni precedentemente salvati e l'esecuzione riprende.

Gli indirizzi di ritorno delle funzioni sono sparsi in tutta l'area di memoria dello stack del thread, puntati dal registro RBP/EBP. Per trovarli sullo stack, dobbiamo prima raccogliere i puntatori ai frame, poi dereferenziarli per sovrascriverli:

stack frame

(l'immagine sopra è stata presa dal post di Eli Bendersky intitolato Stack frame layout on x86-64)

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

L'implementazione iniziale di ThreadStackSpoofer faceva questo nelle funzioni walkCallStack e spoofCallStack, tuttavia l'implementazione attuale mostra che questi sforzi non sono necessari per mantenere una call stack furtiva.

Esempio di esecuzione

Caso d'uso:

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

Dove:

  • <shellcode> è il percorso del file shellcode
  • <spoof> quando è 1 o true abiliterà la falsificazione dello stack del thread, qualsiasi altra cosa la disabilita.

Esempio di esecuzione che falsifica la call stack del thread di beacon:

PS D:\dev2\ThreadStackSpoofer> .\x64\Release\ThreadStackSpoofer.exe .\tests\beacon64.bin 1
[.] Lettura dei byte dello shellcode...
[.] Aggancio di kernel32!Sleep...
[.] Iniezione dello shellcode...
[+] Shellcode ora in esecuzione.
[>] Indirizzo di ritorno originale: 0x1926747bd51. Terminazione della call stack...

===> MySleep(5000)

[<] Ripristino dell'indirizzo di ritorno originale...
[>] Indirizzo di ritorno originale: 0x1926747bd51. Terminazione della call stack...

===> MySleep(5000)

[<] Ripristino dell'indirizzo di ritorno originale...
[>] Indirizzo di ritorno originale: 0x1926747bd51. Terminazione della call stack...

Come lo uso?

Guarda il codice e la sua implementazione, comprendi il concetto e reimplementalo all'interno dei tuoi Loader di Shellcode che usi per le tue attività Red Team. Questa è un'ulteriore tecnica di evasione avanzata in-memory che aumenta le possibilità del tuo Team di non essere scoperto da Antivirus, EDR e Analisti Malware che esaminano i tuoi impianti.

Mentre sviluppi il tuo loader di shellcode avanzato, potresti anche voler implementare:

  • Crittografia dell'Heap del Processo - prendi ispirazione da questo post: Hook Heaps and Live Free - che può permetterti di eludere estrattori di configurazione di Beacon come BeaconEye
  • Cambiare la protezione delle pagine di memoria del tuo Beacon in RW (da RX/RWX) e crittografarne il contenuto - usando la tecnica Shellcode Fluctuation - proprio prima di dormire (che potrebbe eludere scanner come Moneta o pe-sieve)
  • Pulire eventuali residui del Reflective Loader per evitare rilevamenti basati su firme in-memory
  • Sganciare tutto ciò che potresti aver agganciato (come AMSI, ETW, WLDP) prima di dormire e poi riagganciarlo successivamente.

In realtà questa non è (ancora) una vera falsificazione dello stack

Scarica lo strumento