Skip to content
KitploitKITPLOIT
ToolsBlog
Einreichen
ToolsBlog
Einreichen

Hacking-, PenTest- und Cybersicherheits-Tools für Ihr Sicherheitsarsenal!

Kitploit ist ein Verzeichnis von Hacking-, Cybersicherheits- und Pentesting-Tools. Entdecken Sie die neuesten Projekt-Updates, um Schwachstellen zu finden, Systeme zu analysieren, Tests zu automatisieren und Ihre Sicherheit zu stärken.

··Feeds·Kontakt·Datenschutz·© 2026 Kitploit

Tool-Verzeichnis

Kategorien

Alle Kategorien anzeigen
Loading categories
ShellcodeFluctuation — Eine fortschrittliche In-Memory-Evasion-Technik, die den Speicherschutz von Shellcode zwischen RW/NoAccess und RX umschaltet und anschließend dessen Inhalt ver- und entschlüsselt. | Kitploit
Tools/GitHubGitHub/mgeeky/shellcodefluctuation
ShellcodePost-ExploitationRed TeamingPayload-EntwicklungAdversarial-Angriff
GitHubmgeeky/shellcodefluctuation

ShellcodeFluctuation

Eine fortschrittliche In-Memory-Evasion-Technik, die den Speicherschutz von Shellcode zwischen RW/NoAccess und RX umschaltet und anschließend dessen Inhalt ver- und entschlüsselt.

Repository anzeigen
1.1k163vor 4 JahrenVon Kitploit geprüft

Beliebteste

Alle anzeigen →

Entdecken Sie die meistgenutzten Tools unserer Community.

Alle Tools erkunden

Durchsuchen Sie unsere Tool-Sammlung

Alle Tools anzeigen →
Teilen

Shellcode Fluctuation PoC

A PoC implementation for an another in-memory evasion technique that cyclically encrypts and decrypts shellcode's contents to then make it fluctuate between RW (or NoAccess) and RX memory protection. When our shellcode resides in RW or NoAccess memory pages, scanners such as Moneta or pe-sieve will be unable to track it down and dump it for further analysis.

Einführung

Nach der Veröffentlichung von ThreadStackSpoofer habe ich einige Fragen zu folgendem Punkt der README erhalten:

Ändere den Schutz der Speicherseiten deines Beacons auf RW (von RX/RWX) und verschlüssele deren Inhalte vor dem Schlafen (das könnte Scanner wie Moneta oder pe-sieve umgehen)

Zuvor war ich ziemlich sicher, dass die Community bereits weiß, wie sie ihre Payloads verschlüsseln/entschlüsseln und ihre Speicherschutzberechtigungen umstellen kann, um Speicherscanner zu umgehen, die nach anomalen ausführbaren Regionen suchen. Die Fragen haben das Gegenteil bewiesen, also habe ich beschlossen, diesen nicht bewaffneten PoC zu veröffentlichen, um eine weitere Evasion-Strategie zu dokumentieren und der Community eine Beispielimplementierung zur Arbeit anzubieten.

Dieser PoC ist eine Demonstration einer relativ einfachen Technik, die der Offensive-Community bereits bekannt ist (ich bringe hier also wirklich nichts Neues), in der Hoffnung, die Geheimnisse hinter der Magie zu enthüllen, die einige kommerzielle Frameworks zeigen, die ihre Evasion-Fähigkeiten gegen beide zuvor genannten Speicherscanner demonstrieren.

Hier ist ein Vergleich beim Fluktuieren zu RW (eine andere Option ist das Fluktuieren zu PAGE_NOACCESS - unten beschrieben):

  1. Beacon nicht verschlüsselt
  2. Beacon verschlüsselt (fluktuierend)

comparison

Diese Implementierung zusammen mit meinem ThreadStackSpoofer bringt der Offensive-Security-Community Beispielimplementierungen, um mit dem Angebot kommerzieller C2-Produkte gleichzuziehen, damit wir in unseren Red-Team-Tools nicht schlechter abschneiden. 💪


Wie funktioniert es?

