Skip to content
KitploitKITPLOIT
ToolsExploitsBlog
Log in
Einreichen
ToolsExploitsBlog
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
Tools/GitHubGitHub/0xsch1zo/nullgate
Verschlüsselungs-/EntschlüsselungstoolsShellcodePost-ExploitationRed TeamingPayload-EntwicklungAdversarial-Angriff
GitHub0xsch1zo/nullgate

NullGate

Bibliothek, die die Verwendung indirekter Syscalls erleichtert. Ziemlich interessanter AV/EDR-Bypass als PoC.

Repository anzeigen
1681918vor 1 JahrVon 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

NullGate

Dieses Projekt implementiert eine komfortable und moderne Möglichkeit, die NTAPI-Funktionen mithilfe indirekter Syscalls zu verwenden, gekoppelt mit der FreshyCalls-Methode mit einer kleinen Abwandlung zur dynamischen Syscall-Nummernabrufung. Es verwendet außerdem eine Technik, von der ich nicht gesehen habe, dass sie erwähnt wird, um den Speicherscan von Windows Defender zu umgehen. Das Projekt implementiert einen klassischen PoC-Prozess-Injektor, der die Bibliothek verwendet. Praktische Funktionen zur Verschlüsselung sind ebenfalls verfügbar.

Demo

Demonstration of the sample

Erstellen

Zum Erstellen des Beispiels verwende -DNULLGATE_BUILD_SAMPLE=ON. Wenn du nullgate direkt gebaut hast, ist es unter <build_dir>/sample.exe verfügbar; wenn du es als Abhängigkeit gebaut hast, unter <build_dir>/_deps/nullgate-build/sample.exe. Unter Windows sind die Build-Ziele seltsam, daher wird es sich wahrscheinlich in denselben Basisverzeichnissen wie die Speicherorte der Beispiele befinden, aber wahrscheinlich noch ein paar Ebenen tiefer verschachtelt. Es benötigt als Argument eine PID, in die du Shellcode injizieren möchtest.

[!WARNING] Wenn du Linux verwendest, musst du den MinGW-Cross-Compiler installiert haben. Auf Arch kannst du zum Beispiel pacman -S mingw-w64-gcc ausführen. Verwende dann die Option -DNULLGATE_CROSSCOMPILE=ON, um mingw als Standard-Compiler festzulegen.

[!TIP] Es wird außerdem empfohlen, die resultierende Binärdatei zu strippen, um die Erkennungswahrscheinlichkeit zu verringern.

git clone https://github.com/0xsch1zo/NullGate
cd NullGate
cmake . -B build -DNULLGATE_BUILD_SAMPLE=ON
cmake --build build/

Veralteter hashser (Versionen 1.1.3 und darunter)

Es kann mit dem Flag -DNULLGATE_DEPRECATED_HASHER gebaut werden.

Verwendung

Hinzufügen von nullgate zu deinem Projekt

CMake FetchContent wird unterstützt. Hier ist ein Beispiel für eine einfache CMakeLists.txt:

cmake_minimum_required(VERSION 3.25)

include(FetchContent)

FetchContent_Declare(nullgate
    GIT_REPOSITORY https://github.com/0xsch1zo/NullGate
    GIT_TAG 1.2.0 
)

FetchContent_MakeAvailable(nullgate)

project(test)

add_executable(test
    main.cpp
)

target_link_libraries(test
    PRIVATE nullgate
)

Die Verknüpfung erfolgt statisch, sodass du dir keine Sorgen um sichtbare Symbole machen musst.

[!NOTE] Die folgenden Beispiele verwenden namespace ng = nullgate

Syscalls

Die Verwendung ist ziemlich einfach. Hier ist ein Codeausschnitt, der die Hauptfunktionalität demonstriert:

ng::syscalls syscalls;
typedef NTSTATUS NTAPI NtAllocateVirtualMemory(
    _In_ HANDLE ProcessHandle,
    _Inout_ _At_(*BaseAddress,
                 _Readable_bytes_(*RegionSize) _Writable_bytes_(*RegionSize)
                     _Post_readable_byte_size_(*RegionSize)) PVOID *BaseAddress,
    _In_ ULONG_PTR ZeroBits, _Inout_ PSIZE_T RegionSize,
    _In_ ULONG AllocationType, _In_ ULONG PageProtection);

NTSTATUS status = syscalls.SCall<NtAllocateVirtualMemory>(
      ng::obfuscation::fnv1Const("NtAllocateVirtualMemory"), processHandle,
      &buf, 0, &regionSize, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);

