Nous continuons d'analyser les vulnérabilités des commutateurs industriels: nous exécutons du code arbitraire sans mot de passe



Dans Positive Research 2019, nous avons examiné le protocole de gestion des commutateurs industriels Moxa. Cette fois, nous allons poursuivre ce sujet et analyser en détail la vulnérabilité CVE-2018-10731 dans les commutateurs Phoenix Contact des gammes de modèles FL SWITCH 3xxx, FL SWITCH 4xxx et FL SWITCH 48xx identifiées par nos experts. Cette vulnérabilité, détectée dans l'interface Web de l'appareil, permet l'exécution de code arbitraire sans connaître les informations d'identification de l'appareil et est évaluée à 9 sur 10 sur l'échelle CVSS version 3.

Premier coup d'oeil


Les appareils mentionnés ci-dessus fonctionnent sous Linux et vous pouvez utiliser l'interface Web pour les configurer. Comme avec de nombreux autres appareils IoT, domestiques et industriels, l'interface Web se compose de nombreuses applications CGI qui traitent les requêtes HTTP des utilisateurs. Dans notre cas, les applications CGI utilisent activement la bibliothèque cgic, ce qui facilite le travail avec les requêtes HTTP, et les fonctions de cette bibliothèque sont intégrées dans la bibliothèque partagée libipinfusionweb.sosituée dans le système de fichiers du périphérique.

Lors du traitement d'une demande HTTP, le serveur Web transmet les données de la demande utilisateur à l'application CGI sous la forme d'un ensemble de variables d'environnement. Leur traitement initial est effectué par la fonction de mainbibliothèque libipinfusionweb. Ensuite, la fonction mainappelle la fonction de l' cgiMainapplication CGI, dans laquelle a lieu le traitement ultérieur de la demande.



Figure 1. Traitement d'une requête HTTP

Au cours de son travail, la fonction principale de la bibliothèque libipinfusionwebappelle une fonction get_login_userqui détermine si l'utilisateur a réussi l'authentification sur le système en utilisant les valeurs de cookie transmises.



Figure 2. Fragment de pseudo-code de la

fonction principale La fonction get_login_userreçoit la valeur du paramètre Cookie c_sessionà l'aide de la fonction cookies_get_valueet la stocke dans une variable local_e0. La variable elle local_e0- même est un tableau de caractères à un octet d'une longueur de 0x80 et est située à une distance de 0xE0 à partir du début de la pile.



Figure 3. Fragment du pseudo-code de la fonction get_login_user

Cependant, dans le code de fonction, cookies_get_valueon peut voir que la cgiCookieStringvaleur du paramètre Cookie reçue par la fonction a une longueur maximale de 0x400 octets.



Figure 4. Un fragment du pseudo-code de la fonction cookies_get_value

Ainsi, lors du passage d'un paramètre Cookie de plus de 0xE0 (224) caractères, la fonction get_login_userenregistre la valeur de ce paramètre dans sa pile, à la suite de quoi toutes les informations sur la pile qui se trouve derrière la variable local_e0seront écrasées, y compris l'adresse fonction de retour.

Remarque: Lorsqu'une fonction en appelle une autre, l'adresse de retour est stockée dans la pile. Le contrôle est transféré à cette adresse lorsque la fonction appelée termine son travail. Par conséquent, si vous réécrivez cette adresse, vous pouvez contrôler le processus d'exécution du programme. Par exemple, un attaquant peut remplacer cette adresse par l'adresse d'un shellcode malveillant situé dans l'espace d'adressage du programme.

Notez que la réécriture de l'adresse de retour se produit avant la vérification de l'authentification, ce qui permet d'exploiter cette vulnérabilité à un attaquant qui ne connaît pas les informations d'identification de l'appareil.

Exploitation


Nous avons examiné plusieurs options pour démontrer la possibilité d'exploiter cette vulnérabilité. Le plus simple est d’écrire le code de la charge utile sur la pile (il reste 0x400 - 0xE0 = 800 octets, c’est suffisant pour le code) et de réécrire l’adresse de retour avec l’adresse du code. Théoriquement, cette option était possible, car le processeur du commutateur vulnérable ne prend pas en charge la fonction NX-bit (c'est-à-dire qu'il permet l'exécution de code situé n'importe où, y compris sur la pile), mais en pratique, il présentait de sérieuses limitations.

Le processeur de commutateur vulnérable a une architecture MIPS; de nombreuses instructions de processeur dans cette architecture sont codées en séquences d'octets contenant zéro octet. Le contenu du tampon est écrit dans le premier octet zéro (en raison de l'utilisation de la fonctionstrcpy), par conséquent, il est uniquement nécessaire d'utiliser des opérandes qui ne contiennent pas d'octet nul, ce qui est impossible, car toute charge utile utiliserait au moins plusieurs de ces octets.