Dieses Programm führt eine Selbstinjektion von Shellcode durch (grob über klassisches VirtualAlloc + memcpy + CreateThread). Wenn der Shellcode läuft (diese Implementierung zielt speziell auf Cobalt-Strike-Beacon-Implantate ab), wird eine Windows-Funktion gehookt, die den Moment abfängt, in dem Beacon einschläft: kernel32!Sleep. Immer wenn die gehookte MySleep-Funktion aufgerufen wird, lokalisiert sie die Grenzen ihrer Speicherzuordnung, stellt deren Schutz auf RW um und wendet xor32 auf alle dort gespeicherten Bytes an. Nachdem die erwartete Zeit abgewartet wurde, entschlüsseln wir, wenn der Shellcode zu unserem MySleep-Handler zurückkehrt, die Daten des Shellcodes und stellen den Schutz wieder auf RX.

Fluktuation zu PAGE_READWRITE funktioniert wie folgt

  1. Lies den Inhalt des Shellcodes aus der Datei.
  2. Hooke kernel32!Sleep, sodass er auf unseren Callback zeigt.
  3. Injiziere und starte den Shellcode über VirtualAlloc + memcpy + CreateThread. Im Gegensatz zu dem, was wir in ThreadStackSpoofer hatten, hooken wir hier nichts in ntdll, um unseren Shellcode zu starten, sondern springen stattdessen von unserer eigenen Funktion aus zu ihm. Dies versucht, einfache IOCs im Speicher zu vermeiden, die auf modifizierten ntdll-Speicher hinweisen.
  4. Sobald Beacon versucht zu schlafen, wird unser MySleep-Callback aufgerufen.
  5. Die Speicherzuordnung von Beacon wird verschlüsselt und der Schutz auf RW umgestellt.
  6. Wir entfernen dann den Hook der ursprünglichen kernel32!Sleep-Funktion, um einfache IOCs im Speicher zu vermeiden, die darauf hindeuten, dass Sleep getrampolint (in-line gehooked) wurde.
  7. Ein Aufruf der ursprünglichen ::Sleep-Funktion erfolgt, um Beacon schlafen zu lassen, während auf weitere Kommunikation gewartet wird.
  8. Nachdem der Schlaf beendet ist, entschlüsseln wir die Daten unseres Shellcodes, stellen die Speicherschutzberechtigungen wieder auf und hooken erneut, um die Abfangung nachfolgender Schlafphasen sicherzustellen.

Fluktuation zu PAGE_NOACCESS funktioniert wie folgt

  1. Lies den Inhalt des Shellcodes aus der Datei.
  2. Hooke kernel32!Sleep, sodass er auf unseren Callback zeigt.
  3. Injiziere und starte den Shellcode über VirtualAlloc + memcpy + CreateThread ...
  4. Initialisiere einen Vectored Exception Handler (VEH), um unseren eigenen Handler einzurichten, der Access Violation-Ausnahmen abfängt.
  5. Sobald Beacon versucht zu schlafen, wird unser MySleep-Callback aufgerufen.
  6. Die Speicherzuordnung von Beacon wird verschlüsselt und der Schutz auf PAGE_NOACCESS umgestellt.
  7. Wir entfernen dann den Hook der ursprünglichen kernel32!Sleep-Funktion, um einfache IOCs im Speicher zu vermeiden, die darauf hindeuten, dass Sleep getrampolint (in-line gehooked) wurde.
  8. Ein Aufruf der ursprünglichen ::Sleep-Funktion erfolgt, um Beacon schlafen zu lassen, während auf weitere Kommunikation gewartet wird.
  9. Nachdem der Schlaf beendet ist, hooken wir kernel32!Sleep erneut, um die Abfangung nachfolgender Schlafphasen sicherzustellen.
  10. Der Shellcode versucht dann, seine Ausführung fortzusetzen, was zu einer Access Violation führt, da seine Seiten als NoAccess markiert sind.

Es ist keine neue Technik

