Michael: Je souhaite la bienvenue à tout le monde, je suis Michael Lai, voici Matthew Richard, vous pouvez l'appeler Matt ou Richard, car il a deux noms, mais cela n'a pas d'importance.
Matt: Le sujet de notre conversation d'aujourd'hui est le ridicule des logiciels malveillants, et c'est exactement ce que nous essayons de faire.

Donc, tous ceux qui écrivent le code ne le font pas bien, les gens font beaucoup d'erreurs. Et tous ceux qui utilisent le virus ne le font pas correctement. Il y a aussi des gens qui échouent dans ces deux cas. Alors asseyez-vous plus confortablement, détendez-vous et écoutez, peut-être que ces informations vous seront utiles.
Au cas où, nous avons inclus des éléments techniques factuels dans la présentation afin que vous appreniez au moins quelque chose si la conversation ne vous semble pas drôle. Je note que ce n'est que notre opinion, qui peut ne pas coïncider avec celle de nos employeurs.
Michael: La première histoire s'appelle "Chérie, j'ai réduit l'entropie!" Elle raconte comment l'auteur de Silent Banker, un algorithme de chiffrement très complexe, a oublié de créer l'entropie en utilisant PRNG - un générateur de nombres pseudo aléatoires. Sur la diapositive, vous voyez un extrait de code Zeus de septembre 2007 dans lequel PRNG est utilisé pour empêcher la détection basée sur le hachage. La génération consiste à lancer cette variable globale appelée ddTickCount: tout d'abord, elle la place dans le registre EAX, d'où la fonction est appelée pour la première fois. Ensuite, il est vérifié si la valeur de la fonction est égale à zéro, et si elle n'est pas égale, alors TickCount est appelé pour générer SEED, c'est-à-dire pour initier un nombre pseudo-aléatoire, à l'aide de la commande GetTickCount.

Nous n'avons pas été surpris lorsque nous avons vu les similitudes avec ce code dans le fichier binaire Silent Banker de février 2008. Il utilise PRNG pour générer des noms de fichiers temporaires. Ici aussi, il y a la même variable globale ddTickCount, qui vérifie s'il y a un zéro, et si c'est le cas, alors un nombre pseudo-aléatoire est initié à l'aide de GetTickCount. Tout d'abord, avant de voir msvsrt rand, le générateur de nombres pseudo-aléatoires utilisé par la fonction rand () de la bibliothèque Microsoft C Runtime Windows, je pensais qu'il y avait une connexion entre l'auteur Zeus et l'auteur Silent Banker, uniquement basée sur des nombres HEX codés en dur dans un fichier binaire . Mais en fait, ils étaient tous deux liés statiquement à msvsrt.
Nous arrivons maintenant à la recette du désastre. Il s'agit d'un extrait de code de la version Silent Banker de juillet 2008, publié quelques mois après la version de février.

Ils ont mis à jour leur code et publié une nouvelle version de Silent Banker, qui était considérablement différente de ce que nous avons vu plus tôt. Dans ce programme, PRNG est utilisé pour générer une clé de chiffrement. Ici, vous ne voyez plus qu'une variable globale appelée CurrentSeed est vérifiée pour une égalité à zéro et qu'un nombre pseudo-aléatoire est généré en fonction de cela, il est simplement utilisé dans ce code.

Il est possible que quelque part dans le fichier binaire, même avant cet endroit, la valeur de cette variable globale soit générée sous la forme d'un certain type de nombre. Je passe donc au démontage de ce code et vois si la valeur CurrentSeed est utilisée ailleurs dans le programme avant d'être utilisée dans cette fonction rand (). Vous voyez qu'initialement dd part de zéro, et nous allons vérifier les références croisées à cette variable.

Dans la colonne T, la valeur w signifie qu'il n'y a qu'une seule opération valide pour cette variable globale dans tout le fichier binaire - c'est la fonction rand elle-même. Je vais passer en revue ces choses couramment car elles ont déjà été mentionnées lors de la DefCon de l’année dernière. Sur la diapositive «Recipe for Disaster», la ligne Seed the PRNG, ou «Initiation of a Pseudo Random Number Generator», est affichée en gris pour indiquer que l'auteur de Silent Banker n'a pas effectué cette initiation.

