
Dynamischer Shellcode-Loader mit hochentwickelten Evasion-Fähigkeiten
AsmLdr ist ein fortschrittlicher Shellcode-Loader, implementiert in x64-Assemblersprache, ausgelegt für Windows-x64-Umgebungen. Sein Hauptzweck ist die Ausführung verschlüsselter Payloads bei gleichzeitiger Minimierung der Erkennung durch hochentwickelte Antivirensoftware, Endpoint Detection and Response (EDR)-Systeme, Sandboxes und Debugger. Dies erreicht er, indem er Module, APIs und Systemaufrufe zur Laufzeit dynamisch auflöst und damit statische Abhängigkeiten wie Importtabellen oder fest verdrahtete Adressen eliminiert. Dieser Ansatz erzeugt ein kompaktes Binärprogramm mit einem niedrigen Erkennungsprofil.
Der Loader verwendet Module Stomping, um Shellcode in den ausführbaren Abschnitt einer vorhandenen DLL zu platzieren, entschlüsselt die Payload im Speicher und führt sie über indirekte Syscalls mit Stack Spoofing aus. Er enthält Evasion-Funktionen wie Anti-Debugging-Maßnahmen, Zeitablauf-Anpassungen zur Nachahmung normaler Anwendungsmuster und die Umgehung der Windows-Ereignisablaufverfolgung (ETW). Diese Fähigkeiten machen ihn zu einem Werkzeug für Red Teaming und Sicherheitsforschung. Ethischer Haftungsausschluss: Dieses Projekt dient ausschließlich Bildungs- und Forschungszwecken. Es demonstriert Low-Level-Windows-Interna, einschließlich PEB-Traversierung, Parsen von Exporttabellen, Syscall-Unhooking und Manipulation des Speicherschutzes. Verwendung nur in kontrollierten Umgebungen (z. B. VMs). Missbrauch für böswillige Aktivitäten ist illegal und unethisch. Der Autor lehnt jede Haftung für Missbrauch ab.
AsmLdr bietet eine Reihe von Funktionen für heimliche Payload-Ausführung und Evasion. Jede wird im Folgenden beschrieben, mit Fokus auf Funktion und Nutzen:
Modulauflösung durch PEB-Traversierung: Der Loader listet laufende Module auf, indem er der Modulkette des PEB folgt. Er gleicht Modulnamen über Unicode-Vergleiche ab, um die Basisadresse der gewünschten DLL zu finden und zurückzugeben. Diese Methode umgeht Standard-Ladefunktionen und verringert das Risiko der Abfangung.
API-Auflösung aus Exporttabellen: Der Loader untersucht das Exportverzeichnis einer DLL, um Funktionen zu lokalisieren. Er gleicht APIs mithilfe von Hashing oder optional direkten Namensprüfungen mit Längenverifizierung ab, um Verwechslungen zwischen ähnlich benannten Funktionen zu vermeiden. Dies liefert die Adresse der Funktion, ohne sich auf vorgeknüpfte Importe zu verlassen.
Anti-Debugging-Schutzmaßnahmen: Der Loader erkennt Debugging über mehrere Prüfungen und beendet sich sauber, wenn eine auf eine Analyse hindeutet.
Junk-Code-Erzeugung zur Analyse-Resistenz: Der Loader führt Sequenzen nicht essenzieller Operationen aus, um verwirrende Muster im Disassembly zu erzeugen, was die statische Analyse erschwert, ohne die Laufzeiteffizienz zu beeinträchtigen.
Zeit- und Verhaltensnormalisierung: Der Loader misst die Systemgeschwindigkeit, um simulierte Arbeitslasten auszuführen, die normalen Anwendungsmustern entsprechen, und sich so an legitime Prozesse anzupassen. Er pausiert außerdem kurz vor wichtigen Aktionen, um die Ausführungszeit zu normalisieren.
ETW-Protokollierungsumgehung: Der Loader setzt Hardware-Breakpoints auf ETW-Protokollierungs-APIs, um Ereignisprotokollierungsaufrufe abzufangen und zu überspringen, und verhindert so Spuren in Systemprotokollen.
Mehrschichtiges Unhooking: Der Loader ruft dynamisch gültige Systemaufrufnummern (SSNs) ab, indem er Funktionen direkt prüft, nahegelegenen Code scannt, falls dieser gehooked ist, oder Muster in ntdll zählt, um die Nummer zu schätzen, mit Anpassung an bekannte Ausnahmen.
Verwendete Techniken:
Indirekter Syscall und Stack Spoofing: Der Loader findet saubere Codepfade in ntdll für Systemaufrufe und verkettet bis zu 32 Operationen, wodurch der Aufrufstack verborgen wird, um die Ablaufverfolgung zu umgehen. Er stellt den ursprünglichen Zustand nach Abschluss wieder her.
DLL-Hollowing: Der Loader lädt eine ZieldLL, erlaubt vorübergehend das Schreiben in deren Codeabschnitt, fügt den verschlüsselten Shellcode ein, entschlüsselt ihn und setzt die Schutzmaßnahmen auf Nur-Ausführen zurück.
Entschlüsselung im Speicher: Der Loader entschlüsselt den Shellcode, indem er ein sich wiederholendes Schlüsselmuster direkt im injizierten Speicher anwendet.
Dienstprogrammfunktionen: Der Loader enthält Werkzeuge zum Messen von Zeichenfolgenlängen, Vergleichen von Zeichenfolgen (Standard- oder Breitzeichen), Hashing von Namen für Nachschlagevorgänge, Validieren von Speicherzeigern und Lesen von Zeitstempeln für Zeitablaufsteuerungen.
Das Python-Skript generate.py verschlüsselt die rohe Shellcode-Datei. Es fügt Padding für die Ausrichtung hinzu, erstellt oder verwendet einen Schlüssel und XOR-verknüpft jedes Byte mit dem Schlüssel in einem sich wiederholenden Zyklus. Die Ausgabedatei shellcode.asm definiert Größen, Arrays für die verschlüsselten Daten und den Schlüssel sowie eine Routine zum Laden der Daten zur Laufzeit. Die Entschlüsselung des Loaders entspricht diesem Prozess im Speicher. Beachten Sie, dass längere Schlüssel die Wartezeit erhöhen.
Bereiten Sie ein rohes Shellcode-Binary vor (z. B. payload.bin). Führen Sie python generate.py payload.bin [optionaler_Schlüssel] aus, um shellcode.asm zu erzeugen.
Ändern Sie szDllName (Unicode-Hex-Wörter in evader.asm) für alternative DLLs wie urlmon.dll. Berechnen Sie DJB2-Hashes für neue APIs mithilfe der str_hash-Logik neu. Kommentieren Sie Makros (z. B. KILL_DEBUGGERS) für das Debugging aus.
AsmLdr ist für Windows 10 und 11 x64 optimiert; Kernel-Updates können Offsets (z. B. PEB+0x18) oder NTDLL-Muster (z. B. 0xb8d18b4c) verändern, was eine Validierung erfordert. Die Fehlerbehandlung stützt sich auf NTSTATUS-Rückgaben (z. B. <0 Fehler), ohne integrierte Protokollierung. Junk- und Fake-Operationen verbrauchen CPU-Zyklen und können Ressourcenmonitore auf Systemen mit begrenzten Ressourcen alarmieren. Ausschließlich in kontrollierten Umgebungen verwenden.