EsxiArgs : Analyse du rançongiciel

Le 1er février dernier, une nouvelle campagne de rançongiciel ciblant des serveurs utilisant une version vulnérable de l’hyperviseur VMware ESXI, a notamment touché la France du fait de la présence de machines vulnérables chez le gestionnaire cloud OVH.


Le 3 février, le nombre de serveurs compromis détectés par Censys search [1] s’élevait à 2 400.
Cette vulnérabilité (CVE-2021-21974) a permis à l’attaquant de déposer et d’exécuter sur les serveurs cibles un rançongiciel chiffrant les fichiers des machines virtuelles.
Baptisé EsxiArgs (de par l’extension .args des fichiers créés par le rançongiciel) ce dernier demande une rançon de 2 bitcoins en échange d’une possible restauration. 

Sur le blog d’OVH [1], il est fait mention d’un lien de parenté entre la version de EsxiArgs et le rançongiciel Babuk dont le code source a été rendu public en 2021.

Après une rapide recherche sur VirusTotal [2], nous avons trouvé un échantillon provenant d’un lieu situé en France.

Par chance, l’exécutable comporte encore tous ses symboles de débuggage et implémente uniquement 78 fonctions (en réalité seules 35 ont été développées par les auteurs), ce qui facilite grandement son analyse. Au premier abord, l’exécutable embarque uniquement des fonctionnalités de chiffrement que ce soit du RSA asymétrique au travers de la bibliothèque libssl et le chiffrement sosemanuk [3,4]. Ce dernier étant connu pour avoir fait son apparition dans le rançongiciel développé par le groupe Babuk [5].  

Pour commencer, regardons le lien de parenté que peut avoir EsxiArgs avec la version de Babuk recompilée par nos soins. Pour cela, nous allons utiliser Gorille et afficher le recouvrement de sites entre les deux binaires :

Nous remarquons que la version de Babuk comporte le double de sites (166 fonctions), ce qui confirme la présence d’un nombre plus élevé de fonctionnalités par rapport à EsxiArgs (78 fonctions). 

Afin de vérifier que EsxiArgs utilise bien le même code source que Babuk lors de l’implémentation du chiffrement sosemanuk, nous recherchons à l’aide de Gorille les fonctions similaires entre les deux binaires à notre disposition. 

Pour cela nous exécutons l’outil binsim ainsi :

$ binsim babuk/e_esxi.out EsxiArgs/encrypt

[…]

functions 40986b – 406d4d matched 60 / 61 or 61

functions 40a95f – 407f7a matched 10 / 11 or 11

functions 40aa88 – 408088 matched 10 / 11 or 11

functions 40a8f3 – 40819e matched 3 / 3 or 3

functions 4011d0 – 400a48 matched 1 / 1 or 1

functions 40554d – 407f58 matched 1 / 1 or 1

Ce qui correspond aux fonctions de chiffrement :

  • sosemanuk_internal,
  • sosemanuk_prng,
  • sosemanuk_schedule,
  • xorbuf,
  • encode32le

Pour re-compiler l’exécutable de Babuk, nous avons utilisé la version 4.9.2 de GCC, alors que celle utilisée pour EsxiArgs semble être la 4.2.4 (Le binaire comporte la chaîne de caractères 
« GCC: (GNU) 4.2.4 (Ubuntu 4.2.4-1ubuntu3) » à plusieurs endroit du programme).

Nous pouvons visualiser ces similarités à l’aide d’IDA pro en générant le fichier de configuration du plugin de synchronisation de code fourni dans Gorille.

$ binsim -j babuk/e_esxi.out EsxiArgs/encrypt -o Babuk-EsxiArgs_similarities.cfg

Sur l’image ci-dessous, montrant l’implémentation de la fonction sosemanuk_internal dans les deux binaires (Babuk est à gauche de l’image), nous trouvons à plusieurs endroits de légères différences introduites par la version de GCC.

Dans les deux cas, la séquence d’instructions du block gauche réalise la même opération : « xorer », deux valeurs situées dans des variables :

Babuk-CyberDetect
EsxiArgs-CyberDetect

Autre constatation, la fonction xorbuf possède la même structure (4 basics blocks avec une boucle) mais le traitement de fin de la boucle est implémenté différemment :

Si nous regardons le code source de la fonction xorbuf dans Babuk, nous constatons que la boucle continue tant que la variable data_len est strictement supérieure à zéro (elle est décrémentée de 1 à chaque tour de boucle) :

capture-cyberdetect

Ainsi, après compilation du code source de Babuk sous GCC 4.2.4, cette condition de fin de boucle est encore compréhensive comme nous pouvons le voir dans le binaire de EsxiAgrs :

Fonction xorbuf dans EsxiArgs :

esxi-cyberdetect

Alors que GCC 4.9.2 l’écrit ainsi :

Fonction xorbuf dans Babuk recompilé :

Ou encore  GCC 4.4.7 ainsi :

Fonction xorbuf dans Babuk généré par le builder divulgé en 2021 [6,7]  :

Pour conclure, le rançongiciel EsxiArgs a été écrit dans le but unique de chiffrer des données passées en argument en utilisant les deux protocoles de chiffrement que sont RSA et Sosemanuk. 

Ce dernier reprend exactement le même code source que Babuk pour l’implémentation du chiffrement Sosemanuk, mais implémente le protocole RSA au travers de a bibliothèque libssl [9] contrairement à la version de Babuk. Malgré une différence dans l’assembleur généré par les versions de GCC utilisées lors de nos tests, nous constatons que cela n’a pas d’influence sur la reconnaissance des similarités de codes identifiées par la technologie de Gorille.