Blog ENI : Toute la veille numérique !
Accès illimité 24h/24 à tous nos livres & vidéos ! 
Découvrez la Bibliothèque Numérique ENI. Cliquez ici
💥 Les 22 & 23 novembre : Accès 100% GRATUIT
à la Bibliothèque Numérique ENI. Je m'inscris !
  1. Livres et vidéos
  2. Cybersécurité et Malwares
  3. Techniques d'obfuscation
Extrait - Cybersécurité et Malwares Détection, analyse et Threat Intelligence (4e édition)
Extraits du livre
Cybersécurité et Malwares Détection, analyse et Threat Intelligence (4e édition)
2 avis
Revenir à la page d'achat du livre

Techniques d'obfuscation

Introduction

L’obfuscation, dans le domaine du développement informatique, consiste à transformer un programme de manière à rendre sa compréhension difficile tout en préservant son comportement. L’idée est de rendre le code du programme le moins intuitif possible de manière à rendre sa lecture complexe. Cette pratique peut paraître surprenante pour les développeurs. En effet, généralement, un bon programme possède un code parfaitement lisible afin de faciliter sa maintenance, d’autres personnes pouvant le modifier, le corriger ou l’améliorer.

L’obfuscation de code est utilisée dans trois cas de figure :

  • Protéger une propriété intellectuelle. Certaines sociétés ne veulent pas que des concurrents puissent copier leur savoir-faire ou ne souhaitent pas que leurs produits puissent être copiés et utilisés illégalement (sans payer de licence). 

  • Ralentir les analyses, dans le cas de l’analyse de malwares, car plus l’analyse prendra du temps, plus longtemps le malware restera fonctionnel.

  • Rendre les antivirus moins efficaces, car après obfuscation, le binaire peut sembler différent et ne pas correspondre à une signature existante.

Il existe une multitude de manières de rendre un code très compliqué à lire. Dans l’analyse de malwares, une méthode fréquemment utilisée est l’obfuscation des chaînes de caractères. Ici, le développeur va dissimuler les chaînes de caractères utilisées par son binaire de manière à ce que le comportement global ne puisse pas être inféré à partir d’une simple lecture superficielle sans analyse de code. Par exemple, les noms de domaine des Command & Control...

Obfuscation des chaînes de caractères

Introduction

Cette section traite des techniques permettant de cacher les chaînes de caractères présentes dans un binaire. Sans chaîne de caractères lisible, l’analyse d’un binaire peut se compliquer : il devient impossible de lire les noms des fichiers ouverts, des clés de registre accédées, ou des sites internet contactés... Nous allons voir cinq procédés pour cacher des chaînes de caractères. Ces techniques ont été classées de la plus simple à appréhender à la plus compliquée :

  • Utilisation de ROT13

  • Utilisation de la fonction XOR avec une clé statique

  • Utilisation de la fonction XOR avec une clé dynamique

  • Utilisation de fonctions cryptographiques

  • Utilisation de fonctions personnalisées

Utilisation de ROT13

Le ROT13 est un algorithme simple de chiffrement de texte. Il consiste à décaler de 13 caractères chaque lettre de l’alphabet. Voici le tableau de conversion :

A

B

C

D

E

F

G

H

I

J

K

L

M

N

O

P

Q

R

S

T

U

V

W

X

Y

Z

N

O

P

Q

R

S

T

U

V

W

X

Y

Z

A

B

C

D

E

F

G

H

I

J

K

L

M

La première ligne du tableau correspond à la lettre de départ et la deuxième ligne à la nouvelle lettre après avoir appliqué la fonction ROT13. Selon notre tableau, l’adresse http://www.google.fr devient uggc://jjj.tbbtyr.se. Il est encore possible de deviner que la chaîne de caractères correspond à une URL. Le malware HerpesNet (hash md5 du fichier qui l’identifie de manière unique : db6779d497cb5e22697106e26eebfaa8) utilise ce type d’encodage pour stocker ses chaînes de caractères.

Voici la sortie de la commande strings appliquée sur ce malware :

rootbsd@lab:~/$ strings...

Obfuscation de l’utilisation de l’API Windows

Introduction

Il est également possible de cacher les appels à l’API Windows. Dans ce cas, l’analyste ne pourra pas lire le nom d’une fonction appelée par le programme. Il existe plusieurs manières pour cacher les utilisations de l’API, l’une d’entre elles consiste à créer sa propre fonction GetProcAddress(). Cette fonction, fournie par Microsoft, permet de connaître l’adresse mémoire d’une fonction particulière. Voici le prototype de cette fonction :

