Skip to content
KitploitKITPLOIT
OutilsExploitsBlog
Log in
Soumettre
OutilsExploitsBlog
Soumettre

Outils de Hacking, PenTest et Cybersécurité pour votre Arsenal de Sécurité !

Kitploit est un répertoire d'outils de hacking, de cybersécurité et de pentesting. Découvrez les dernières mises à jour des projets pour trouver des vulnérabilités, analyser des systèmes, automatiser les tests et renforcer votre sécurité.

··Flux·Contact·Confidentialité·© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
ThreadStackSpoofer — Thread Stack Spoofing - PoC pour une technique avancée d'évasion en mémoire permettant de mieux cacher l'allocation mémoire du shellcode injecté aux scanners et analystes. | Kitploit
Outils/GitHubGitHub/mgeeky/threadstackspoofer
Frameworks de Tests d'IntrusionFrameworks d'ExploitationCriminalistique MémoireShellcodeAnalyse de MalwareRed TeamingDéveloppement de Charges Utiles
GitHubmgeeky/threadstackspoofer

ThreadStackSpoofer

Thread Stack Spoofing - PoC pour une technique avancée d'évasion en mémoire permettant de mieux cacher l'allocation mémoire du shellcode injecté aux scanners et analystes.

Voir le dépôt
1.2k19219il y a 4 ansVérifié par Kitploit

Populaires

Voir tout →

Découvrez les outils les plus utilisés par notre communauté.

Explorer tous les outils

Parcourez notre collection d'outils

Voir tous les outils →
Partager

Preuve de concept de Thread Stack Spoofing / Call Stack Spoofing

Une implémentation de preuve de concept pour une technique avancée d'évasion en mémoire qui usurpe la pile d'appels du thread (Thread Call Stack). Cette technique permet de contourner les règles d'examen de la mémoire basées sur les threads et de mieux cacher les shellcodes en mémoire intra-processus.

Introduction

Ceci est un exemple d'implémentation pour la technique Thread Stack Spoofing visant à contourner les analystes de malwares, les AV et les EDR qui recherchent des références aux frames du shellcode dans la pile d'appels d'un thread examiné. L'idée est de masquer les références au shellcode sur la pile d'appels du thread, dissimulant ainsi les allocations contenant le code du malware.

Cette implémentation, associée à mon projet ShellcodeFluctuation, apporte à la communauté de la sécurité offensive des implémentations d'exemples pour rattraper l'offre faite par les produits C2 commerciaux, afin que nous ne fassions pas moins bien dans nos outils Red Team. 💪

L'implémentation a changé

L'implémentation actuelle diffère considérablement de ce qui a été publié initialement. Cela est dû au fait que j'ai réalisé qu'il existe une approche bien plus simple pour terminer le traitement de la pile d'appels du thread et masquer les frames liées au shellcode en écrivant simplement 0 dans l'adresse de retour de la première frame que nous contrôlons :

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

    [...]
    *overwrite = origReturnAddress;
}

L'implémentation précédente, utilisant StackWalk64, est accessible dans ce commit c250724.

Cette implémentation est beaucoup plus stable et fonctionne parfaitement à la fois en Debug et Release sous les deux architectures - x64 et x86.

Demo

Voici à quoi peut ressembler une pile d'appels lorsqu'elle N'EST PAS usurpée :

not-spoofed

Ceci, en revanche, lorsque l'usurpation de la pile de thread est activée :

spoofed

Ci-dessus, nous pouvons voir que la dernière frame de notre pile d'appels est notre callback MySleep. On peut se demander si cela apporte immédiatement de nouveaux IOCs ? Les règles de chasse peuvent rechercher des threads dont la pile d'appels ne se déroule pas jusqu'aux points d'entrée de thread attendus suivants, situés dans les bibliothèques système :

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

Cependant, la pile d'appels du thread usurpé peut sembler plutôt étrange au premier abord ; un bref examen de mon système a montré qu'il existe d'autres threads qui ne se déroulent pas non plus jusqu'aux points d'entrée ci-dessus :

legit call stack

La capture d'écran ci-dessus montre un thread de Total Commander x64 non modifié. Comme nous pouvons le voir, sa pile d'appels ressemble beaucoup à la nôtre en termes de frames initiales de la pile.

Pourquoi devrions-nous nous soucier de falsifier soigneusement notre pile d'appels alors qu'il existe des processus présentant des caractéristiques que nous pouvons simplement imiter ?

Comment ça fonctionne ?

L'algorithme approximatif est le suivant :

  1. Lire le contenu du shellcode depuis un fichier.
  2. Acquérir tous les pointeurs de fonction nécessaires depuis dbghelp.dll, appeler SymInitialize
  3. Hooker kernel32!Sleep en pointant vers notre callback.
  4. Injecter et lancer le shellcode via VirtualAlloc + memcpy + CreateThread. Le thread doit démarrer à partir de notre fonction runShellcode pour éviter que l'adresse de démarrage du thread pointe vers un endroit inattendu et anormal (comme ntdll!RtlUserThreadStart+0x21)
  5. Dès que Beacon tente de dormir, notre callback MySleep est invoquée.
  6. Nous écrasons ensuite la dernière adresse de retour sur la pile avec 0, ce qui devrait effectivement terminer la pile d'appels.
  7. Enfin, un appel à ::SleepEx est effectué pour laisser Beacon dormir en attendant une communication ultérieure.
  8. Une fois le sommeil terminé, nous restaurons les adresses de retour originales des fonctions précédemment sauvegardées et l'exécution reprend.

Les adresses de retour des fonctions sont dispersées dans toute la zone mémoire de la pile du thread, pointées par le registre RBP/EBP. Pour les trouver sur la pile, nous devons d'abord collecter les pointeurs de frame, puis les déréférencer pour les écraser :

stack frame

(l'image ci-dessus est empruntée au billet d'Eli Bendersky intitulé Stack frame layout on x86-64)

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

L'implémentation initiale de ThreadStackSpoofer faisait cela dans les fonctions walkCallStack et spoofCallStack, mais l'implémentation actuelle montre que ces efforts ne sont pas nécessaires pour maintenir une pile d'appels furtive.

Exemple d'exécution

Utilisation :

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

Où :

  • <shellcode> est un chemin vers le fichier shellcode
  • <spoof> quand 1 ou true active l'usurpation de la pile de thread, toute autre valeur la désactive.

Exemple d'exécution qui usurpe la pile d'appels du thread de beacon :

PS D:\dev2\ThreadStackSpoofer> .\x64\Release\ThreadStackSpoofer.exe .\tests\beacon64.bin 1
[.] Reading shellcode bytes...
[.] Hooking kernel32!Sleep...
[.] Injecting shellcode...
[+] Shellcode is now running.
[>] Original return address: 0x1926747bd51. Finishing call stack...

===> MySleep(5000)

[<] Restoring original return address...
[>] Original return address: 0x1926747bd51. Finishing call stack...

===> MySleep(5000)

[<] Restoring original return address...
[>] Original return address: 0x1926747bd51. Finishing call stack...

Comment l'utiliser ?

Regardez le code et son implémentation, comprenez le concept et réimplémentez-le dans vos propres chargeurs de shellcode que vous utilisez pour mener vos engagements Red Team. C'est une technique supplémentaire d'évasion avancée en mémoire qui augmente les chances de vos équipes de ne pas être détectées par les antivirus, les EDR et les analystes de malwares qui examinent vos implants.

Lors du développement de votre chargeur de shellcode avancé, vous pourriez également vouloir implémenter :

Télécharger l’outil