
Pour ceux qui ont déjà assez joué avec les
puzzles crackme , nous avons apporté un nouveau cheval de Troie. Dans la nature, le téléchargeur Hancitor se trouve toujours dans son habitat naturel - les courriers indésirables. Actuellement, il est activement utilisé pour télécharger le cheval de Troie bancaire Panda, qui est une modification du fameux Zeus.
Par une froide soirée d'été, nous l'avons rencontré face à face, en train de regarder les courriers indésirables. Si vous aimez voir ce que le malware a sous le capot, lisez notre nouvelle analyse inverse.
Notre document malveillant ressemble à ceci:

Par défaut, les macros sont bloquées, donc le système avertit: "Les macros ont été désactivées." Cependant, le contenu du message indique que les macros doivent être incluses. Eh bien, faisons-le. Après avoir cliqué sur le bouton Activer le contenu, l'ordinateur est infecté. Voyons maintenant quel type de macro est exécuté et comment exactement l'infection se produit. Cela peut être fait immédiatement dans Word en allant dans l'onglet Affichage-> Vacros \ Afficher les macros.

Vous pouvez faire plus professionnellement - utilisez
olevba à partir du paquet oletools. Vous pouvez y installer le package sur le lien. Ensuite, tapez olevba doc_file –c –decode> source.txt et obtenez la macro source.

Par le code, je veux immédiatement dire que le cheval de Troie appartient à la classe des téléchargeurs. Le script se dégonfle de quelque part vers le Malwara. Pour le prouver, décodons les chaînes base64. Il est plus pratique pour nous de le faire immédiatement via hiew, afin de ne pas copier-coller cent fois. Pour ce faire, nous utilisons un plugin spécial, qui est décrit
ici . Voici ce qui s'est passé:

Il s'agit d'un script malveillant, divisé en deux parties et enregistré sous 1.hta. En principe, nous ne sommes pas particulièrement intéressés par son fonctionnement. C'est assez banal. Le seul point important est de déterminer l'URL à laquelle le fichier malveillant est téléchargé. Essayons de le retrouver, car ces informations peuvent être utiles à la
sécurité . Ils peuvent ajouter des règles de réseau pour bloquer les demandes à ces URL, ce qui peut sauver l'entreprise de l'infection.
Ha! Il n'y a aucun lien. Mais d'où vient le fichier 6.exe, qui démarre 1.hta? Il est temps de revoir notre fichier dock dans hiew, mais plus attentivement:

Oui, un exe-shnik est intégré au document du dock. Oui, et fortement emballé. Expliquons ce qui se passe. La macro dépose le script 1.hta malveillant dans le dossier Temp et le lance, et 1.hta, à son tour, lance 6.exe à partir de son répertoire. Il est clair que 6.exe est le même PE-shnik emballé que nous voyons à l'écran. Mais maintenant, nous nous demandons comment 6.exe baisse en% temp%. Et cela se produit en raison d'une fonctionnalité intéressante de la suite Microsoft Office. Le fait est que dans tout document OLE, tout autre fichier au format Ole10Native peut être incorporé.
Si c'est le cas, au démarrage, MS-Office lui-même dépose le fichier ainsi construit dans le dossier% temp% sous le nom spécifié dans l'en-tête de la structure Ole10Native. Jetons un coup d'œil à cet objet. Nous avons été aidés par le plugin pour le gestionnaire FAR -
OLE2Viewer . Nous ouvrons notre document malveillant dans le plugin, allons dans le répertoire ObjectPool \ _1593522492 et voyons ceci:

Copiez ce fichier (Ole10Native) et ouvrez-le dans la vue.

Ici, nous voyons sous quel nom notre objet OLE - 5c.pif tombera dans le dossier% temp%. Revenons maintenant à notre macro. Sa tâche consiste à lancer un exe-shnik ivre.

En fait, pour être précis, la macro ne démarre pas toujours le fichier déposé via 1.hta, mais aussi comme ceci: Shell "cmd.exe / c ping localhost -n 100 &&" & Environ ("Temp") & "\ 6 .pif ", vbHide

La méthode de lancement, comme nous le voyons, dépend de la présence des processus suivants dans le système: bdagent.exe et PSUAMain.exe. Pourquoi alors avez-vous besoin de ping localhost -n 100? Et c'est une astuce grecque ancienne pour créer un retard artificiel, au cas où. Habituellement, ses variantes sont utilisées pour l'auto-suppression.
À ce stade, nous avons examiné le fonctionnement d'un document malveillant. Il nous est apparu clairement que le document lui-même n'appartient pas à des logiciels malveillants de type Trojan-Downloader, comme il semblait à première vue, mais convient au type de Trojan-Dropper. Voici ce qui s'est passé au démarrage:

