Résumé
- SharpRhino est basé sur le projet open source ThunderShell.
- Il est distribué aux victimes sous la forme d'un programme d'installation NSIS qui dépose des scripts PowerShell
- Les scripts PowerShell contiennent des assemblages .NET encodés.
- La charge active .NET sert à communiquer avec le serveur C2
- Des commandes peuvent être exécutées à distance
- Le trafic réseau est chiffré avec RC4 et encodé au format Base64
Introduction
Hunters International, un groupe de cybercriminels bien connu pour ses opérations de ransomware-as-a-service, a commencé à utiliser un nouveau malware RAT (cheval de Troie à distance). Le premier incident signalé a été repéré au début du mois d'août 2024 et a été baptisé SharpRhino en raison du langage C# qu'il utilise. Le cheval de Troie envoyé a l'apparence d'un logiciel légitime et permet l'accès distant à la machine de la victime. Grâce à ce logiciel, les criminels peuvent exécuter différentes commandes et propager d'autres malwares.
Détails techniques
Présentation
L'échantillon analysé est distribué aux victimes sous la forme d'un programme d'installation créé avec Nullsoft Scriptable Install System. Ce fichier comporte la mention « Angryip.org » dans sa description et un certificat numérique valide, mais le nom de l'entreprise est faux et il n'existe pas.

Il contient un programme d'installation supplémentaire, une archive protégée par mot de passe et d'autres fichiers qui seront utilisés lors de l'exécution du malware.

Installation
À l'exécution, l'échantillon dépose tous les fichiers dans le dossier « C:\ProgramData\Microsoft\WindowsUpdate24 » et exécute un fichier « ipscan-3.9.1-setup.exe », programme d'installation du logiciel légitime Angry IP Scanner.

Ce programme d'installation occupe l'utilisateur, tandis que le malware extrait les fichiers de l'archive UpdateFull.zip protégée par mot de passe. Pour décompresser l'archive, il utilise un programme 7za.exe intégré. Dans la ligne de commande, nous pouvons voir le mot de passe de l'archive :
C:\ProgramData\Microsoft\WindowsUpdate24\7za.exe x C:\ProgramData\Microsoft\WindowsUpdate24\UpdateFull.7z -pTG98HJerxsdqWE45 -oC:\ProgramData\Microsoft\WindowsUpdate24
Le contenu de l'archive est le suivant :

Après extraction, l'échantillon crée un nouveau dossier — « C:\ProgramData\Microsoft\LogUpdateWindows » — où il copie les fichiers extraits de l'archive. L'utilisation de deux dossiers d'installation différents peut aider les attaquants à se maintenir sur le système si l'un des dossiers est supprimé, car les fichiers qu'ils comportent sont identiques. Une nouvelle clé de la base de registre est ajoutée au chemin « HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run » qui pointe vers le fichier « Microsoft.AnyKey.lnk ». Ce fichier est un raccourci, qui contient la cible suivante :
C:\ProgramData\Microsoft\LogUpdateWindows\Microsoft.AnyKey.exe abnormal c:\programdata\%username%0 cmd /c C:\ProgramData\Microsoft\LogUpdateWindows\LogUpdate.bat
L'exécutable « Microsoft.AnyKey.exe », également extrait de l'archive, est un programme légitime faisant partie des outils Node.js pour Visual Studio et portant le nom de « Microsoft.NodejsTools.PressAnyKey.exe ».
Exécution
Les fichiers « LogUpdate.bat » et « WindowsUpdate.bat » ont la même fonctionnalité, mais ils chargent des fichiers différents.

Les fichiers « Wiaphoh7um.t » et « kautix2aeX.t » contiennent tous deux des données avec obfuscation. Les données brutes de ces fichiers et la clé sont différentes, mais les résultats seront identiques. Après le processus de décodage, l'échantillon définit ces données comme un assemblage .NET et invoque une méthode avec certains paramètres.

Après le vidage mémoire de toutes les données du script, nous pouvons observer les variables suivantes :
Les variables $var1, $var2, $var3 déterminent les assemblages référencés et, lorsqu’elles sont concaténées, forment la chaîne suivante :
System.Drawing.dllSystem.Web.Extensions.dllSystem.Windows.Forms.dll
$var4 est différent pour chaque fichier et contient l'adresse d'un serveur C2. Le tableau ci-dessous représente les arguments utilisés dans l'appel d'assemblage .NET pour chaque fichier :

« $fjwZrHB1k2RF » est l'assemblage .NET chargé en mémoire. Après le vidage mémoire des données, nous pouvons observer du code C#. Le script PowerShell appelle une fonction de l'espace de noms « Bzxmlpi » et de la classe « OyrWkb ». Au début de cette classe, nous pouvons observer certaines importations supplémentaires et des noms de variables illisibles.