Die Technik ist nicht brandneu und nichts, was ich mir selbst ausgedacht habe. Sie ist lediglich eine Implementierung, die das Konzept und seine praktische Nutzung zeigt, damit unsere Offensive-Security-Community mit dem Angebot kommerzieller C2-Frameworks aufholen kann.

Eigentlich wurde ich vor ein paar Jahren durch die Arbeit von Josh Lospinoso in seinem erstaunlichen Gargoyle mit der Idee vertraut gemacht, den Speicherschutz von Shellcode umzustellen.

Hier gibt es weitere Hintergrundinformationen:

  • gargoyle, eine Technik zur Umgehung von Speicherscannern
  • Umgehung von Speicherscannern mit Cobalt Strike und Gargoyle

Gargoyle führt das Konzept von selbstbewusstem und selbstfluktuierendem Shellcode noch weiter, indem es eine ROP-Sequenz nutzt, die VirtualProtect aufruft. Die Technik ist jedoch beeindruckend, aber ebenso schwer mit Cobalt Strikes Beacon einzusetzen, ohne dessen Thread zu beenden und Beacon während des Betriebs im Speicher immer wieder neu zu initialisieren.

Das ist alles andere als perfekt, aber da wir bereits von den Grundlagen unseres eigenen Selbstinjektions-Loader-Prozesses aus operieren, können wir mit der Umgebung, in der der Shellcode arbeitet, machen, was wir wollen, und ihn verbergen, wie wir möchten. Diese Technik (und die vorherige, ThreadStackSpoofer) zeigt Vorteile, wenn wir unsere Shellcodes auf diese Weise ausführen.

Die Implementierung der Fluktuation zu PAGE_NOACCESS ist inspiriert von der Arbeit von ORCA666, die in seinem https://github.com/ORCA666/0x41-Injektor vorgestellt wurde. Er zeigte, dass:

  1. wir einen Vectored Exception Handler (VEH) initialisieren können,
  2. die Seiten des Shellcodes auf NoAccess umstellen können
  3. und dann Access-Violation-Ausnahmen abfangen können, die auftreten, sobald der Shellcode seine Ausführung fortsetzen möchte, und seine Speicherseiten entschlüsseln und wieder auf Read+Execute umstellen kann.

Diese Implementierung enthält diese Idee umgesetzt und ist mit Option 2 in <fluctuate> verfügbar. Schaut euch unbedingt auch seine anderen Projekte an.


Demo

Das Tool ShellcodeFluctuation akzeptiert drei Parameter: Der erste ist der Pfad zum Shellcode und der zweite ein Modifikator unserer Funktionalität.``` 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 (scheinbar) Fehlalarm```
C:\> ShellcodeFluctuation.exe beacon64.bin -1

So zunächst schauen wir uns an, was der Moneta64-Scanner über einen Prozess denkt, der nichts Verdächtiges tut und sich einfach darauf beschränkt, eine Endlosschleife auszuführen:

moneta false positive

Wie wir sehen können, gibt es einen Fehlalarm (zumindest sehe ich das so), der angeblich Mismatching PEB module / Phantom image erkennt. Die Speichergrenzen zeigen auf das ShellcodeFluctuate.exe-Modul selbst und könnten darauf hindeuten, dass dieses Modul, obwohl es vom Typ MEM_IMAGE ist, nicht in der PEB des Prozesses verlinkt ist – was ungewöhnlich ist und ziemlich seltsam klingt. Der Grund für diesen IOC ist mir nicht bekannt, und ich habe nicht versucht, ihn besser zu verstehen, aber es ist wirklich nichts, worüber wir uns Sorgen machen sollten.

Falls jemand weiß, was der Grund für diese Erkennung ist, würde ich sehr gern davon hören! Bitte melde dich.