Il reste maintenant à démonter la charge utile elle-même. Nous avons déjà réalisé que notre cheval de Troie est emballé, nous devons donc le déballer d'abord. Habituellement, ce processus est divisé en deux étapes:
1. Suppression du vidage décompressé + restauration de la table d'importation.
2. Analyse et purification des variables globales.
Nous avons besoin de la deuxième étape car il existe de nombreuses fonctions API qui, à la suite de leur travail, nous renvoient des valeurs non répétitives. Par exemple, CreatHeap nous renverra un descripteur de tas, qui sera ensuite utilisé pour le travail. Très souvent, il y a des vérifications de type dans le code:
si le descripteur de tas == 0, alors obtenez le descripteur de tas, sinon utilisez-en un déjà initialisé . Mais au moment du vidage, la variable contenant le descripteur donné était déjà initialisée par lui et à ce moment le descripteur était valide. Lorsque nous essayons de démarrer le vidage, la variable avec notre descripteur contiendra l'ancienne valeur, c'est-à-dire non égale à 0, ce qui signifie que le test passera.
Après cela, dès que le programme essaie d'utiliser ce descripteur, le système d'exploitation lèvera une exception et le programme se bloquera avec une erreur. Donc, pour éviter cela, vous devez mettre à zéro ces variables. Ils sont généralement situés dans une section accessible en écriture des données. Vous suggérez probablement d'ouvrir cette section dans l'éditeur hexadécimal et de tout écraser avec des zéros? Vous avez en partie raison, mais vous ne devez pas prendre de mesures irréfléchies. Il existe des chevaux de Troie qui vérifient les variables non pas sur 0, mais sur un DWORD aléatoire. Et selon que le test est testé ou non, diverses actions sont prises. Vous n'avez pas besoin d'aller loin pour des exemples. Il suffit de regarder le
Cridex (récemment, il a disparu quelque part des radars, apparemment il a été complètement mis à niveau vers EMOTETA).
Exécutons donc notre exemple (dans une machine virtuelle, bien sûr). Il est également souhaitable que le trafic sortant de la machine virtuelle passe par un VPN.
Nous lançons notre cheval de Troie et il se bloque simplement dans le processus. Super! En règle générale, les chevaux de Troie font les choses rapidement, puis s'arrêtent immédiatement et s'autodétruisent. Par conséquent, vous devez rechercher des emplacements dans le code responsables de ces actions, y mettre une pause, puis effectuer un vidage. Dans notre cas, nous pouvons le faire comme ça.
Pour le vidage, nous utilisons le merveilleux utilitaire - Process Dump, qui peut être trouvé
ici . Cet utilitaire non seulement trouve tous les modules exécutables cachés et les vide, mais restaure également la table d'importation elle-même. L'utilitaire doit être exécuté en tant qu'administrateur de la manière suivante: pd / pid xxxx, où xxxx est l'ID du processus cheval de Troie. Après cela, l'utilitaire vide tous les modules de processus. Nous avons supprimé les supplémentaires et voici ce qui reste:

Le nom du fichier exécutable du processus cheval de Troie est 1.exe. Il s'avère que le cheval de Troie déballé était situé à 0x2C0000. Ouvrez-le ici:

Juste un œil heureux! Maintenant, le fichier est décompressé, il est clairement visible. La table d'importation a également été reconnue. Ouvrons-le dans IDA-PRO.

Nous avons déjà renommé certaines fonctions lors du tri de l'échantillon. La première chose que le cheval de Troie commence par déterminer l'adresse de chargement de son module. Et vraiment: comment savait-il à quelle adresse son talon était déballé? Cela se fait avec une ancienne technique éprouvée - retourner une page mémoire à 0x1000 par rapport à l'adresse actuelle jusqu'à ce que nous rencontrions les octets "MZ". Cela fonctionne car les modules exécutables chargent toujours le système d'exploitation à une adresse qui est un multiple de 0x1000. Vérifiez par vous-même. Dans notre cas, une limite de 100 décapage est fixée.

Si quelqu'un ne comprend pas où il y a un retournement, voici où:
result + = 0xFFFFF000 est équivalent à result - = 0x1000.
Après avoir reçu l'adresse de téléchargement de son module, le cheval de Troie déballé reçoit les adresses des fonctions nécessaires à son fonctionnement. Pour commencer, les adresses de deux fonctions sont recherchées - LoadLibraryA et GetProcAddress. Connaissant les adresses de ces fonctions, vous pouvez les utiliser pour obtenir tout le reste. Ces fonctions se trouvent dans la bibliothèque kernel32. Son adresse est obtenue en lisant le premier élément (zéro - ntdll, première base de noyau, etc.) de la liste en anneau qui décrit tous les modules chargés dans l'ordre d'initialisation avec la structure _LDR_DATA_TABLE_ENTRY. Le pointeur vers la liste est extrait du PEB.

Après avoir reçu l'adresse kernel32.dll (à partir de Windows 7 - kernelBase.dll), le cheval de Troie peut analyser manuellement sa table d'exportation et trouver les deux fonctions nécessaires, qui sont exécutées de manière prévisible dans le sous-programme sub_EF1E60.

