Si l'été est généralement synonyme de vacances, il semble que le groupe Sednit ait développé de nouveaux composants à ajouter à la famille des logiciels malveillants Zebrocy.

Le groupe Sednit - également connu sous le nom d'APT28, Fancy Bear, Sofacy ou STRONTIUM - opère depuis au moins 2004 et a souvent fait les gros titres ces dernières années.

Le 20 août 2019, une nouvelle campagne a été lancée par le groupe ciblant les victimes habituelles du groupe, soit les ambassades et les ministères des Affaires étrangères de pays d'Europe orientale et d'Asie centrale.

Cette dernière campagne a commencé par un courriel d'hameçonnage contenant une pièce jointe malveillante qui lance une longue chaîne de téléchargeurs (et downloaders) et se termine par une porte dérobée. Un exemple d'un tel courriel a été téléchargé sur VirusTotal le 22 août, deux jours après la livraison du courrier. Un aperçu du vecteur d'attaque a récemment été publié par Telsy TRT.

Cependant, nous avons d'autres pièces de ce casse-tête, qui pourraient nous aider à brosser un tableau plus complet de cette campagne.

Comme l'avaient prédit d'autres chercheurs, le groupe Sednit a ajouté un nouveau langage de développement dans leur boîte à outils, plus précisément pour leur téléchargeur : le langage Nim. Cependant, leurs développeurs étaient également occupés à améliorer leur téléchargeur Golang, ainsi qu'à réécrire leur backdoor de Delphi à Golang.

Une compromission compliquée

La figure 1 illustre les différentes étapes menant à la compromission d'une victime, depuis le courriel malveillant initialement reçu dans la boîte de réception jusqu'à la backdoor déployée sur des cibles jugées « suffisamment intéressantes » par les opérateurs.

Figure 1. Aperçu de la chaîne de compromission

Quand une victime est ciblée par les composants de Zebrocy, la chaîne est généralement assez forte. Fort parce que, dans ce cas, la victime a au moins six composants malveillants lâchés sur l'ordinateur avant que la charge utile finale ne soit exécutée. De telles activités peuvent facilement soulever différents types de drapeaux pour un produit de sécurité.

Le document joint au courriel d'hameçonnage est vierge, mais fait référence à un modèle distant, wordData.dotm, hébergé chez Dropbox. L'ouverture de ce document dans Word lui permet de télécharger wordData.dotm, comme illustré à la Figure 2, et de l'intégrer dans l'environnement de travail du document associé, y compris tout contenu actif que le modèle peut contenir.

Figure 2. Document Word vide téléchargeant un modèle distant