FARPROC WINAPI GetProcAddress( 
  _In_   HMODULE hModule, 
  _In_   LPCSTR lpProcName 
); 

Le premier argument contient la bibliothèque à interroger et le second argument contient le nom de la fonction. Cette fonction retourne l’adresse de la fonction passée en second argument.

Voici un exemple simple d’utilisation de cette bibliothèque :

 PGNSI pGNSI; 
 pGNSI = (PGNSI) GetProcAddress( 
    GetModuleHandle(TEXT("kernel32.dll")),  
    "CreateProcessW"); 

GetProcAddress() retournera l’adresse de la fonction CreateProcessW() disponible dans le fichier kernel32.dll.

Une des techniques très répandues pour cacher les appels aux bibliothèques est donc de créer sa propre fonction GetProcAddress() qui prendra en argument, non pas le nom de la fonction, mais un identifiant (un hash, un mot- clé...). L’adresse de la fonction sera alors retournée et le call se fera donc directement sur cette adresse.

Dans le cas d’une analyse dynamique, les débogueurs afficheront le nom des fonctions en toutes lettres, car ces noms seront forcément résolus au moment de l’exécution de la fonction...

Packers

Introduction

Une des techniques les plus utilisées pour compliquer les analyses de malwares est d’utiliser des packers. Un packer est un logiciel permettant de compresser, encoder ou encore de chiffrer un binaire sans en altérer le fonctionnement. Il existe une multitude de packers, parmi les plus connus nous pouvons citer ArmadilloASPack, ASProtect, Themida, UPX... Certains packers ont pour but avoué de rendre le reverse engineering très compliqué et d’autres ont pour but de simplement compresser le binaire pour qu’il soit plus petit et plus simple à distribuer. Il existe des packers libres ainsi que des packers commerciaux.

La technique pour analyser des malwares obfusqués par des packers est de retrouver ou de restaurer le binaire original. Cette opération s’appelle l’unpack (ou encore « dépacker » un malware). Il est possible que certains malwares utilisent plusieurs couches de packers, il faut alors dépacker couche après couche le malware jusqu’à obtenir le binaire initial, qui pourra alors être analysé.

Chaque packer a son propre fonctionnement, mais dans la plupart des cas le binaire initial sera chargé en mémoire (entièrement ou partiellement). Le but de l’analyse est de trouver ce binaire en mémoire et de l’extraire. Dans le cas des packers qui utilisent le tas (ou heap) pour stocker le binaire original après sa décompression, le binaire initial sera directement utilisable après avoir été extrait de la mémoire. Dans le cas des packers qui utilisent la pile (ou stack) pour stocker le binaire original, il sera nécessaire d’appliquer des corrections à ce binaire extrait de la mémoire pour le rendre utilisable. Quant aux packers extrêmement complexes...

Autres techniques

Anti-VM

Une technique de plus en plus utilisée est la détection de machines virtuelles. Étant donné que les analystes travaillent énormément sur des machines virtuelles, les développeurs de malwares tentent de les identifier afin de stopper l’exécution du binaire et donc d’empêcher les analyses via des outils tels que les sandboxes. Il existe une multitude de manières de contrôler si un binaire est exécuté sur une machine virtuelle : le malware peut inspecter le matériel, les drivers, vérifier si des logiciels additionnels ont été installés pour contrôler la machine virtuelle... C’est pour cette raison qu’il est important de configurer la machine virtuelle comme cela a été décrit dans le chapitre Reverse engineering.

En plus de faire un contrôle, certains malwares peuvent utiliser des bogues au niveau de l’outil de virtualisation. C’est le cas de VirtualBox et de la vulnérabilité CVE-2012-3221 découverte en novembre 2011. Un bogue a été trouvé sur cet outil de virtualisation : quand une machine virtuelle exécutait une interruption 0x8, elle crashait. Les malwares pouvaient donc facilement faire crasher la machine servant à l’analyse en ajoutant le code suivant :

int crash() { 
  asm (  
    "int $0x8;" 
    : // output: none 
    : // input: none 
    :"%eax", "%ebx", "%ecx", "%edx"   // clobbered register 
  );  
  return(0); 

Il est donc extrêmement important de mettre à jour les solutions de virtualisation utilisées dans le laboratoire d’analyse.

Une autre...

Résumé

Les développeurs de malwares ont énormément de techniques à leur disposition pour rendre l’analyse de leurs malwares très compliquée. Ils font également preuve d’une grande imagination et disposent d’un bagage technique de plus en plus grand. Il y a fort à parier que dans les années qui arrivent de nouvelles techniques seront découvertes.