Jetez maintenant un œil à la fonction que nous avons appelée getHeap.

Ici, nous observons uniquement la situation décrite ci-dessus. Au moment du vidage, la variable hHeap contenait une valeur de 600000h. Par conséquent, GetProcessHeap ne sera pas appelé. Au lieu de cela, le programme ira à l'étiquette loc_EF11DD, où HeapAlloc est appelé avec un handle non valide, ce qui nous donnera une erreur. Par conséquent, nous prenons l'éditeur hexadécimal et mettons à zéro ce nombre. Nous avons compté six endroits similaires.
Ensuite, le plaisir commence. Le cheval de Troie génère un ID «client» unique basé sur le numéro de série du disque dur et l'adresse MAC. Informations reçues ici:

Nous obtenons également les informations suivantes: adresse IP, version du système d'exploitation, nom du réseau et nom d'utilisateur. Sur la base de tout cela, une requête HTTP est générée vers le panneau d'administration, dont nous ne connaissons pas encore l'adresse. Ce n'est pas dans les lignes (même sous la forme déballée). Mais il n'est pas là, car il est chiffré dans la configuration. Son adresse peut être extraite du code:

La configuration pèse 0x2008 octets et a le format suivant: les 8 premiers octets sont la clé RC4, 0x2000 octets sont les données cryptées.

Le fait que l'algorithme de chiffrement RC4 soit utilisé ressort clairement de la liste suivante:

Veuillez noter que les 8 premiers octets seuls ne sont pas la clé de RC4. La clé est le hachage SHA1 de ces octets. Vous devez également faire attention au drapeau 0x280011 de la fonction CryptDeriveKey. MSDN a un avertissement concernant ce drapeau:

De là, il devient clair que les 16 bits de poids fort de ce drapeau définissent la taille de clé en bits. Autrement dit, en octets, la taille de la clé est: (0x280011 >> 16) / 8 = 5. Par conséquent, la clé sera les cinq premiers octets du hachage des huit premiers octets de la configuration. Videons la configuration et écrivons un script python qui le décryptera pour nous. Le script ressemble à ceci:

Le résultat de son travail a été le fichier config.rc4. Ouvrez-le ici:

Nous voyons une liste déchiffrée des zones d'administration. Le premier mot est «19nep07» - numéro de build. 16 octets lui sont alloués. Ensuite, une liste d'URL d'administration séparées par "|".
Ainsi, le premier appel au panneau d'administration aura ce format:
GUID = 3068075364164635648 & BUILD = 19nep07 & INFO = WIN-56G04BL06SL @ WIN -56G04BL06SL \ Reverse & IP = 35.0.127.52 & TYPE = 1 & WIN = 6.1 (x32

Ensuite, la demande générée est envoyée en premier dans la liste du panneau d'administration.

Ensuite, la réponse de l'administrateur est lue, bien sûr, si elle est toujours vivante. La réponse doit être codée en base64. Si ce n'est pas le cas, le prochain administrateur de la liste est pris. Parfois, les administrateurs en direct renvoient une réponse étrange:

C'est familier, non? Oui, ce sont les mêmes
chiffres ! En fait, un auteur sait pourquoi l'administrateur commence à les renvoyer! Sous forme normale, la commande revient. Malheureusement, il est impossible de dire avec certitude quel sera le format de réponse, car il n'y a pas de trafic, tous les administrateurs sont morts. Le fichier décodé est également décodé en 0x7A:

La réponse doit contenir une commande. Si ce n'est pas le cas, il y a un appel au prochain panneau d'administration. Le code de commande est codé comme "x:", où x est la lettre codant une commande spécifique. Il y en a 7: «r», «l», «e», «b», «d», «c», «n». Considérez les commandes «b» et «r».
Les gestionnaires de ces commandes ont la même fonction. Nous l'avons nommé comme GetExe. Voici à quoi ça ressemble:

Je pense que tout est clair ici. Le cheval de Troie fait une requête http et le fichier exécutable est retourné en réponse sous une forme compressée, qui est ensuite décompressée. Des variations sont alors possibles. Dans le cas de la commande «b», les trois actions suivantes se produisent:
1. Création du processus svchost sous forme figée
2. Injection dans l'espace d'adressage du processus de module téléchargé
3. Contrôle du transfert vers le module injecté
Dans le cas de la commande r, les trois actions suivantes se produisent:
1. Téléchargement du fichier exécutable en appelant la fonction GetExe.
2. Enregistrement du fichier téléchargé dans un dossier temporaire sous un nom aléatoire.
3. Lancez un fichier déposé.

Terminé
PS La prochaine fois, nous pourrons analyser le Panda ou un crypteur. Écrivez dans les commentaires les logiciels malveillants qui vous intéressent le plus (à des fins de recherche, bien sûr).