EntropyReducer : Réduisez l'entropie de votre payload et obfusquez-la avec des listes chaînées sérialisées
L'algorithme EntropyReducer est déterminé par les valeurs BUFF_SIZE et NULL_BYTES. Voici comment EntropyReducer organiserait votre payload si BUFF_SIZE était défini à 4, et NULL_BYTES à 2.

Algorithme d'obfuscation
- EntropyReducer vérifie d'abord si le payload brut d'entrée est d'une taille qui est un multiple de
BUFF_SIZE, sinon, il le complète pour qu'il le soit.
- Il prend ensuite chaque bloc de
BUFF_SIZE du payload, et en fait un nœud de liste chaînée, en utilisant la fonction InitializePayloadList, initialisant le payload sous forme de liste chaînée.
- Le nœud créé aura un tampon vide de taille
NULL_BYTES, qui sera utilisé pour réduire l'entropie
- À ce stade, bien que EntropyReducer ait accompli sa tâche en réduisant l'entropie du payload, il ne s'arrête pas là. Il continue ensuite à randomiser l'ordre de chaque nœud dans la liste chaînée, brisant l'ordre du payload brut. Cette étape est réalisée via un algorithme de tri par fusion implémenté par la fonction MergeSort.
- La liste chaînée triée est dans un ordre aléatoire car la valeur selon laquelle la liste chaînée est triée est la valeur XOR des trois premiers octets du payload brut, cette valeur détermine sa position dans la liste chaînée réorganisée, cette étape peut être vue ici
- Étant donné que sauvegarder une liste chaînée dans un fichier est impossible du fait qu'elle est liée par des pointeurs. Nous sommes forcés de la sérialiser.
- La sérialisation de la liste chaînée générée est effectuée via la fonction
Obfuscate ici.
- Après cela, les données sérialisées sont prêtes à être écrites dans le fichier de sortie.
Algorithme de désobfuscation
- Étant donné que la dernière étape de l'
Algorithme d'obfuscation était la sérialisation de la liste chaînée, la première chose à faire ici est de désérialiser le payload obfusqué, en générant une liste chaînée à partir de celui-ci, cette étape est effectuée ici dans la fonction Deobfuscate.
- L'étape suivante consiste à trier la liste chaînée en utilisant l'Id du nœud, ce qui est effectué en utilisant le même algorithme de tri par fusion utilisé auparavant.
- Maintenant, la liste chaînée est dans le bon ordre pour reconstruire les octets du payload tels qu'ils devraient être. Nous extrayons donc simplement les octets originaux du payload de chaque nœud, comme fait ici.
- La dernière étape consiste à libérer les nœuds alloués, ce qui est effectué ici.
Utilisation
- EntropyReducer lit simplement le fichier de payload brut depuis la ligne de commande, et écrit la version obfusquée dans le même nom de fichier préfixé par ".ER".
- La taille du payload obfusqué final varie en fonction des valeurs de
BUFF_SIZE et NULL_BYTES. Cependant, elle peut être déterminée à l'aide de l'équation suivante
FinalSize = ((OriginalSize + BUFF_SIZE - OriginalSize % BUFF_SIZE ) / BUFF_SIZE) * (BUFF_SIZE + NULL_BYTES + sizeof(INT))
Le projet PoC de ce dépôt sert à exécuter le fichier ".ER" généré comme exemple de désérialisation et de désobfuscation de celui-ci.
Intégration dans vos projets
Tout ce que vous avez à faire est d'ajouter les fichiers EntropyReducer.c et EntropyReducer.h à votre projet, puis d'appeler la fonction Deobfuscate. Vous pouvez consulter PoC/main.c pour référence.
Exemple de sortie
Dans cet exemple, BUFF_SIZE a été défini à 3, et NULL_BYTES à 1.
- La charge utile brute, premier fragment de charge utile (
FC 48 83)

- Le même fragment de charge utile, mais à un décalage différent

Résultat
- Le shellcode calc x64 généré par metasploit a une entropie de
5.883, visible via pestudio.

- Le même fichier, chiffré avec AES, obtient une entropie de
7.110.

- Résultat presque identique avec l'algorithme RC4 également ;
7.210

- En utilisant EntropyReducer toutefois, l'entropie obtenue est encore plus faible que celle de la charge utile brute d'origine ;
4.093

L'algorithme de tri par fusion est repris de c-linked-list.