Nicht verschlüsseltes Beacon```

C:> ShellcodeFluctuation.exe beacon64.bin 0

root@kitploit:~
Der zweite Anwendungsfall zeigt Memory-IOCs eines Beacons, das in unserem Prozess agiert und weder irgendwelche angepassten `Artifact Kits`, `User-Defined Reflective Loaders` (wie mein [`ElusiveMice`](https://github.com/mgeeky/ElusiveMice)) noch irgendwelche anfänglichen Aktionen verwendet, die unsere Ergebnisse verfälschen würden.

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

Wir können sehen, dass `Moneta64` korrekt `Abnormal private executable memory` erkennt, das auf den Ort zeigt, an dem sich unser Shellcode befindet. 
Das ist ein wirklich starkes Memory-IOC, das unseren Shellcode offenlegt, sodass er von automatisierten Scannern aus dem Speicher geholt und analysiert werden kann. Nicht cool.

### Verschlüsseltes Beacon mit RW-Schutz```
C:\> ShellcodeFluctuation.exe beacon64.bin 1

Nun der dritte, aus Sicht dieser Implementierung interessanteste Anwendungsfall: der fluktuierende Beacon.

moneta encrypted

Abgesehen vom ersten IOC, das gewissermaßen als Fehlalarm betrachtet wird, sehen wir ein neues, das darauf hindeutet, dass der Speicher von kernel32.dll modifiziert wurde. Allerdings gibt es diesmal kein Abnormal private executable memory-IOC. Unsere Fluktuation (also wiederholtes Ver-/Entschlüsseln und Umschalten der Speicherschutzattribute) ist aktiv.

Und der Vollständigkeit halber: pe-sieve erkennt implantierte PE-Dateien auch bei Verwendung der Option /data 3 (ohne diese Option wird keine Erkennung durchgeführt):

pe-sieve

Meine derzeitige Annahme ist, dass PE-Sieve auf dieselben Merkmale anspricht wie Moneta (weiter unten unter Modified code in kernel32.dll beschrieben) – nämlich darauf, dass ein als PE gemapptes Modul einen nicht leeren Working Set hat, was ein offensichtlicher Hinweis auf eine Art Code-Injektion ist. Das wird als Implanted PE / Implanted bezeichnet. Wenn das der Fall ist, ähnelt die Schlussfolgerung der Beobachtung von Moneta. Ich denke nicht, dass wir uns in Bezug auf die Erkennung allzu sehr um dieses IOC kümmern sollten.

Derzeit fällt mir keine bessere Möglichkeit ein, die Ausführung des Shellcodes in der Mitte zu unterbrechen (jetzt spreche ich von Cobalt Strike), als kernel32!Sleep zu hooken. Daher sind wir gezwungen, diese Art von IOCs in Kauf zu nehmen.

Aber hey, immer noch unterscheidet sich kein einziges Byte von dem, was da draußen auf dem Dateisystem liegt (C:\Windows\System32\kernel32.dll), und keine Funktion ist gehookt – was soll das? 😉

Verschlüsselter Beacon mit PAGE_NOACCESS-Schutz```

C:> ShellcodeFluctuation.exe beacon64.bin 2

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

Das bewirkt effektiv, dass der Shellcode zwischen `RX`- und `NA`-Seiten wechselt.

Derzeit bin ich mir nicht sicher, welche Vorteile das Umschalten auf `PAGE_NOACCESS` anstelle von `PAGE_READWRITE` bietet.

### Modifizierter Code in kernel32.dll

Was ist also mit diesem modifizierten `kernel32`-IOC?

Versuchen wir nun, diesem IOC auf den Grund zu gehen und herauszufinden, was es damit auf sich hat.

Zunächst werden wir den genannten Speicherbereich auslesen – den `.text`-Abschnitt (Code) von `kernel32.dll`. Dazu verwenden wir `ProcessHacker`, um eine öffentlich bekannte und stabile Werkzeugkette zu nutzen:

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

Wir lesen den Code-Abschnitt des angeblich modifizierten kernel32 aus und tun dasselbe für das kernel32, das in einem Prozess läuft, der diesen Bereich nicht verändert hat.

Nachdem wir beide Dumps erstellt haben, können wir sie byteweise vergleichen (mithilfe meines [expdevBadChars](https://github.com/mgeeky/expdevBadChars)), um etwaige Unstimmigkeiten zu finden:

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

Nur um festzustellen, dass sie übereinstimmen. Offensichtlich wurde kein einziges Byte in `kernel32.dll` modifiziert, und der Grund dafür ist, dass wir den Hook von `kernel32!Sleep` entfernen, bevor wir es aufrufen:

`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);