L'étape suivante consiste à générer une clé de 16 octets, effectuant 1000 appels système à la fonction MyRand (). Ensuite, à partir d'une clé de 16 octets, ils génèrent un nombre de 8 octets - la clé, à l'aide d'une formule spécifique.
Après cela, ils génèrent un autre numéro de 8 octets pour créer une clé secondaire à partir du premier numéro de 8 octets, y ajoutent une valeur arbitraire à partir du fichier de configuration INI et obtiennent une clé tertiaire, qui est également un nombre de 8 octets. Enfin, ils utilisent une fonction mathématique de précision arbitraire pour transformer une clé de 8 octets en une clé de 32 octets.
Après cela, ils chiffrent les données volées telles que le mot de passe de l'utilisateur à l'aide de la clé d'origine de 16 octets. Mais ils ne transmettent pas ce nombre de «16» octets à «leur» attaquant avec les données volées, car envoyer la clé avec le message chiffré n'est pas une bonne idée. Au lieu de cela, l'auteur de Silent Banker place un numéro de 32 octets dans les données volées et l'envoie au destinataire, qui devrait avoir un programme qui reconvertit ce numéro en clé d'origine de 16 octets. Cependant, nous n'avons pas ce programme!
La diapositive suivante montre une recette pour utiliser cette catastrophe avec le numéro 1 - le manque d'un générateur PRNG - à votre avantage.

Pour commencer, nous assimilons la valeur de PRNG à zéro. Nous pouvons automatiser les quatre étapes suivantes à l'aide d'un script Python pour le débogueur, car nous avons une formule qui calcule une clé de 16 octets, une clé de 8 octets, la clé de 8 octets suivante et une clé de 32 octets. Cette formule n'est pas dans le code C, mais nous l'avons parce que nous avons une copie du fichier binaire Silent Banker dans laquelle elle existe.
Je vais vous montrer une démonstration du fonctionnement de ce script Python. Nous avons un bon scénario: ici, j'ai Silent Banker et un débogueur indépendant auquel je suis attaché, ainsi qu'Internet Explorer, dans lequel s'exécute Silent Banker. J'ai noté quatre fonctionnalités qui génèrent des clés de cryptage. J'inclus ce script Python montré dans la diapositive précédente, que j'invoque avec la commande bang keygen. Vous pouvez voir que le débogueur "perd" simplement ces quelques fonctions que je veux effectuer pour cette démo 5 fois. Mais dans la vraie vie, nous avons effectué cette action 5000 fois pour obtenir un plus grand jeu de clés.
Sur le panneau de journal, vous pouvez voir que pour chaque itération de la boucle, une clé primaire de 16 octets est sortie, qui est ensuite associée à une clé de 32 octets. En même temps que le script imprime des informations dans le journal, un fichier texte est également créé sur le disque, qui comprend des paires de clés associées de 16 et 32 octets. Il s'agit simplement d'un fichier hexadécimal HEX, nous pouvons donc utiliser notre script Python pour traiter ce fichier, nous avons également un répertoire de journaux que nous avons récupéré à partir du nœud de commande et de contrôle volé.

En haut, vous voyez plusieurs certificats de clés privées chiffrées, et en dessous, plusieurs fichiers texte contenant des données chiffrées. Nous pouvons simplement exécuter le programme et rechercher à l'intérieur de ces fichiers texte en extrayant cette clé de 32 octets et la clé d'origine de 16 octets qui lui est associée.
Dès que le programme trouve une clé de 16 octets, il déchiffre les informations qu'il contient et les présente sous la forme d'un fichier texte. Vous voyez ce fichier à l'écran et il est impossible de le lire.

Mais alors nous avons un tas de fichiers temporaires .tmp lisibles, d'où nous pouvons obtenir ces informations et les renvoyer aux propriétaires "légitimes". Ainsi, tout le travail acharné pour protéger les informations a été fait par Silent Banker en vain car ils ont oublié de lancer un générateur de nombres pseudo-aléatoires.