Lors de la construction de la chaîne ROP, encore une fois, nous aurions à faire face aux limitations de l'octet nul: l'adresse des gadgets ROP ne devrait pas contenir de zéros, ce qui complique grandement leur recherche. Dans l'ensemble, nous ne pouvions utiliser qu'un seul zéro, copié par la fonction strcpy. Cela impose une limitation à la création d'une chaîne ROP à part entière, et en plus de cela, les gadgets dont nous avions besoin étaient extrêmement peu nombreux. Cependant, lors des recherches dans la bibliothèque libipinfusionweb, le fragment de code suivant a été trouvé:



Figure 5. Un fragment du code exécutable de la bibliothèque libipinfusionweb

À condition que le contenu du registre $ s0 soit contrôlé, ce fragment de code vous permet d'exécuter une commande OS à l'aide d'une fonction mysystem(initialement cette fonction n'avait pas de nom, mais nous l'avons renommée, car elle est très similaire à la fonction système sous Linux).

Puisque nous réécrivons l'adresse de retour à partir de la fonction get_login_user, cette fonction sera exécutée jusqu'à la fin. Dans l'épilogue de la fonction get_login_user, vous pouvez voir que la valeur du registre $ s0 est restaurée à partir de la valeur précédemment enregistrée sur la pile (à l'offset 0xD8 par rapport au haut de la pile). Cependant, à ce stade, cette zone de la pile est déjà sous notre contrôle, c'est-à-dire que nous pouvons en fait contrôler le contenu du registre $ s0 et ainsi exécuter des commandes OS arbitraires à l'aide de la fonction mysystem.



Figure 6. Un extrait du code exécutable de la fonction get_login_user

Ainsi, afin de démontrer avec succès l'exploitation de cette vulnérabilité, nous devons envoyer en paramètre une Cookie c_sessionlongue ligne contenant:

  • Commande de chaîne OS, qui sera ensuite transmise à la fonction mysystem;
  • l'adresse de cette commande sur la pile;
  • nouvelle adresse de retour (adresse du fragment de code représenté sur la figure 5).

La charge utile finale devrait ressembler à ceci:



Figure 7. Charge utile

À ce stade, nous avions déjà un shell sur le périphérique obtenu à l'aide d'une vulnérabilité qui nécessitait des droits d'administrateur pour fonctionner. Par conséquent, nous avons pu obtenir des informations supplémentaires qui nous ont aidés à opérer:

  • L'ASLR sur le périphérique à l'étude a été désactivé - par conséquent, les adresses du gadget utilisé et les commandes du système d'exploitation seront toujours les mêmes.



Figure 8. État ASLR sur le périphérique sous enquête

  • Plage d'adresses mémoire dans laquelle la pile peut se trouver. Pour calculer l'adresse exacte, nous avons parcouru toutes les adresses de cette plage.

En tant que charge utile, nous avons implémenté le chargement d'un shell web, une application CGI avec le contenu suivant:

#!/bin/sh
eval $HTTP_CMD 2>&1

Étant donné que, selon le protocole CGI, le contenu des en-têtes HTTP est transmis à l'application CGI sous la forme de variables d'environnement avec les noms HTTP_ <Nom de l'en-tête>, ce shell utilisera la commande evalpour exécuter le contenu de l'en-tête HTTP CMD. La figure ci-dessous montre le résultat de l'opération et de l'exécution réussies de la commande ls à l'aide du shell chargé.



Figure 9. Résultat de l'opération et de l'exécution réussies de la commande ls

Conclusion


Nous avons démontré la capacité d'exploiter cette vulnérabilité. Comme nous l'avons déjà mentionné, son fonctionnement ne nécessite pas la connaissance du mot de passe et peut donc être effectué même par un attaquant non authentifié.

Le piratage d'un commutateur de réseau industriel peut compromettre toute la production. La violation de l'interaction réseau peut nuire au processus jusqu'à ce qu'il s'arrête complètement.

Des informations sur la vulnérabilité et le PoC ont été transmises au fournisseur, qui a publié la version 1.34 du micrologiciel mise à jour, et l'identifiant CVE-2018-10731 a été attribué à la vulnérabilité elle-même.

Cherche une personne


Si vous avez envie de faire de telles choses, nous recherchons simplement un spécialiste dans notre équipe. Nous sommes engagés dans l'analyse de sécurité des systèmes de contrôle de processus (grandes installations industrielles / énergétiques / de transport, etc.). Sur chaque projet, nous recherchons des moyens d'arrêter ou de perturber le fonctionnement de ces objets. Chaque fois, nous trouvons de nombreuses façons d'influencer le processus de fabrication, en explorant le matériel et les logiciels industriels, en analysant les protocoles réseau propriétaires. Nous trouvons et rapportons beaucoup de zirodey, écrivons des rapports (pas selon GOST) et faisons beaucoup plus. Lorsqu'il y a du temps, nous parlons à l'IB et pas seulement aux conférences. Lien vers l'offre d'emploi: hh.ru/vacancy/36371389

Publié par Vyacheslav Moskvin, Positive Technologies

All Articles