Was genau führt also dazu, dass der IOC ausgelöst wird? Schauen wir uns Moneta genauer an:

moneta

Wenn wir uns in Monetas Ioc.cpp etwa um die Zeile 104 begeben, wo der MODIFIED_CODE-IOC gemeldet wird, können wir den Code ein wenig verändern, um den genauen Zeitpunkt besser sichtbar zu machen, an dem der kernel32-Pool analysiert wird. Nun:

  1. Es wird geprüft, ob der Bereich von kernel32 ausführbar ist. Wir sehen, dass dieser Bereich tatsächlich ausführbar ist: a = true
  2. Die Menge des privaten Speichers dieses Moduls wird ermittelt. Hier sehen wir, dass kernel32 b = 0x1000 private Bytes aufweist. Wie kommt das? Es sollten 0 sein.
  3. Wenn eine ausführbare Allokation mehr als 0 Bytes privaten Speichers aufweist (a && b), wird der IOC gemeldet.
  4. Und das ist der Beweis, dass wir zu diesem Zeitpunkt kernel32 untersucht haben.

Wenn der Windows-Image-Loader ein DLL-Modul in den Speicherbereich eines Prozesses abbildet, werden die zugrunde liegenden Speicherseiten je nach Szenario als MEM_MAPPED oder MEM_IMAGE gekennzeichnet. Sobald wir auch nur ein einziges Byte der MEM_MAPPED/MEM_IMAGE-Allokation verändern, trennt das System eine einzelne Speicherseite ab (vorausgesetzt, wir haben weniger als PAGE_SIZE Bytes verändert und keine Seitengrenze überschritten), um ein Fragment zu kennzeichnen, das nicht mehr auf das ursprüngliche Image zurückgeführt werden kann.

Diese Beobachtung wird dann als IOC genutzt – ein Image sollte keine MEM_PRIVATE-Allokationen innerhalb seines Speicherbereichs aufweisen, da dies darauf hindeuten würde, dass in diesem Bereich einst Bytes modifiziert wurden. Moneta erkennt Code-Modifikationen korrekt, selbst wenn die Bytes zum Zeitpunkt des Vergleichs mit denen des ursprünglichen Moduls übereinstimmten.

Für eine umfassende Erklärung, wie Moneta, die Implementierung der Prozessinjektion und der damit verbundene IOC unter der Haube funktionieren, lies die folgenden erstklassigen Artikel von Forrest Orr:

  1. Maskierung bösartiger Speicher-Artefakte – Teil I: Phantom-DLL-Hollowing
  2. Maskierung bösartiger Speicher-Artefakte – Teil II: Mit False Positives verschmelzen
  3. Maskierung bösartiger Speicher-Artefakte – Teil III: Defensive Scanner umgehen

Das ist wahrhaft herausragende Forschung und Dokumentation von Forrest, starke Arbeit, Kumpel!

Besonders der zweite Artikel erläutert die Begründung für diese Erkennung, wenn wir lesen, was Forrest uns lehrt:

Falls das Modul legitim geladen und zur PEB hinzugefügt worden wäre, wäre das Shellcode-Implantat dennoch erkannt worden, aufgrund der 0x1000 Bytes (1 Seite) Speicher, die privat in den Adressraum abgebildet und von Moneta durch Abfragen seines Working Sets abgerufen wurden – was zu einem modifizierten Code-IOC führt, wie oben zu sehen.

Zusammenfassend hinterlassen wir einen IOC, aber sollten wir uns darüber Sorgen machen? Selbst wenn es einen IOC gibt, sind keine gestohlenen Bytes sichtbar, also gibt es keinen unmittelbaren Hinweis, der auf unseren Shellcode zurückverweist oder die Technik unseres Shellcodes von anderen unterscheidet.

Kurz gesagt – wir sollten uns über diesen IOC nicht wirklich Sorgen machen. :-)

Aber kommerzielle Frameworks hinterlassen keine IOCs