Ce fichier est en réalité une version modifiée du projet open source « ThunderShell ». Plusieurs modifications ont été apportées au projet source :
- Suppression des fonctions de chargement de l'enregistreur de frappe, de captures d'écran et d'assemblages .NET, ainsi que des commandes du serveur correspondant à ces fonctions.
- Toutes les classes, fonctions et variables ont été renommées.
- Ajout de valeurs par défaut qui seront utilisées si la charge active est exécutée sans argument.

Cette fonction génère d'abord une chaîne aléatoire de 16 octets. Lors de l'initialisation de la classe Random, l'échantillon utilise les valeurs actuelles de date, d'heure et d'identifiant de traitement comme graine. Ensuite, il récupère certaines variables d'environnement, telles que COMPUTERNAME, USERDOMAIN et USERNAME. Toutes ces données seront formatées :

La chaîne suivante est alors générée :

L'échantillon transmet ensuite cette chaîne à une fonction qui l'envoie au serveur. Ici, il chiffre les données en RC4 avec une clé passée en deuxième argument.

Après le processus de chiffrement, il ajoute des données à la requête et encode également la chaîne chiffrée au format Base64. Toutes ces données sont ensuite envoyées au serveur.

Lors de cette première connexion, la réponse du serveur est ignorée. Lorsque l'échantillon entre dans une boucle, il se connecte à nouveau au serveur, mais les deux arguments sont « null ». Ensuite, la réponse est enregistrée et comparée aux valeurs enregistrées. Si la commande « delay » est reçue, l'échantillon prend un argument supplémentaire et modifie la valeur qui sera transmise à la fonction dormante. Si la commande « exit » était obtenue, elle interromprait la boucle et la procédure d'exécution. Si elle venait à obtenir des données autres que « delay » ou « exit », elle créerait un nouveau thread avec une fonction qui prendrait les données obtenues comme argument. Toutes ces actions seront répétées avec un délai de 95 secondes entre chaque itération de la boucle.

La réponse du serveur est transmise à la fonction de désérialisation de la classe « zWxFlnVASjHYb », qui récupère et stocke les données suivantes : ‘UUID’, ‘ID’ et ‘Data’.

Serveur C2
Bien que le lien présenté dans l'échantillon soit déjà hors ligne, nous pouvons utiliser le serveur du projet source pour voir comment fonctionne la communication. Nous devons d'abord modifier la configuration du serveur. Y figurent un certain nombre de champs, dont l'adresse IP du serveur, la clé de chiffrement, les paramètres de l'interface utilisateur et les paramètres HTTP et HTTPS. Deuxièmement, nous devons modifier les paramètres « callback-url », « gui-host » et « encryption-key ». Nous allons reprendre les paramètres de la clé de chiffrement d'un échantillon de SharpRhino.

Le serveur est une application Python qui nécessite un serveur Redis en cours d'exécution. Une fois démarrée, elle affiche des informations sur le serveur.

L'adresse d'une interface utilisateur web y figure. L'utilisateur est invité à s'identifier. Peu importe le nom d'utilisateur saisi, le mot de passe doit lui provenir du fichier de configuration. Une fois la connexion établie, le tableau de bord s'affiche. Il contient des informations sur les sessions et les journaux.

La charge active peut être créée dans l'interface web. Vous devez fournir l'adresse IP du serveur et le type de charge active.

Après qu'il a sélectionné une session, l'attaquant peut interagir avec elle. La commande « help » affiche toutes les commandes utilisables dans la session.

Communications avec C2
Ces commandes contiennent des chaînes prédéfinies qui seront ajoutées aux données que l'attaquant entre en tant qu'arguments. Par exemple, l'utilisation de la commande « shell [command] » ajoutera « cmd.exe /c » au début de la chaîne qui sera envoyée. La commande « ps » envoie le script PowerShell au client :

La commande adressée au client est chiffrée avec RC4 et encodée au format Base64. Elle contient les paramètres ID et UUID, où ID est l'identifiant du client et UUID est l'identifiant de la commande.

Toutes ces données sont transmises au nouveau thread. Ce thread a pour but d'utiliser des modules PowerShell pour exécuter des commandes spécifiées.

L'échantillon récupère alors le résultat de la commande exécutée. Ces données sont ensuite chiffrées et renvoyées au serveur.

Conclusion
Hunters International a utilisé ThunderShell, un ancien projet open source qui n'avait pas été mis à jour depuis près de quatre ans, pour propager des malwares aux victimes. Le malware est distribué sous la forme d'un programme d'installation de l'utilitaire Angry IP Scanner, mais il dépose et exécute des scripts PowerShell malveillants. Grâce aux fonctionnalités de PowerShell, ces scripts exécutent des assemblages .NET encodés, sans qu'il faille d'exécutable compilé supplémentaire. Le code malveillant est invoqué et exécuté en mémoire.
Même si le code d'origine a été modifié, il conserve sa fonctionnalité principale : l'exécution de commandes à distance sur les systèmes ciblés. C'est le danger de ces projets open source. S'ils sont généralement développés à des fins éducatives ou de tests d'intrusion, ils peuvent être utilisés pour perpétrer des attaques réelles.
Détecté par Acronis