Es gibt eine eingebaute Typsicherheit. Du musst nur die Definition der NT-Funktion bereitstellen, die du aufrufen möchtest! Du kannst sie leicht von ntdoc bekommen. Dies ist der empfohlene Weg, die Bibliothek zu verwenden.

Die bisherige, nicht veraltete Schnittstelle

Für Leute, die die C++-Template-Schwarze Magie oder so etwas nicht mögen, ist die bisherige Schnittstelle weiterhin verfügbar:

NTSTATUS status = syscalls.Call(ng::obfuscation::fnv1Const("NtAllocateVirtualMemory"),
                         processHandle, (PVOID)&buf, (ULONG_PTR)0, &regionSize,
                         (ULONG)(MEM_RESERVE | MEM_COMMIT), (ULONG)PAGE_EXECUTE_READWRITE);

Bei dieser Schnittstelle musst du die Argumente in den richtigen Typ casten. Wenn du das nicht tust, kann das zu Problemen führen.

Verschlüsselung/Hashing

Hashing von NTAPI-Aufrufen

constexpr uint64_t hash = ng::obfuscation::fnv1Const("NtAllocateVirtualMemory");

Die zuvor gezeigte fnv1Const-Methode bringt die Freuden des modernen C++ in die Maldev-Welt. Sie ist eine consteval-Funktion, sodass garantiert ist, dass sie zur Kompilierzeit ausgewertet wird und den lesbaren Funktionsnamen durch einen fnv1-Hash ersetzt.

Es gibt auch ein Laufzeit-Äquivalent namens fnv1Runtime, aber natürlich bietet es nicht den Vorteil, dass unsere Funktionsnamen verschleiert werden. Es wird von der Implementierung verwendet, um zu prüfen, welche Funktion innerhalb von ntdll die Syscall-Nummer liefert.

Allgemeine xor-Verschlüsselung

Es gibt drei Routinen für die xor-„Verschlüsselung“:

xorConst
constexpr ng::obfuscation::ConstData xored = ng::obfuscation::xorConst("some string");
std::cout << xored.string();

Mögliche Ausgabe:

<Y:-E&X0

Diese Routine wird ähnlich wie die fnv1Const-Funktion zur Kompilierzeit ausgewertet, sodass "some string" niemals in der Binärdatei erscheint, weil der String in seiner verschlüsselten Form gespeichert wird. Aber hey, wir müssen diese Daten tatsächlich nutzen! ConstData ist ein dünner Wrapper um rohe Bytes mit konstanter Größe. Es hat zwei Methoden: raw() und string(). raw() gibt ein std::vector<unsigned char> zurück und string gibt, wie der Name schon sagt, ein std::string zurück.

[!NOTE] Falls du ConstData direkt mit einem String-Literal konstruieren musst, verwende std::to_array, um ein Zwischenarray zu erstellen, das an ConstData übergeben wird. Beachte jedoch, dass ConstData bei diesem Ansatz das zusätzliche Nullzeichen des Literals speichert.

Natürlich brauchen wir eine Möglichkeit, dies zu entschlüsseln und zu verwenden, was die nächste Funktion ist, die wir behandeln werden.

xorRuntime

xorRuntime ist die zweite verfügbare Routine. Wie der Name schon sagt, ist es das Laufzeit-Äquivalent von xorConst. Bitte beachte, dass es nicht nur zur Entschlüsselung verwendet werden muss; es funktioniert in beide Richtungen, obwohl die Verwendung zur Verschlüsselung nicht den Vorteil bietet, den String zur Kompilierzeit zu verschleiern.

ng::obfuscation::ConstData xored = ng::obfuscation::xorConst("some string");
ng::obfuscation::ConstData data = ng::obfuscation::xorRuntime(xored);
assert(data.string() == "some string");

std::string dynamicString = "some data of dynamic size";
auto dynamicData = ng::obfuscation::DynamicData(dynamicString);
auto xoredDynamic = ng::obfuscation::xorRuntime(dynamicData);
auto unxoredDynamic = ng::obfuscation::xorRuntime(xoredDynamic);
assert(unxoredDynamic.string() == dynamicString);

DynamicData hat dieselben Methoden wie ConstData, mit einigen zusätzlichen Konstruktoren für die Interoperabilität, und kann, wie der Name schon sagt, eine Größe haben, die zur Kompilierzeit nicht bekannt ist. xorRuntime akzeptiert sowohl DynamicData als auch ConstData.

Tool herunterladen