Man könnte sagen, dass diese Implementierung alles andere als perfekt ist, weil sie etwas hinterlässt – es gibt eben IOCs, und die kommerziellen Produkte zeigen, dass sie ähnliche Merkmale nicht aufweisen.

Wenn dieses Argument auf den Tisch kommt, muss ich daran erinnern, dass kommerzielle Frameworks die vollständige Kontrolle über den Quellcode ihrer Implantate und Shellcode-Loader haben und diese daher sauber miteinander integrieren können, um die Notwendigkeit zu vermeiden, ihren eigenen Shellcode selbst zu hooken und daran herumzudoktern. Hier müssen wir kernel32!Sleep hooken, um die Ausführung des Cobalt-Strike-Beacons genau bevor es schlafen geht zu unterbrechen und mit unseren Aufräumarbeiten fortzufahren. Wenn es einen besseren Mechanismus gäbe, um einzugreifen, ohne Sleep hooken zu müssen, wäre das perfekt.

Allerdings gibt es das Konzept der Sleep Mask, das in Cobalt Strike eingeführt wurde; die Größenbeschränkung von einigen hundert Bytes macht es uns völlig unmöglich, diese Logik in die Maske selbst einzubringen (andernfalls könnten wir auch auf das Hooking von Sleep verzichten und ebenso wenig IOCs hinterlassen wie kommerzielle Produkte).

Ein weiteres Argument könnte sein, dass kommerzielle Frameworks diese Art von Logik in ihre Reflective Loader integrieren und wir sie stattdessen im EXE-Harness belassen. Das stimmt, aber der Grund für diese Entscheidung ist zweigeteilt:

  1. Ich muss bei der Veröffentlichung dieser Technologie wirklich vorsichtig sein, um das Risiko zu vermeiden, echte Kriminelle mit einer Implementierung zu bewaffnen, die uns mit einem weiteren Petya heimsuchen wird. Aus diesem Grund habe ich beschlossen, einige der unschönen Details wegzulassen, die ich in meiner professionellen Tooling-Umgebung für kommerzielle, vertraglich gebundene Adversary-Simulationen einsetze. Ich hoffe, dass die Veröffentlichung dieses Samens von Fachleuten aus der Community aufgegriffen wird, die das Konzept in ihren eigenen Toolings weiterentwickeln können, sofern sie über die entsprechenden Fähigkeiten verfügen.

  2. Ich würde diese gesamte Logik viel lieber in den User-Defined Reflective Loader von Cobalt Strike verlagern, um Red-Team-Gruppen bessere Chancen in ihrer Auslieferungsphase zu ermöglichen. Aber erstens siehe Punkt (1), und zweitens ist diese Technologie derzeit auf eine Größe von 5 KB für ihre RDLLs beschränkt, was es mir völlig unmöglich macht, sie auch dort zu implementieren. Diejenigen unter uns, die eigene C2- und Implantate für interne Adversary-Simulationen entwickeln, haben nun eine Beispielimplementierung erhalten, die ihnen sicherlich dabei helfen wird, ihre Toolings entsprechend zu verfeinern.


Wie verwende ich es?

Sieh dir den Code und seine Implementierung an, verstehe das Konzept und setze es in deinen eigenen Shellcode-Loadern neu um, die du für deine Red-Team-Einsätze verwendest. Dies ist eine weitere Technik für fortgeschrittene In-Memory-Evasion, die die Chancen deines Teams erhöht, nicht von Antivirenprogrammen, EDRs und Malware-Analysten erwischt zu werden, die sich deine Implantate ansehen.

Während du deinen fortgeschrittenen Shellcode-Loader entwickelst, solltest du vielleicht auch Folgendes implementieren:

  • Process-Heap-Verschlüsselung – lass dich von diesem Blogbeitrag inspirieren: Hook Heaps and Live Free – damit kannst du Beacon-Konfigurationsextraktoren wie BeaconEye umgehen.
  • Spoofe den Call-Stack deines Threads vor dem Schlafen (das könnte Scanner umgehen, die versuchen, die Threads eines Prozesses und ihre Call-Stacks zu untersuchen, um nach MEM_PRIVATE-Speicherallokationen zu suchen, auf die diese Threads verweisen)
  • Entferne alle Überreste des Reflective Loaders, um signaturbasierte In-Memory-Erkennungen zu vermeiden.
  • Enthookie alles, was du möglicherweise gehooked hast (z. B. AMSI, ETW, WLDP), bevor du schläfst, und hooke danach wieder.