Maintenant, je vais montrer la meilleure partie de ce qui précède - c'est la fonction Silent Banker, que j'ai appelée Why_Not_Use_This (pourquoi ne pas l'utiliser?).

En fait, à l'intérieur de leur propre programme, ils ont la fonction GetCursorPos (déterminer la position du curseur) pour générer l'entropie, qui peut être utilisée pour lancer PRNG, et nous pouvons vérifier les références croisées à cette fonction à l'intérieur du programme.

Nous voyons qu'il est utilisé dans 10 à 15 autres endroits du code. Ainsi, il s'avère que les auteurs de Silent Banker n'ont pas oublié d'insérer un générateur de nombres pseudo-aléatoires dans le programme, ils ont simplement oublié d'exécuter cette fonction dans le processus de cryptage en utilisant l'opérateur d'appel.

La diapositive suivante s'intitule "Ça s'est échappé ..." et elle montre comment ce programme fonctionnerait si l'auteur n'avait rien oublié.

L'histoire suivante, intitulée «DES ou pas DES», concerne un auteur de malware qui ne sait même pas comment utiliser correctement l'interface de programmation Windows ou ne sait pas quelle est la taille maximale de la clé DES. Par conséquent, en raison de la taille non valide de cette clé, son cheval de Troie est utilisé par défaut avec l'opérateur logique xor.
Ainsi, pour la fonction d'interface du programme CryptDeriveKey, les deux octets faibles du paramètre dwFlags, indicateurs qui définissent l'apparence de l'URL résultante, déterminent la taille de votre clé de chiffrement.

Donc, si les octets faibles sont 0080, la clé de chiffrement que nous demandons sera une clé RC4 de 128 bits. C'est la même chose que de se tirer une balle dans le pied, et je vais vous montrer pourquoi.

Sur la diapositive, vous voyez une ligne avec la mauvaise taille de la clé dwFlags 128 bits - 800000 et une ligne avec la mauvaise valeur MSCryptoAPI. Je vais vous montrer le démontage de cette chose. Vous voyez une fonction appelée «initialisation du sous-système de chiffrement»: le cheval de Troie appelle le contexte chiffré, puis crée un conteneur pour le hachage MD5, puis crée un hachage MD5 du mot de passe codé en dur dans le fichier binaire et essaie d'utiliser la sortie de cette fonction de hachage pour créer une clé DES de 128 bits. Cependant, aucune clé n'est créée dans ce cas, car il n'existe pas de clé DES 128 bits.

Si l'une de ces fonctions API échoue, elle saute à cet endroit, que j'ai marqué en jaune, et affiche un message indiquant que la clé ne peut pas être reçue. Et cet endroit est ici, où il déplace la valeur qui est en ebp et à ce moment-là 0, c'est-à-dire directement dans cette valeur booléenne bUseMSCryptoAPI.
Voyons quel effet cela provoque lors de l'exécution du programme. Nous suivrons cet élément de la structure du code pour voir où il est utilisé dans le programme et comment se comporte cette exposition de cheval de Troie lorsque la fonction est vraie et lorsque la blessure est fausse.

Nous voyons que la valeur logique est vérifiée dans la fonction que j'ai appelée chiffrer les données, «chiffrement des données», et si c'est vrai, il s'agit de ce bloc, où le chiffrement DES et CryptEncrypt MSAPI sont utilisés.

Cependant, si cette valeur est 0, et comme nous le savons, elle sera toujours au début zéro, la fonction va à ce bloc, qui par défaut est xor.

J'étais curieux de savoir à quel moment l'auteur du programme malveillant a décidé de sauvegarder tout cela. Peut-être que les gens le poussaient d'en haut, il a donc été obligé de se débarrasser des logiciels malveillants, mais à la dernière minute, il s'est rendu compte que son DES ne fonctionnait pas, il a donc utilisé xor pour l'enregistrement de sauvegarde. Dans l'ensemble, c'était assez drôle, donc la morale de cette histoire est de toujours faire des sauvegardes!
L'histoire suivante s'intitule «Qu'avez-vous fait de quoi?». J'ai essayé de trouver un terme décrivant le fonctionnement du cryptage du cheval de Troie Coreflood et j'ai décidé de l'appeler «cryptage dépendant de l'emplacement». Bref, les auteurs de ce cheval de Troie ont inventé une nouvelle méthode de cryptage. J'ai pensé, peut-être que quelqu'un a déjà écrit un article à ce sujet et que ça devrait être "google"? Google m'a donné un lien vers un site de brevets américain où quelqu'un a déposé un brevet pour le "cryptage dépendant de l'emplacement". Ce schéma est assez déroutant, il faudra donc beaucoup de temps pour l'étudier. Voici comment cela fonctionne: je vous envoie un message crypté, et pour le décrypter et le lire, vous devez prendre un appareil GPS et vous rendre à un point avec la latitude et la longitude que j'ai indiquées. En règle générale, le chiffrement est un compromis entre sécurité et convivialité, mais il n'y a ni l'un ni l'autre dans cette méthode.

Ce n'est certainement pas sûr et vous oblige à aller là où l'expéditeur pointe pour lire le message. Matt a plaisanté en disant que si vous vous battez en ligne par e-mail et que vous voulez vraiment vous débarrasser de quelqu'un, envoyez-lui un message crypté qu'il peut lire quelque part en Irak, et vous n'aurez plus de problèmes avec lui.
Comment cette méthode est-elle utilisée dans le cheval de Troie Coreflood? La diapositive montre un fragment de code à partir duquel il s'ensuit qu'après que le cheval de Troie a volé des informations sur l'utilisateur, il les chiffre et les écrit sur le disque afin que le cheval de Troie puisse plus tard recevoir ces informations et télécharger la commande et le contrôle sur son site Web.
Cette fonction est appelée SetFilePointer (définir le pointeur de fichier) et sa valeur de retour est dWord, indiquant le décalage dans le fichier sur lequel le pointeur a été défini s'il a été dépassé. Ensuite, la fonction prend le nombre d'octets pour crypter nNumberOfBitesToWrite et le déplace vers le registre ecx. Elle prend ensuite le pointeur de données pour le chiffrement et le déplace vers le registre edx.

Après cela, l'opérateur xor est utilisé, ce qui place chaque octet dans le tampon al et ah, ce qui signifie des octets de bas et haut niveau renvoyés par SetFilePointer. Ainsi, la clé de chiffrement dans ce schéma est le décalage dans le fichier dans lequel les données existent. C'est tout simplement incroyable!
La diapositive suivante est intitulée «Comment réinitialiser un vidage de mémoire». Il représente le programme dumpCore que je viens d'écrire et qui vient de sortir. Vous pouvez le télécharger, il y a tout le code source. Ce programme vous aidera si l'ordinateur est infecté par le virus Coreflood, qui, pour une raison quelconque, n'a pas pu accéder au serveur de commande et de contrôle pour télécharger les données volées. Vous pouvez donc obtenir ces fichiers qu'il a enregistrés sur le disque et les décrypter en utilisant mon programme pour savoir ce qui vous a été volé, par exemple, si vous devez en informer le client.
Les journaux des données volées sont encerclés en rouge sur la diapositive.

Ce qui est toujours intéressant dans Coreflood: bien qu'il ait un algorithme de chiffrement assez faible, il essaie toujours de transférer toutes les informations volées sur la configuration informatique de la victime, toutes les informations cibles des banques et des coopératives de crédit, etc. Ainsi, une autre façon de supprimer un vidage de mémoire est appelée «Comment supprimer un vidage de mémoire à l'aide de Wireshark». Wireshark est un programme qui analyse le trafic réseau Ethernet ou le flux de données TCP.

La diapositive suivante montre le fonctionnement de Coreflood. Ce sont des DLL qui sont entrées dans Explorer et Internet Explorer. Ils modifient le registre, nécessitent un redémarrage de l'application, mais ne nécessitent pas de redémarrage du système. Il existe différentes façons d'injecter ces DLL dans un processus.

La façon dont le virus pénètre dans l'ordinateur de l'utilisateur est importante pour les pirates qui souhaitent envahir le virus: faut-il un redémarrage du système pour que le logiciel malveillant ait un effet, ou suffit-il que l'utilisateur redémarre simplement l'application, dans ce cas, l'Explorateur.
Et maintenant, c'est calme pour que personne n'entende!

C'est le code que nous avons reconstruit en utilisant la rétro-ingénierie. Cela montre comment Coreflood arrête manuellement Explorer afin que les modifications prennent effet immédiatement. Vous savez probablement ce qui se passe lorsque l'explorateur échoue sur l'ordinateur - la barre des tâches disparaît, les fenêtres de toutes les applications ouvertes, toutes les icônes du bureau disparaissent, puis, une à une, elles commencent à revenir à leur place.
Les auteurs de Coreflood étaient évidemment au courant de cela, ils ont donc placé un appel système à cet endroit pour définir le mode d'erreur "correct" du conducteur juste avant l'appel OpenProcess.
Que fait la fonction SetErrorMode? Il empêche une défaillance spécifique des notifications envoyées au système qui créent une petite fenêtre contextuelle et envoient un message d'erreur qui a conduit à la fermeture de l'application. Tout ce qu'ils ont fait avec ce message d'erreur était d'empêcher une fenêtre contextuelle d'apparaître à l'utilisateur avant l'échec d'Explorer. Dites-moi ce qui semble plus suspect à l'utilisateur: une petite fenêtre pop-up accompagnée de la disparition de tout ce qui apparaît à l'écran puis réapparaît, ou de la disparition et de l'apparition de tout sans aucun message d'erreur? Je vous entends dire: «les deux événements».
La diapositive suivante que j'ai intitulée «Avec les bras et les jambes, mais sans tête». Coreflood, lorsqu'il est chargé en tant que dll, n'apparaît pas dans la liste des modules chargés. Il alloue un peu de mémoire sur le tas et se copie à cet endroit du tas - je l'ai mis dans un cadre rouge.

Puis il supprime son en-tête PE, donc si vous rencontrez un ordinateur infecté par ce cheval de Troie, dites alors: "ma prochaine étape devrait être de vider ce fichier exécutable et de le télécharger vers l'IDA pour analyse", mais il est très difficile de vider le fichier exécutable, s'il n'y a pas son en-tête PE. Ainsi, lorsque Coreflood appelle virtual alloc, il définit l'indicateur mem de haut en bas, ce qui oblige le système à renvoyer l'adresse la plus élevée et non la plus basse disponible. Cela permet au cheval de Troie de masquer les guillemets d'ouverture / de fermeture dans une zone de mémoire supérieure du mode utilisateur parmi les autres DLL du système. Par conséquent, la prochaine démo que j'ai intitulée "Comment rendre inutile tout ce qui est caché."

Lorsque vous rencontrez quelque chose comme Coreflood qui utilise la furtivité et qu'il n'y a pas d'outils prêts à l'emploi pour travailler avec de tels virus, vous devez créer le vôtre.
Si vous êtes familier avec le déballage, l'utilisation d'un débogueur est courante pour vous. Surtout s'il n'y a pas de décompresseur automatique, car ce n'est pas un algorithme commun. Dans ce cas, vous pouvez utiliser le débogueur pour accéder au point d'entrée d'origine, puis supprimer le vidage du cheval de Troie à l'aide de ProcDump ou d'un autre utilitaire. PE Import Reconstructor, , , .
, . . Volatility, Internet Explorer . , Coreflood, , . , 7FF81000.

, HEX , Coreflood. , , . .
, , Coreflood, Volatility . , ID Internet Explorer. , , PID 1732. Malfind, , , , . VAD , , . , .

, , 7FF81000. , Fix IAT, PID 1732 Internet Explorer , Coreflood.
dll, Internet Explorer, , RBA , , .
Il désassemble ensuite toutes les informations, à partir de la zone de mémoire à 7FF81000, et recherche les appels système qui conduisent à l'une de ces fonctions exportées. Ainsi, il recrée la table des adresses importées même sans en-têtes PE. Vous voyez que le résultat émis par lui ressemble au résultat d'Import Reconstructor: il y a un module, la première fonction et chaque fonction importée des modules. La sortie de ce script Fix IAT n'est pas exécutable, vous pouvez donc l'ouvrir dans la visionneuse de modification PE et voir que la table d'importation a été correctement restaurée.
21:15
Conférence DEFCON 17. Riez de vos virus! 2e partieMerci de rester avec nous. Aimez-vous nos articles? Vous voulez voir des matériaux plus intéressants? Soutenez-nous en passant une commande ou en le recommandant à vos amis, une
réduction de 30% pour les utilisateurs Habr sur un analogue unique de serveurs d'entrée de gamme que nous avons inventés pour vous: Toute la vérité sur VPS (KVM) E5-2650 v4 (6 cœurs) 10 Go DDR4 240 Go SSD 1 Gbps à partir de 20 $ ou comment diviser le serveur? (les options sont disponibles avec RAID1 et RAID10, jusqu'à 24 cœurs et jusqu'à 40 Go de DDR4).
VPS (KVM) E5-2650 v4 (6 cœurs) 10 Go DDR4 240 Go SSD 1 Gbit / s jusqu'en décembre gratuitement en payant pour une période de six mois, vous pouvez commander
ici .
Dell R730xd 2 fois moins cher? Nous avons seulement
2 x Intel Dodeca-Core Xeon E5-2650v4 128 Go DDR4 6x480 Go SSD 1 Gbps 100 TV à partir de 249 $ aux Pays-Bas et aux États-Unis! Pour en savoir plus sur la
création d'un bâtiment d'infrastructure. classe utilisant des serveurs Dell R730xd E5-2650 v4 coûtant 9 000 euros pour un sou?