L’affaire de la backdoor XZ : premiers résultats d’analyse
(securelist.com)- La backdoor XZ Utils/liblzma a été révélée le 29 mars 2024 sur la liste de diffusion Openwall OSS-security, et l’objectif final de l’attaquant était très probablement d’implanter une capacité d’exécution de code à distance dans le serveur OpenSSH sshd des distributions basées sur systemd
- La chaîne d’infection reposait sur une injection en plusieurs étapes utilisant des fichiers de test et l’infrastructure de build du dépôt XZ ; via
build-to-host.m4,bad-3-corrupt_lzma2.xzetgood-large_compressed.lzma, un fichier objet malveillant était lié àliblzmapendant la compilation - Les versions XZ 5.6.0 et 5.6.1 contenant la backdoor ont été distribuées dans des builds bêta et expérimentaux de certains grands fournisseurs, et CVE-2024-3094 a reçu un score de criticité de 10
- La backdoor binaire se charge en détournant l’IFUNC de GLIBC et le chemin d’appel
cpuid, puis tente de surveiller les connexions de la machine infectée en hookant des fonctions liées à OpenSSL/libcrypto - Le code malveillant vérifie si
/usr/bin/sshdest en cours d’exécution ainsi qu’une variable d’environnement servant de kill switch, et complique l’analyse et la détection grâce à un traitement de chaînes basé sur un trie, à une résolution dynamique des symboles et à un patch runtime dertdl-audit
Vue d’ensemble de l’incident et périmètre d’impact
- La découverte de la backdoor XZ a été rendue publique le 29 mars 2024 via un message sur la liste de diffusion Openwall OSS-security
- XZ est un utilitaire de compression intégré à plusieurs grandes distributions Linux
- Le cœur du risque tient au fait que
liblzma, qui contenait la backdoor, pouvait être liée au processus du serveur OpenSSHsshdsur certaines distributions basées sur systemd- Ubuntu, Debian et RedHat/Fedora Linux ont patché OpenSSH pour utiliser des fonctionnalités de systemd, ce qui le rend dépendant de cette bibliothèque
- Arch Linux et Gentoo sont considérées comme non affectées
- L’objectif final de l’attaquant était très probablement d’ajouter une fonctionnalité d’exécution de code à distance via sshd que personne d’autre ne pouvait utiliser
- Contrairement à d’autres attaques de chaîne d’approvisionnement centrées sur un unique patch malveillant, un faux paquet ou un paquet de typosquatting, cet incident s’apparente davantage à une opération en plusieurs étapes qui a failli réussir à compromettre des serveurs SSH dans le monde entier
Comment la backdoor a été introduite
- La backdoor
liblzmaa été injectée à deux niveaux, en exploitant à la fois le processus de build et des fichiers de test- Le code source de l’infrastructure de build qui génère le paquet final a été modifié par l’ajout de
build-to-host.m4 - Des scripts et composants binaires cachés dans des fichiers de cas de test étaient extraits pendant le build
- Le code source de l’infrastructure de build qui génère le paquet final a été modifié par l’ajout de
- Le flux d’infection tournait autour de trois fichiers
build-to-host.m4: script de build qui extrait le script de l’étape suivantebad-3-corrupt_lzma2.xz: fichier de test contenant un script shell cachégood-large_compressed.lzma: fichier de test contenant un objet binaire malveillant caché
- Le composant binaire malveillant extrait pouvait être lié avec la bibliothèque légitime pendant la compilation, puis transmis aux dépôts Linux
- Les principaux fournisseurs ont distribué ce composant malveillant dans des builds bêta et expérimentaux
- La compromission de XZ Utils s’est vu attribuer CVE-2024-3094, avec le score de criticité maximal de 10
Principale chronologie
- 19 janvier 2024 : le nouveau mainteneur principal
jiaT75migre le site web de XZ vers GitHub Pages - 15 février 2024 :
build-to-host.m4est ajouté à.gitignore - 23 février 2024 : deux « fichiers de test » contenant l’étape de script malveillante sont ajoutés
- 24 février 2024 : XZ 5.6.0 est publié
- 26 février 2024 : un commit perturbant la fonctionnalité de sécurité Landlock est intégré dans
CMakeLists.txt - 4 mars 2024 : la backdoor provoque un problème lié à Valgrind
- 9 mars 2024 : les deux fichiers de test sont mis à jour, la fonction CRC est modifiée, et le problème Valgrind est « corrigé »
- 9 mars 2024 : XZ 5.6.1 est publié
- 28 mars 2024 : le bug est découvert et Debian et RedHat sont prévenus
- 28 mars 2024 : Debian rétablit XZ 5.6.1 à la version 5.4.5-0.2
- 29 mars 2024 : un e-mail public est publié sur la liste de diffusion OSS-security
- 29 mars 2024 : RedHat confirme que des versions de XZ contenant la backdoor ont été distribuées dans Fedora Rawhide et Fedora Linux 40 beta
- 30 mars 2024 : Debian interrompt les builds et lance une procédure de rebuild
- 2 avril 2024 : le développeur principal de XZ reconnaît l’incident de backdoor
Les 3 étapes de la chaîne d’infection
-
Étape 1 :
build-to-host.m4modifié- Les releases du dépôt GitHub officiel de XZ contenaient les fichiers de test malveillants, mais ceux-ci n’ayant aucune occasion de s’exécuter, ils étaient au départ inoffensifs
- Le code malveillant qui amorçait l’infection semble avoir été inclus dans les releases fournies depuis
xz[.]tukaani.org, contrôlé parjiaT75 - La plupart des distributions utilisaient cette URL, et la release téléchargée contenait le fichier
build-to-host.m4avec le code malveillant build-to-host.m4s’exécute pendant le build : il corrige avectrles données « corrompues » debad-3-corrupt_lzma2.xz, puis les décompresse avecxz -d- Le résultat de la décompression contient un script shell qui sera ensuite exécuté par
/bin/bash
-
Étape 2 : script shell injecté
- Le script injecté par le fichier
.m4malveillant vérifie qu’il s’exécute sur une machine Linux et dans le processus de build attendu - L’exécution de l’étape suivante utilise
good-large_compressed.lzma - Ce fichier est bien compressé avec XZ, mais les données décompressées contiennent des données parasites
- Le script exécute un pipeline
headviaevalpour extraire les données - Chaque commande
headignore les 1024 octets suivants, ou extrait les 2048 ou 724 octets suivants - Au total, 33 492 octets sont extraits
tailconserve les 31 265 derniers octets du fichier et ignore le reste- Ensuite,
trapplique une substitution de base pour lever l’obfuscation, puis une deuxième commande XZ décompresse les octets transformés comme un fluxlzmabrut avant d’envoyer le résultat au shell
- Le script injecté par le fichier
-
Étape 3 : extraction de l’objet de la backdoor
- Le script shell de la dernière étape vérifie plusieurs conditions pour s’assurer qu’il s’exécute dans l’environnement attendu
- Il vérifie que le projet est configuré pour utiliser IFUNC
- Il vérifie que la compilation se fait avec GCC
- Il vérifie ensuite que certains fichiers dont le script aura besoin existent dans le projet
- Cette étape extrait un fichier objet caché à un autre offset de
good-large_compressed.lzma - La procédure d’extraction exécute plusieurs commandes en séquence et transmet la sortie de chacune comme entrée de la suivante
- L’outil XZ extrait
good-large_compressed.lzma eval $iet plusieurs appels àheadsont utilisés- Les données binaires sont déchiffrées avec un algorithme personnalisé similaire à RC4
- Le fichier compressé déchiffré est de nouveau extrait avec XZ
- Après suppression de quelques octets au début, le résultat est enregistré sous
liblzma_la-crc64-fast.o - Enfin, le script modifie la fonction
is_arch_extension_supporteddans le fichiercrc_x86_clmul.hdeliblzma - Il remplace l’appel
__get_cpuidpar_get_cpuid, supprimant ainsi un underscore - Ce changement permet à l’objet de la backdoor d’être lié à la bibliothèque
Mode de chargement de la backdoor binaire
- Le code XZ d’origine contient des fonctions spécialisées pour le calcul CRC,
lzma_crc32etlzma_crc64 - Ces deux fonctions sont stockées dans la table des symboles ELF avec le type IFUNC de GLIBC
- IFUNC permet au linker dynamique de choisir dynamiquement la fonction à utiliser lors du chargement d’une bibliothèque partagée
- XZ utilise cette fonctionnalité pour vérifier la présence de fonctionnalités récentes du processeur, CLMUL, SSSE3 et SSE4.1, puis décider s’il faut employer une fonction CRC optimisée
- La vérification des fonctionnalités du processeur nécessite l’instruction
cpuid, et le wrapper__get_cpuidfourni par GLIBC est appelé - Lorsque le script malveillant remplace
__get_cpuidpar_get_cpuid, l’appel du code est relié au symbole_get_cpuidprésent dans le fichier objet de la backdoor - Le code initial de la backdoor est appelé deux fois, car
lzma_crc32etlzma_crc64utilisent la même fonction modifiée_get_cpuid- Un simple compteur vérifie si elle a déjà été exécutée
- Lorsque l’IFUNC
lzma_crc64appelle_get_cpuidet que la valeur du compteur est 1, l’étape de redirection vers le point d’entrée final démarre
Comportement à l’exécution et cibles du hooking
- La backdoor initialise des structures contenant les informations clés du processus en cours d’exécution
- Elle trouve l’adresse de la Global Offset Table (GOT) à l’aide d’offsets codés en dur, puis y repère le pointeur
cpuid - Elle remplace ensuite ce pointeur par la fonction malveillante principale, de sorte que celle-ci soit appelée comme si
cpuidétait appelé - L’objectif principal est de hooker certaines fonctions afin de pouvoir surveiller les connexions entrantes vers la machine infectée
- Les fonctions ciblées sont liées à
libcryptoRSA_public_decrypt: utilisée pour déchiffrer un texte chiffré signé avec une clé privéeEVP_PKEY_set1_RSA: utilisée pour définir la clé RSA d’un contexte donné- Absente des versions récentes des serveurs SSH, mais utilisée dans des outils autonomes de génération de clés SSH
RSA_get0_key: utilisée pour récupérer une clé RSA
- Le processus de hooking nécessite l’accès à plusieurs structures internes et la manipulation de structures propres au processus ; le code malveillant effectue aussi des vérifications destinées à échapper à l’analyse
Vérifications de l’environnement d’exécution et techniques d’évasion de l’analyse
-
Vérification de
sshdet du kill switch- La backdoor commence par analyser le linker dynamique
ld-linux, qui résout dynamiquement les adresses de symboles - Elle vérifie que l’environnement d’exécution actuel correspond à ses critères
- Elle vérifie que le processus courant est
/usr/bin/sshd - Elle vérifie la présence d’un kill switch
- Le nom du processus courant est extrait de
argv[0] - Elle analyse toutes les variables d’environnement du processus pour vérifier si l’une correspond à une valeur présente dans sa table de chaînes interne
- Si une variable d’environnement correspond ou si le processus n’est pas
sshd, le code malveillant interrompt son exécution - L’unique variable de la table interne,
yolAbejyiejuvnup=Evjtgvsh5okmkAvj, agit dans ce contexte comme un kill switch
- La backdoor commence par analyser le linker dynamique
-
Traitement de chaînes basé sur un trie
- L’une des caractéristiques de la backdoor est l’utilisation d’une unique structure de trie pour les opérations sur les chaînes
- Au lieu de comparer directement des constantes comme des noms de fonctions, ou d’utiliser des hashes de chaînes, elle vérifie si le résultat d’une recherche dans le trie correspond à une valeur constante donnée
- La valeur magique de l’en-tête ELF renvoie 0x300 dans le trie
- Le nom de fonction
systemcorrespond à la valeur de retour 0x9F8 - Le trie sert non seulement aux comparaisons, mais aussi à trouver des chaînes dans le binaire hôte
- Par exemple, une fonction qui utilise un pointeur vers une chaîne comme
ssh-2.0recherche cette chaîne dans le binaire hôte afin de ne pas laisser de données suspectes dans le corps de la backdoor - L’implémentation utilise un bitmask de 16 octets
- Chaque moitié correspond aux plages d’octets d’entrée
0x00-0x3Fet0x40-0x7F - Les nœuds feuilles du trie font 2 octets ; 3 bits servent de flags et le reste est réservé à la valeur ou à l’emplacement du nœud suivant
Résolution des symboles et hooking de rtdl-audit
-
Routines de résolution des symboles
- La backdoor contient au moins 3 routines de résolution des symboles destinées à trouver des structures ELF Symbol
- Toutes les fonctions de résolution de symboles prennent en entrée la clé à rechercher dans le trie
- L’une de ces fonctions parcourt tous les symboles pour trouver celui qui possède la clé recherchée et, lorsqu’elle le trouve, renvoie la structure
Elf64_Sym - Cette structure est ensuite utilisée pour remplir des structures internes de la backdoor et conserver les pointeurs de fonctions nécessaires
- Ce procédé ressemble aux routines de hashing d’API que l’on observe couramment dans les menaces Windows
- La backdoor recherche ensuite de nombreuses fonctions OpenSSL
libcryptoqui serviront dans ses routines cryptographiques - Elle suit le nombre de fonctions trouvées et résolues, puis utilise cette valeur pour décider si l’exécution peut se poursuivre ou doit s’arrêter
-
Faux allocator exploitant
lzma_alloc- Un autre résolveur de symboles détourne
lzma_alloc, une fonction deliblzmaelle-même lzma_allocest une fonction qui aide à allouer efficacement de la mémoire en utilisant l’allocator par défaut,malloc, ou un allocator personnalisé- Dans la backdoor XZ, un faux allocator fait que cette fonction se comporte comme un autre résolveur de symboles
- Le paramètre normalement utilisé comme « taille d’allocation » sert en réalité de clé de symbole dans le trie
- Cette astuce vise à rendre l’analyse de la backdoor plus difficile
- La backdoor résout dynamiquement les symboles pendant son exécution, sans se limiter à une résolution de tous les symboles en une fois ni uniquement au moment où ils sont nécessaires
- Les cibles de résolution vont de fonctions OpenSSL légitimes à des fonctions comme
system, qui exécute des commandes sur la machine
- Un autre résolveur de symboles détourne
-
Patch runtime de
rtdl-audit- La backdoor utilise la fonctionnalité rtdl-audit du linker dynamique pour hooker des fonctions
- En temps normal,
rtdl-auditpermet à un développeur de créer une bibliothèque partagée personnalisée afin de recevoir des notifications d’événements du linker, par exemple la résolution de symboles - La backdoor XZ ne crée pas de bibliothèque partagée distincte ; elle patche à l’exécution l’interface par défaut déjà enregistrée en mémoire pour détourner la routine de résolution des symboles
- La structure malveillante
audit_ifacestockée dans la variable globaledl_auditde la zone mémoire du linker dynamique contient l’adresse du callbacksymbind64 - Lorsque le linker dynamique appelle ce callback, toutes les informations de symboles passent sous le contrôle de la backdoor, qui renvoie une adresse malveillante pour les fonctions ciblées afin de réaliser le hooking
- Les adresses de
dl_auditetdl_nauditsont obtenues en désassemblant les fonctionsdl_mainetdl_audit_symbind_alt - La backdoor contient un désassembleur interne minimal destiné au décodage d’instructions, largement utilisé pour trouver certaines valeurs, comme les adresses
*audit
Distributions confirmées contenant la backdoor et informations de détection
-
Distributions source contenant la backdoor
- xz-5.6.0
- MD5 :
c518d573a716b2b2bc2413e6c9b5dbde - SHA1 :
e7bbec6f99b6b06c46420d4b6e5b6daa86948d3b - SHA256 :
0f5c81f14171b74fcc9777d302304d964e63ffc2d7b634ef023a7249d9b5d875
- MD5 :
- xz-5.6.1
- MD5 :
5aeddab53ee2cbd694f901a080f84bf1 - SHA1 :
675fd58f48dba5eceaf8bfc259d0ea1aab7ad0a7 - SHA256 :
2398f4a8e53345325f44bdd9f0cc7401bd9025d736c6d43b372f4dea77bf75b8
- MD5 :
- xz-5.6.0
-
Principaux artefacts analysés
bad-3-corrupt_lzma2.xz:86fc2c94f8fa3938e3261d0b9eb4836be289f8aebuild-to-host.m4:b4dd2661a7c69e85f19216a6dbbb1664good-large_compressed.lzma:540c665dfcd4e5cfba5b72b4787fec4fliblzma_la-crc64-fast.o:212ffa0b24bb7d749532425a46764433
-
Bibliothèques connues contenant la backdoor
- Debian Sid
liblzma.so.5.6.0- MD5 :
4f0cf1d2a2d44b75079b3ea5ed28fe54 - SHA1 :
72e8163734d586b6360b24167a3aff2a3c961efb - SHA256 :
319feb5a9cddd81955d915b5632b4a5f8f9080281fb46e2f6d69d53f693c23ae
- MD5 :
- Debian Sid
liblzma.so.5.6.1- MD5 :
53d82bb511b71a5d4794cf2d8a2072c1 - SHA1 :
8a75968834fc11ba774d7bbdc566d272ff45476c - SHA256 :
605861f833fc181c7cdcabd5577ddb8989bea332648a8f498b4eef89b8f85ad4
- MD5 :
- Debian Sid
-
Noms de détection
- Les produits Kaspersky détectent les objets malveillants liés à l’attaque sous les noms HEUR:Trojan.Script.XZ et Trojan.Shell.XZ
- Kaspersky Endpoint Security for Linux détecte le code malveillant dans la mémoire du processus SSHD sous le nom MEM:Trojan.Linux.XZ, dans le cadre de la tâche Critical Areas Scan
- La règle Yara fournie est la règle
liblzma_get_cpuid_function, destinée à repérer la fonction malveillanteget_cpuidliée à CVE-2024-3094
1 commentaires
Avis de Hacker News
J’ai l’impression que cette phrase minimise en fait ce qui s’est réellement passé.
Ce qui est encore plus effrayant que les aspects techniques de la backdoor, c’est l’ampleur et le niveau d’ingénierie sociale. La backdoor était le produit final, et si elle a pu être introduite, c’est parce qu’à ce moment-là l’ensemble du projet xz était déjà, depuis longtemps, sous l’emprise d’acteurs malveillants, à savoir « Jia Tan » et son entourage. Ils ont mené une guerre psychologique contre le mainteneur pendant plus d’un an, sans que le mainteneur ni personne d’autre ne s’en aperçoive.
On se croirait dans un roman d’espionnage, et si ce genre de chose est possible, on se demande ce qui peut bien être en train de se passer dans d’autres projets en ce moment.
Le code de la backdoor lui-même reflète le même état d’esprit. Il ne se contente pas d’essayer d’avoir l’air inoffensif : à travers les messages de commit, les commentaires, les noms de variables, le choix des commandes, etc., il construit activement une narration sur ce qu’il est censé faire en apparence, alors qu’en réalité il fait tout autre chose. La structure est faite pour que la première personne qui examine le code doute d’abord de sa propre compréhension, puis soupçonne un bug, et ne commence à envisager une intention malveillante que bien plus tard.
J’espère que des agences de renseignement, quelles qu’elles soient, enquêtent plus en profondeur sur cette affaire.
C’est frustrant de voir, dans chaque fil HN sur les backdoors, cette possibilité rejetée comme de la paranoïa ou un délire de chapeau en papier aluminium. On fait comme si cela n’arrivait pas, alors que cette fois-ci n’est qu’un cas concret qui a été attrapé, et qu’il en existe d’innombrables autres qui ne l’ont pas encore été.
Dans ce cas, comme il s’agissait d’un projet open source, la découverte était relativement plus facile, et pourtant il a fallu de la chance. Maintenant, pensez aux produits propriétaires : y placer une backdoor revient à infiltrer ou faire pression sur une seule organisation. Ce genre de chose arrive souvent. Personne ne veut y croire, mais c’est courant. Quiconque a travaillé dans une entreprise d’infrastructure technologique a probablement quelques histoires à raconter. Il est difficile d’en parler à cause des NDA, ou pour des raisons encore plus graves, mais cela arrive vraiment.
Cela peut être le résultat de l’obsession de quelqu’un, ou le travail d’une société de sécurité privée ou d’un acteur étatique qui mène ce genre d’opérations sur plusieurs projets comme un travail de bureau de 9 h à 17 h.
Il est naturel que l’attention se soit jusqu’ici concentrée sur le fait que la backdoor fonctionne et sur la manière dont elle atteint ses objectifs.
Mais j’aimerais aussi voir une analyse plus approfondie des erreurs et des parties surconçues. Dans l’interview de Bryan Cantril [1], Andrés dit que cela ressemble à un composant de backdoor prêt à l’emploi, pas forcément conçu en connaissant précisément la manière dont il allait être distribué, et qu’il contient beaucoup d’éléments stupides. Par exemple, la recherche dans la table des symboles qui l’a poussé à enquêter.
De même, je me demande pourquoi ils ont découpé 48 octets avec RC4 [2].
J’aimerais entendre ce qui aurait pu être mieux fait avec plus de temps ou une meilleure équipe, ou au contraire où ils se sont plantés encore plus lourdement.
[1] https://youtu.be/jg5F9UupL6I?si=gvXsYFXgagkGOMd4
[2] https://twitter.com/matthew_d_green/status/17744729080201014...
Si j’ai bien compris, une mesure de durcissement utile serait que chaque bibliothèque liée dynamiquement ait sa propre GOT, puis que la table soit marquée en lecture seule une fois le linking dynamique terminé. Autrement dit, empêcher de patcher des entrées ifunc de l’autre côté d’une frontière dynamique.
Cela pourrait améliorer la sécurité de la chaîne d’approvisionnement pour du code qui est lié quelque part mais jamais exécuté.
Plus loin, il serait peut-être préférable d’implémenter ifunc de manière déclarative, afin d’éviter de déclencher l’exécution de code arbitraire dans chaque bibliothèque liée. La compatibilité ascendante rendrait cette implémentation difficile aujourd’hui, mais à long terme cela semble pouvoir être introduit par paliers. Par exemple, si une bibliothèque est construite avec un bit de fonctionnalité « ifunc de linking déclaratif », le linker dynamique échouerait à l’exécution si toutes les bibliothèques liées ne disposent pas du même indicateur de fonctionnalité.
Aujourd’hui, la plupart des builds de bibliothèques consistent à exécuter des scripts très complexes et obscurs qui nécessitent un environnement Turing-complet. Cela offre aux attaquants une surface d’attaque infinie, et si le processus de build est détourné, cela crée des opportunités.
Passer à un processus de build déclaratif, où l’exécuteur n’est qu’une machine à états limitée, aiderait. Il serait aussi intéressant d’exiger que tous les blocs de source soient reproductibles.
À partir de là, toutes les défenses tombent. S’il le veut, il peut remapper la GOT en écriture ; même si ce comportement peut être détecté comme « suspect » ou si le système d’exploitation peut empêcher la transition, le code injecté peut détourner le flot de contrôle de centaines d’autres manières. Lecture/écriture arbitraires, exécution de code, tout est possible. Il n’existe pas de mesure d’atténuation capable d’empêcher une compromission à ce stade. S’il le souhaite, il peut exfiltrer la clé privée et l’envoyer directement à l’attaquant, ou lancer un shell. Essayer de concevoir une protection à ce stade est une perte de temps.
Le bon pointeur de fonction est chargé lors du premier appel et inséré dans la table à la place du stub, et ce moment peut être arbitrairement éloigné dans le futur. En pratique, dans de grands écosystèmes de bibliothèques comme les apps gtk, la plupart des fonctions liées ne sont jamais appelées du tout.
-march=native, et désactiver ifunc est simple en définissant-multiarchdans les USE flags de glibc. Je n’ai constaté aucun effet négatif.Concernant les trois premières étapes, cet article n’ajoute pas grand-chose à ce qu’on sait depuis deux semaines. C’est plutôt une bonne synthèse avec un organigramme.
En revanche, la partie qui analyse le binaire avec autant de détail semble nouvelle.
Comment le code source qui y figure a-t-il été produit ? Ils ont passé le tout dans un désassembleur, compris ce que faisait le code, puis renommé tous les symboles avec des noms descriptifs ? Pour quelque chose réalisé en deux semaines, cela paraît être un résultat considérable.
Global Research & Analysis Team, Kaspersky Lab
https://securelist.com/author/great/
Comme l’auteur semble être l’équipe d’analyse de malware de Kaspersky Lab, il y a de fortes chances qu’ils soient assez bons en rétro-ingénierie de binaires.
https://hex-rays.com/ida-pro/
Ce que j’aimerais vraiment savoir, c’est ce qui a exactement provoqué le délai initial de SSH qui a déclenché l’enquête sur xz. Quelqu’un l’a-t-il déterminé ?
D’après ceux qui ont fait la rétro-ingénierie du code, le message de commande devait aussi être lié à la clé d’hôte SSH. Donc, si la clé d’hôte était une clé RSA, il est possible qu’une opération de déchiffrement RSA supplémentaire ait aussi été effectuée à chaque connexion.
Cela suffirait probablement à expliquer le délai.
C’est un moyen simple de déterminer depuis l’extérieur si le serveur est infecté, sans même tenter d’abord une injection de code.
Les auteurs connaissent très en profondeur les structures internes de glibc. C’est le genre de choses qu’on ne peut savoir qu’en étant plongé jusqu’au cou dans le code source, et il y a aussi beaucoup de techniques nouvelles.
Le parseur ELF personnalisé et le désassembleur sont tellement complexes qu’il est difficile d’imaginer que ce code n’ait pas été utilisé ailleurs auparavant, ou ne le sera plus à l’avenir.
Je me demande si cette affaire fera l’objet d’une enquête sérieuse à la hauteur de ce qu’elle mérite, mais j’en doute.
Quelqu’un a-t-il finalement analysé le bug de la backdoor qui a provoqué l’erreur Valgrind et le ralentissement de SSH ayant révélé l’affaire ?
Le « correctif » Valgrind consistait à désactiver ifunc, ce qui désactivait la backdoor et faisait disparaître l’erreur.
Le ralentissement venait, à ma connaissance, de toutes les recherches de symboles et d’instructions effectuées par la backdoor.
Si l’on cherche le retournement de situation, vu les efforts déployés par l’attaquant dans les scripts et le code pour éviter la détection, tout ce projet pourrait être une diversion, ou un plan de secours pendant que plusieurs autres tentatives étaient menées en parallèle.
Comment garder une longueur d’avance sur ce genre de choses ? Le fait que la communauté se concentre sur SSHD aura-t-il un impact sur d’autres parties du système dans son ensemble ? Sur d’autres aspects techniques ou sociaux ?
Les chapeaux en papier aluminium, c’est amusant.
Ou bien acheter du code propriétaire à une entreprise comme Microsoft, en espérant qu’elle ait les ressources et la volonté d’examiner le code plus rigoureusement.
Et il reste toujours l’approche consistant à avoir une excellente équipe d’opérations de sécurité pour détecter les activités réseau suspectes et les tentatives d’élévation de privilèges.
Mais un contributeur qui n’a aucun historique ni aucune trace en dehors du projet sur lequel il travaille devrait désormais être considéré comme un signal d’alerte.
D’anciens groupes comme GOBBLES, ADM, ac1db1tch3z, ~el8 faisaient aussi ce genre de choses, tout comme des « chercheurs en sécurité » privés comme isec.pl.
Ce qui pose problème cette fois, c’est que des acteurs étatiques exploitent le capitalisme d’entreprise qui a créé une époque où des projets d’infrastructure tiennent grâce à du travail sous-payé. Les acteurs malveillants disposent en pratique de ressources illimitées pour atteindre leurs objectifs.
C’est finalement ce qui a créé la demande et l’émergence d’organisations comme NSO et Zerodium.
Avant cela, les exploits et les backdoors n’avaient presque aucune valeur, et les hackers espéraient plutôt être sponsorisés ou recrutés par des entreprises comme Qualys.
J’ai vu plusieurs analyses de piratages de vulnérabilités zero-day par Google, et elles étaient déjà incroyablement impressionnantes, mais ce hack-ci pourrait bien être l’un des plus marquants de tous les temps.
J’ai vu que le dépôt xz était de nouveau sur GitHub, et que Lasse et un nouveau contributeur étaient en train de faire le ménage. Ils ont supprimé la prise en charge d’ifunc et ont commité dans le dépôt le code de génération des fichiers de test, afin de pouvoir créer ces fichiers sans blob. Cela semble aller dans la bonne direction.