Beispielausführung

Anwendungsfall:``` 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:~
Wobei:
- `<shellcode>` ist ein Pfad zur Shellcode-Datei
- `<fluctuate>` akzeptiert, wie oben beschrieben, `-1`, `0` oder `1`


Beispielaufruf, der den Thread-Call-Stack des Beacons vortäuscht:```
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)

Vorsichtshinweis

Wenn Sie diese Funktionalität zu Ihren eigenen Shellcode-Loadern / Toolings hinzufügen möchten, stellen Sie sicher, dass Sie das Unhooking von kernel32.dll VERMEIDEN. Ein Versuch, kernel32 zu unhooken, stellt die ursprüngliche Sleep-Funktionalität wieder her und verhindert, dass unser Callback aufgerufen wird. Wenn unser Callback nicht aufgerufen wird, kann der Thread seinen eigenen Call-Stack nicht selbst spoofen.

Wenn Sie das möchten, müssen Sie möglicherweise einen weiteren Watchdog-Thread ausführen, der sicherstellt, dass der Beacon-Thread bei jedem Sleep gespooft wird.

Wenn Sie Cobalt Strike und ein BOF unhook-bof von Raphael Mudge verwenden, schauen Sie sich unbedingt meinen Pull Request an, der einen optionalen Parameter zu dem BOF hinzufügt, mit dem Bibliotheken angegeben werden können, die nicht unhooked werden sollen.

Auf diese Weise können Sie Ihre Hooks in kernel32 beibehalten:``` 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:~
Modifiziertes `unhook-bof` mit der Option, bestimmte Module zu ignorieren

---

## Abschließende Bemerkung

Dieses PoC wurde entwickelt, um mit Cobalt Strikes Beacon-Shellcodes zu funktionieren. Der Beacon ruft bekanntermaßen `kernel32!Sleep` auf, um auf weitere Anweisungen von seinem C2 zu warten. 
Dieser Loader nutzt diese Tatsache aus, indem er `Sleep` hookt, um seine Verwaltungsaufgaben zu erledigen. 

Diese Implementierung funktioniert möglicherweise nicht mit anderen Shellcodes auf dem Markt (wie _Meterpreter_), wenn diese `Sleep` nicht zum Abkühlen verwenden. 
Da dies lediglich eine _Proof of Concept_-Implementierung ist, die die Technik demonstriert, habe ich nicht vor, Unterstützung für andere C2-Frameworks hinzuzufügen.

Wenn du das Konzept verstanden hast, wirst du es sicherlich auf deine Shellcode-Anforderungen übertragen und die Lösung zu deinem Vorteil anpassen können.

Bitte erstelle keine Github-Issues bezüglich "dieser Code funktioniert nicht mit XYZ-Shellcode"; sie werden sofort geschlossen.

---

### ☕ Unterstützung zeigen ☕

Diese und andere Projekte sind das Ergebnis schlafloser Nächte und **viel harter Arbeit**. Wenn dir gefällt, was ich tue, und du es zu schätzen weißt, dass ich immer etwas an die Community zurückgebe,
[Erwäge, mir einen Kaffee zu kaufen](https://github.com/sponsors/mgeeky) _(oder besser ein Bier)_ , um einfach Danke zu sagen! 💪 

---

## Autor```   
   Mariusz Banach / mgeeky, 21
   <mb [at] binary-offensive.com>
   (https://github.com/mgeeky)
Tool herunterladen
RX
kernel32!Sleep
  • Unser VEH-Handler fängt die Ausnahme ab, entschlüsselt und stellt die Speicherschutzberechtigungen wieder auf RX um, und der Shellcode wird fortgesetzt.