Le fichier wordData.dotm comprend des macros malveillantes qui sont ensuite exécutées. (Selon la version de Microsoft Word, les macros VBA peuvent être désactivées par défaut; une action de l'utilisateur est alors nécessaire pour les activer.) Il contient également une archive ZIP intégrée que les macros ont déposée et extraite.

Comme le montre la Figure 1, les macros de wordData.dotm ouvrent un autre document (lmss.doc qui a été décompressé de l'archive extraite de wordData.dotm ). Les macros dans lmss.doc exécutent lmss.exe (le nouveau downloader Nim, de Zebrocy, également extrait de l'archive intégrée dans wordData.dotm) au lieu que wordData.dotm exécute directement le téléchargeur.

Cependant, il est important de noter que lmss.doc, contenant le code VBA qui exécute le nouveau téléchargeur Nim, intègre également un exécutable codé en base64. Selon les propriétés du document, lmss.doc a été créé en janvier 2019 et modifié le 20 août, quelques heures avant le début de cette campagne.

Figure 3. Dates de création et de dernière modification de lmss.doc

L'exécutable intégré dans lmss.doc est un downloader AutoIt (SHA-1 : 6b300486d17d07a02365d32b673cd6638bd384f3) utilisé dans le passé pour une campagne réalisée au moment de la création de lmss.doc. Ici, le téléchargeur AutoIt est ignoré et n'a pas d'autre but que d'agrandir la taille du document. L'opérateur a probablement oublié de supprimer l'ancien téléchargeur intégré. Ce ne serait pas la première fois que les opérateurs Sednit font des erreurs.

Les downloaders

Les opérateurs Sednit ont utilisé plusieurs téléchargeurs écrits dans différentes langues. Cette campagne utilise l'extension la plus récente de cette liste - un téléchargeur écrit dans la langue relativement nouvelle, Nim. Il s'agit d'un binaire de téléchargement et d'exécution simple avec deux petits détails ajoutés. La première est probablement utilisée comme mesure anti-sandbox et vérifie que la première lettre du fichier exécuté (la lettre l ici, ou 0x6C en hexadécimal) n'a pas changé.

Figure 4. Vérification du nom de fichier

La seconde est une sorte d'obscurcissement où l'opérateur remplace les lettres du caractère de remplissage d'une chaîne par les lettres correctes, avec des décalages définis. Comme le montre la Figure 5, le téléchargeur reconstruit la chaîne URL de téléchargement correcte avec cette méthode, pour éviter les outils d'analyse statique de base qui pourraient autrement localiser la chaîne URL.

Figure 5. Résultat Hex-Rays de la désobfuscation des chaînes de caractères

Par exemple, la chaîne o-ps-c..ll est « patchée » avec trois décalages, respectivement par s, v et d, pour donner ospsvc.dll. Quant à l'URL, à partir du début de la chaîne dans le downloader est h@@p://, les outils recherchant http:// ne pourront pas le détecter ainsi.

Le téléchargeur Nim récupère sa bibliothèque de liens dynamiques (DLL), nommée ospsvc.dll, dans C:\ProgramData\Java\Oracle\, et l'exécute comme service via regsvr32 /s.

ospsvc.dll  est un téléchargeur écrit en Golang, et différent des autres téléchargeurs Sednit observé auparavant.

Les précédents téléchargeurs Golang de Sednit ont été décrits en détail par d'autres chercheurs[1][2][3] et il semble que les développeurs de Sednit aient réécrit leur précédent téléchargeur Delphi dans Golang. Ces premiers téléchargeurs recueillent beaucoup d'informations sur l'ordinateur de la victime et les envoient à leur serveur C&C. Cependant, cette nouvelle version est assez légère en ce qui concerne ses capacités de collecte de données, comme nous le décrivons ci-dessous.

Sa fonction main_init() contient des librairies qui sont initialisées et n'ont pas besoin d'explications supplémentaires en raison de leur nom (vous pouvez consulter cet article pour plus d'informations).

 

 

 

 

 

Figure 6. Résultat Hex-Rays des fonctions initialisées dans main_init()en utilisant le plugin IDAGolangHelper

Puisque la DLL est exécutée comme un service, via le téléchargeur Nim, nous devons regarder main_DllRegisterServer() au lieu de main_main(). Les chaînes et la clé sont empilées et peuvent être déchiffrés en utilisant une simple boucle XOR. Ce chiffrement simple est assez efficace contre les outils qui extraient statiquement les chaînes de caractères empilées dans les binaires.

Figure 7. Résultat IDA Pro des chaînes de caractères chiffrées empilées

Outre le téléchargement de l'étape suivante du logiciel malveillant, la prise de captures d'écran du bureau de la victime et l'exécution des commandes reçues du serveur C&C sont les principales fonctions de ce logiciel malveillant.

Des captures d'écran sont prises toutes les 35 secondes pendant les premières minutes de l'exécution de ce downloader, puis elles sont envoyées au serveur C&C sous forme codée en base64. Le nom d'hôte et les valeurs %USERPROFILE% sont également envoyés au serveur C&C encodé en base64. La réponse du serveur C&C est également simple : il s'agit d'une concaténation de chaînes codées en base64, séparées par « | ».

<spaces>|<cmd to execute>|<name of the binary to drop>|<binary to drop>

Selon notre télémétrie, ce téléchargeur a été utilisé pour exécuter trois logiciels malveillants différents. Le premier est le dumper que nous avons décrit dans notre article précédent sur Zebrocy. La seconde est la porte dérobée Delphi habituelle - également exécutée en tant que service via la même commande que celle utilisée par le téléchargeur Nim. La troisième que nous avons vue est une nouvelle porte dérobée téléchargée et exécutée sur la machine de la victime, comme décrit dans la section suivante.

La nouvelle porte dérobée

Analyse

La nouvelle backdoor Zebrocy n'est pas écrite en Delphi, comme c’est généralement le cas, mais plutôt en Golang. A notre connaissance, c'est la première fois que cette porte dérobée a été vue, mais elle partage beaucoup de similitudes avec celle de Delphi.

En regardant à nouveau le code d'initialisation de la bibliothèque de la fonction main_init() (Figure 8) nous pouvons voir de nouvelles entrées. Un algorithme AES, un codage hexadécimal et des capacités de capture d'écran sont les principales entrées qui ont été ajoutées.

Figure 8. Différence entre les fonctions de la backdoor et du downloader initialisées dans main_init()

Notez que image_png_ini remplace image_jpeg_init dans la prise de captures d'écran. Les images au format JPG sont généralement plus petites que les images au format PNG.

La porte dérobée est démarrée avec un argument qui est une chaîne codée en hexadécimal. Tout sauf le dernier bloc de six octets de cette chaîne de caractères est chiffré en XOR, la clé étant stockée dans les six derniers octets de la chaîne. L'extrait de python suivant décrit la logique du déchiffrement.

key = arg[-6:].decode('hex')
enc = arg[:-6].decode('hex')
''.join(chr(ord(i) ^ ord(j)) for i, j in zip(itertools.cycle(key), enc))

C'est l'adresse du serveur C&C, qui est ensuite chiffrée et stockée sur disque. Ce chiffrement est effectué à l'aide de l'algorithme AES-128 ECB avec une clé générée à partir du nom d'hôte. Il n'est donc pas possible d'obtenir ce serveur C&C simplement en regardant le binaire. Il n'y a pas de persistance définie par les téléchargeurs comme nous l'avons vu dans le passé, et la porte dérobée ne dispose d’aucun mécanisme de persistance.

Cette nouvelle porte dérobée a diverses capacités qui ont également été vues précédemment dans la porte dérobée Delphi de Zebrocy :

  • manipulation de fichiers comme la création, la modification et la suppression de fichiers
  • capacités de capture d'écran
  • dénombrement des lecteurs
  • exécution des commandes (via cmd.exe)
  • programmation d’une tâche sous le nom suivant Windows\Software\OSDebug (que les opérateurs pourraient utiliser pour définir manuellement la persistance).

Comme dans la porte dérobée Delphi, il y a un ensemble très limité de commandes - mais la possibilité d'exécuter des commandes arbitraires via cmd.exe étend les possibilités comme la persistance ou la collecte d'informations.  Une autre similitude trouvée est un numéro de version à trois chiffres (dans le format x.y.z); la version majeure actuelle est 4.y.z.

Réseau

Le protocole réseau présente certaines similitudes avec la version Delphi de la porte dérobée.  La première interaction avec le serveur C&C récupère une clé AES 32 bits pour chiffrer les communications futures.  La capture de paquets de cette première requête ressemble à :

POST [REDACTED URI] HTTP/1.1
Host: [REDACTED IP]
User-Agent: Go-http-client/1.1
Content-Length: 297
Content‑Type: multipart/form‑data; boundary=b116f1e0a94eff1bb406531e74bb0feba65687cf90ec8a64fc409f230fbd
Accept-Encoding: gzip

--b116f1e0a94eff1bb406531e74bb0feba65687cf90ec8a64fc409f230fbd
Content-Disposition: form-data; name="filename"; filename="[REDACTED]"
Content-Type: application/octet-stream

1
--b116f1e0a94eff1bb406531e74bb0feba65687cf90ec8a64fc409f230fbd--

Ceux qui ont de l'expérience avec Sednit pourraient penser que les mots-clés Content-Disposition et boundary leur semblent familiers. Ils étaient auparavant utilisés par la porte dérobée Delphi dans son protocole réseau; elle utilise également l'algorithme AES pour chiffrer le pseudo body (formé avec les données de Content-Type). Notez que même si Content-Disposition  et la deuxième instance de Content-Type sont de véritables en-têtes HTTP, ici ils sont utilisés dans le corps du message HTTP. Le champ boundary est randomisé pour chaque échange et le champ de nom de fichier à l'intérieur du pseudo en-tête Content-Disposition peut être déchiffré avec l'extrait suivant de Python :

len_filename = len(filename)
len_key = 14
xor_key = filename[-len_key:].decode('hex')
filename = filename[:len_filename-len_key].decode('hex')
val_filename = ''.join(chr(ord(i)^ord(j)) for i,j in zip(itertools.cycle(xor_key),filename))
random_int = val_filename[-4:]

ce qui correspond à la chaîne suivante :

757365722D504318162020190821151055207C.inc

On peut ainsi mieux comprendre cette chaîne de caractères :

Username: 757365722D5043
SID*: 181620
Date: 20190821151055
Random: 207C.inc

* 6 octets proviennent des identificateurs de sécurité de l'utilisateur actuel (SID) S-1-5-21‑xxxxxxxxx‑yyyyyyyyyy‑zzzzzzzzzz‑1000

D'autres interactions avec le serveur C&C suivent ce modèle sauf que le pseudo corps, qui est 1 dans l'exemple ci-dessus, est remplacé par la sortie de la commande demandée par le serveur C&C. L'ensemble du corps du message est également chiffré, en utilisant le même algorithme AES utilisé précédemment, avec la clé fournie lors du premier échange.

Conclusion

Nouveaux downloaders, nouvelle backdoor - le groupe Sednit a été actif et ne laisse pas ses composants tomber en désuétude. Une grande nouveauté? Pas vraiment. En le regardant, il semble que le groupe Sednit est en train de porter le code original vers d'autres langues ou de le réimplémenter dans d'autres langues dans l'espoir d'échapper à la détection. C'est probablement plus facile de cette façon et cela signifie qu'ils n'ont pas besoin de changer leurs PTT en entier. Le vecteur de compromis initial reste inchangé, mais utiliser un service comme Dropbox pour télécharger un template distant est inhabituel pour le groupe.

ESET recommande aux utilisateurs d'être attentif lorsqu’ils ouvrent des pièces jointes provenant de courriers électroniques suspects.

Nous continuerons à rester informés sur les nouvelles activités du groupe Sednit. Pour ce faire, nous publierons des informations pertinentes sur notre blog. Pour toute demande de renseignements, contactez-nous à threatintel@eset.com.

Indicateurs de compromission (IoC)

Hashes (SHA-1) Filenames ESET detection names
c613fcccb380f7e3ce157c4f620efca503c1bad3 - (eml file) DOC/TrojanDownloader.Agent.AMY
6f281b30d8d6a9bc1dbe2fe73995aac382c4a543 612243236.docx DOC/TrojanDownloader.Agent.AMY
f3f945fb22916f82cb7407cde2a80a68cd83b074 wordData.dotm VBA/TrojanDropper.Agent.AIP
a56af5b44624e8ada60057fd7f39af5b3de10724 lmss.zip Win32/TrojanDownloader.Sednit.BK
b8ac400e1deb6e90fa4e2adb150c511c98bafc6e lmss.doc VBA/TrojanDropper.Agent.AIQ
f0793e02180f3ccf48e41bd67ec1161d93f07e01 lmss.exe Win32/TrojanDownloader.Sednit.BK
04303024ff453f918925d7160abbd199f137a442 ospsvc.dll Win32/Sednit.DI
c96db85ece2b57a9e82ba36b5f31ca9d2051a6f0 osppsvc.exe Win32/Sednit.DJ

Réseaux

https://www.dropbox[.]com/s/foughx315flj51u/wordData.dotm?dl=1

185.221.202[.]35

Techniques MITRE ATT&CK

Tactic ID Name Description
Initial Access T1193 Spearphishing Attachment Zebrocy is using spearphishing emails with an attachment as method of compromise.
Execution T1059 Command-Line Interface The Golang backdoor uses cmd.exe to execute commands.
T1117 Regsvr32 The Nim downloader uses regsvr32.exe to launch the Golang downloader.
T1053 Scheduled Task The Golang backdoor can create a pre-defined scheduled task.
T1064 Scripting The remote template contains VBA used to execute the next stage of the malware.
T1204 User Execution Zebrocy attempts to get users to click on Microsoft Office attachments containing malicious macro scripts.
Persistence T1053 Scheduled Task The Golang backdoor can create a pre-defined scheduled task.
Privilege Escalation T1053 Scheduled Task The Golang backdoor can create a pre-defined scheduled task.
Defense Evasion T1107 File Deletion The Golang backdoor can delete files.
T1117 Regsvr32 The Nim downloader uses regsvr32.exe to launch the Golang downloader.
T1064 Scripting The remote template contains VBA used to execute the next stage of the malware.
Discovery T1083 File and Directory Discovery The Golang backdoor can list drives.
Collection T1113 Screen Capture HTTP is used for C&C communications.
Command and Control T1043 Commonly Used Port All components are using port 80 to communicate with the C&C server.
T1024 Custom Cryptographic Protocol The Golang backdoor is using an XOR loop for its communications.
T1132 Data Encoding The Golang backdoor base64- encodes the data before encrypting it.
T1071 Standard Application Layer Protocol HTTP is used for C&C communications.
T1032 Standard Cryptographic Protocol The Golang backdoor encrypts communications with the C&C server with AES ECB.
Exfiltration T1022 Data Encrypted The Golang backdoor encrypts the data with AES ECB before sending it over the C&C server.
T1041 Exfiltration Over Command and Control Channel The Golang backdoor exfiltrates data to its C&C server.

Références :

[1] https://unit42.paloaltonetworks.com/sofacy-creates-new-go-variant-of-zebrocy-tool/
[2] https://securelist.com/a-zebrocy-go-downloader/89419/
[3] https://www.vkremez.com/2018/12/lets-learn-dissecting-apt28sofacy.html