EntropyReducer: Reduziere die Entropie deiner Payload und verschleiere sie mit serialisierten verketteten Listen
Wie es funktioniert
Der EntropyReducer-Algorithmus wird durch die Werte BUFF_SIZE und NULL_BYTES bestimmt. Im Folgenden wird gezeigt, wie EntropyReducer deine Payload organisieren würde, wenn BUFF_SIZE auf 4 und NULL_BYTES auf 2 gesetzt wären.

Verschleierungsalgorithmus
- EntropyReducer prüft zunächst, ob die eingegebene rohe Payload eine Größe hat, die ein Vielfaches von
BUFF_SIZE ist; falls nicht, wird sie aufgefüllt, damit dies zutrifft.
- Anschließend nimmt es jeden
BUFF_SIZE-Block aus der Payload und erstellt dafür einen Knoten einer verketteten Liste mithilfe der Funktion InitializePayloadList, wodurch die Payload als verkettete Liste initialisiert wird.
- Der erstellte Knoten enthält einen leeren Puffer der Größe
NULL_BYTES, der dazu dient, die Entropie zu senken.
- An diesem Punkt hat EntropyReducer seine Aufgabe durch die Senkung der Entropie der Payload zwar erfüllt, hört aber hier nicht auf. Es fährt fort, die Reihenfolge jedes Knotens in der verketteten Liste zu randomisieren und damit die Reihenfolge der rohen Payload aufzubrechen. Dieser Schritt erfolgt über einen Merge-Sort-Algorithmus, der durch die Funktion MergeSort implementiert wird.
- Die sortierte verkettete Liste liegt in zufälliger Reihenfolge vor, da der Wert, nach dem die verkettete Liste sortiert wird, der XOR-Wert der ersten drei Bytes der rohen Payload ist; dieser Wert bestimmt ihre Position in der neu organisierten verketteten Liste. Dieser Schritt ist hier zu sehen.
- Da das Speichern einer verketteten Liste in einer Datei unmöglich ist, weil sie durch Zeiger miteinander verknüpft ist, sind wir gezwungen, sie zu serialisieren.
- Die Serialisierung der erzeugten verketteten Liste erfolgt über die Funktion
Obfuscate hier.
- Danach sind die serialisierten Daten bereit, in die Ausgabedatei geschrieben zu werden.
Deobfuskierungsalgorithmus
- Da der letzte Schritt im
Verschleierungsalgorithmus die Serialisierung der verketteten Liste war, muss hier zuerst die verschleierte Payload deserialisiert werden, wodurch daraus eine verkettete Liste erzeugt wird. Dieser Schritt erfolgt hier in der Funktion Deobfuscate.
- Der nächste Schritt besteht darin, die verkettete Liste anhand der Id des Knotens zu sortieren, was mit demselben zuvor verwendeten Merge-Sort-Algorithmus erfolgt.
- Nun befindet sich die verkettete Liste in der richtigen Reihenfolge, um die Bytes der Payload so zu rekonstruieren, wie sie sein sollten. Wir entfernen also einfach die ursprünglichen Bytes der Payload aus jedem Knoten, wie hier gezeigt.
- Der letzte Schritt besteht darin, die zugewiesenen Knoten freizugeben, was hier erfolgt.
Verwendung
- EntropyReducer liest einfach die Datei mit der rohen Payload von der Kommandozeile und schreibt die verschleierte Version in eine Datei mit demselben Dateinamen, versehen mit dem Präfix ".ER".
- Die Größe der endgültigen verschleierten Payload variiert je nach den Werten von
BUFF_SIZE und NULL_BYTES. Sie kann jedoch mit der folgenden Gleichung bestimmt werden
FinalSize = ((OriginalSize + BUFF_SIZE - OriginalSize % BUFF_SIZE ) / BUFF_SIZE) * (BUFF_SIZE + NULL_BYTES + sizeof(INT))
Das PoC-Projekt in diesem Repository wird verwendet, um die generierte ".ER"-Datei als Beispiel für deren Deserialisierung und Deobfuskierung auszuführen.
In Ihre Projekte einbinden
Sie müssen lediglich die Dateien EntropyReducer.c und EntropyReducer.h zu Ihrem Projekt hinzufügen und die Funktion Deobfuscate aufrufen. Als Referenz können Sie PoC/main.c einsehen.
Ausgabebeispiel
In diesem Beispiel wurde BUFF_SIZE auf 3 und NULL_BYTES auf 1 gesetzt.
- Der rohe Payload, erster Payload-Chunk (
FC 48 83)

- Derselbe Payload-Chunk, jedoch an einem anderen Offset

Nutzen
- Der von metasploit generierte x64-calc-Shellcode weist eine Entropie von
5.883 auf, angezeigt durch pestudio.

- Dieselbe Datei, AES-verschlüsselt, erreicht eine Entropie von
7.110.

- Nahezu dasselbe Ergebnis auch mit dem RC4-Algorithmus;
7.210

- Mit EntropyReducer hingegen liegt die Entropie sogar niedriger als die des ursprünglichen rohen Payloads;
4.093

Der Merge-Sort-Algorithmus stammt aus c-linked-list.