Skip to content

libssh & CVE-2018-10933

Le 16 Octobre 2018 est sortie une nouvelle CVE : La CVE-2018-10933.

Cette faille touche la libssh, une librairie en C pour faire… Du SSH. L’occasion pour moi de faire un petit article sur SSH pour ensuite présenter cette CVE et pourquoi elle est “Surcôtée”.

SSH c’est quoi ?

Un peu d’histoire de l’informatique ne fait jamais de mal !

On va revenir aux débuts de l’informatique “moderne”, les grandes entreprises et les université viennent de s’équiper d’ordinateurs et surtout de serveur UNIX. Et avec ces serveurs sont venus aussi les premiers administrateurs système. A l’époque, les administrateurs systèmes étaient déjà assez paresseux… Donc en 1969 entre une sortie à Woodstock et une rediffusion du premier pas sur la lune, ils ont inventé telnet (note à moi même : le rajouter sur la page wikipedia de 1969).

Telnet c’est un programme défini au début par la RFC 15 (ah oui c’est vieux) et qui leur permet d’echanger des données de manière bi-directionnelle sur un réseau et donc d’administrer les serveurs à distance.

Seulement, telnet n’est pas l’outil le plus “secure” du monde, à peu près tout le monde peut se connecter au serveur et y faire ce qu’il veut… Mais heureusement pour nous, en 1977 un gentil monsieur a créé un shell à son nom : le Bourne Shell (connu sous le nom de sh ou des fois bsh).

Ce shell est l’un des premiers (si ce n’est LE premier) à intégrer une version “restreinte”. Ce shell restreint (ou restricted shell) va tout simplement limiter les possibilités d’action, ainsi on peut limiter l’utilisateur à la simple execution d’un script (qui va redémarrer un service par exemple). Le restricted shell a bien sûr été gardé pour les shell se basant sur le Bourne Shell (bash, ksh, …). On a donc associé telnet au restricted shell pour avoir une connexion à distance plus “securisée”.

Malheureusement, ça ne suffit pas à nos chers admin sys. Ils voulaient avoir toutes les possibilités sur leurs serveurs tout en restant à distance. Et pour ça, en 1995, fut inventé un nouveau protocole qui permet une authentification à distance sur le serveur avec des échanges chiffrés et le même shell que s’y l’on se connectait en direct au serveur : le SSH !

Le principe convenait parfaitement aux utilisateurs, il a donc rapidement gagné plusieurs millions d’utilisateurs majoritairement via les implémentations OSSH et son fork OpenSSH.

Puis, parce qu’on a jamais assez de sécurité, une nouvelle version du protocole SSH a été inventée en 2006 : SSH2. Cette nouvelle version étant plus sécurisée notamment au niveau de l’échange de clef mais n’étant pas compatible avec la nouvelle version (qu’on appellera SSHv1). On a donc vu SSH1 se faire remplacer petit à petit par SSH2 tant est que maintenant lorsque l’on parle de SSH, on parle de SSH2.

Donc en résumé :

Ce qu’on appelle SSH est la deuxième version d’un protocole qui permet de se connecter à distance sur une machine.

Et libssh ?

libssh, au même titre qu’OpenSSH, est une implémentation du protocole SSH. En fait plus qu’une implémentation, c’est toute une librairie en C qui permet d’implémenter ce protocole.

Donc j’en profite pour le dire une bonne fois pour toute :

libssh est différent d’OpenSSH. Et OpenSSH n’utilise pas libssh.

En effet, OpenSSH est un fork de OSSH par des développeurs OpenBSD. Ils ont eux-même créé leurs fonctions et méthodes pour implémenter le SSH. Aussi, OpensSSH n’est normalement disponible que sur des machines UNIX (Sur windows il faut passer par Cygwin).

libssh, lui est une librairie multi-plateforme. N’importe quel développeur en C pourra alors utiliser libssh pour avoir du SSH dans son programme. On retrouve d’après le site https://www.libssh.org/ des applications utilisant la lib :

  • GitHub (le fameux git via SSH)
  • KDE (pour la gestion du sftp)
  • X2Go (pour la connexion au serveur X)

On retrouve aussi dans le bastion “WALLIX AdminBastion” qui serait très utilisé dans les systèmes industriels.

Je tiens à préciser qu’il existe 2 “versions” de libssh. On ne va pas ici parler de libssh2 mais juste de “libssh”. Si vous voulez connaître la difference entre les 2 j’ai trouvé cette petite page web faite par les devs de libssh2.

La CVE-2018-10933

Je vous connais petits gredins que vous êtes ! Ce que vous attendez réellement c’est que je parle de la CVE !

Cette CVE est sortie aux alentours du 15 Octobre 2018. Elle permet à n’importe qui d’obtenir un accès sur une machine via SSH (si bien sûr le serveur SSH est fait via libssh). On va donc voir ensemble ce que c’est cette faille.

Dans un premier temps, il faut comprendre comment fonctionne une authentification avec libssh. Pour ça j’ai fais un petit schéma simplifié en ascii (depuis le temps que je rêve de faire ça) :

Client SSH                                         Serveur SSH

    +                                                  +
    |          Ouverture d'une connexion SSH           |
    +------------------------------------------------->|
    |                                                  |
    |                                                  |
    |      Envoie la version du logiciel SSH           |
    |<-------------------------------------------------+
    |                                                  |
    |                                                  |
    |      Envoie la version du logiciel SSH           |
    +------------------------------------------------->|
    |                                                  |
    |      Initialisation de l'échange des clefs       |
    |                 (côté client)                    |
    +------------------------------------------------->|
    |                                                  |
    |      Initialisation de l'échange des clefs       |
    |                 (côté serveur)                   |
    |<-------------------------------------------------+
    |                                                  |
    |                                                  |
    |      Echange des clefs via Diffie-Hellman        |
    | <----------------------------------------------->|
    |                                                  |
    |                  Envoi du message                |
    |             SSH2_MSG_SERVICE_REQUEST             |
    +------------------------------------------------->|
    |                                                  |
    |                  Envoi du message                |
    |              SSH2_MSG_SERVICE_ACCEPT             |
    |<-------------------------------------------------+
    |                                                  |
    |                  Envoi du message                |
    |         SSH2_MSG_USERAUTH_REQUEST + data         |
    +------------------------------------------------->|
    |                                                  |
    |                                                  +--------+
    |                                                  |        |
    |                                                  |        | Verification des données de connexion
    |                                                  |        |
    |                                                  |<-------+
    |                  Envoi du message                |
    |             SSH2_MSG_USERAUTH_SUCCESS            |
    |<-------------------------------------------------+
    |                                                  |
    |                                                  |
    |                                                  |
    |                Connexion établie !               |
    |<------------------------------------------------>|
    +                                                  +
AsciiFlow authentification libssh

On peut donc voir l’implémentation SSH avec les différents messages (SSH2_MSG_*).

Notre faille de sécurité va se situer au niveau du SSH2_MSG_USERAUTH_REQUEST. En effet, le serveur s’attend à commencer une authentification mais si à la place on lui envoie le message SSH2_MSG_USERAUTH_SUCCESS alors il va l’interprété. Ainsi, sans avoir lancé aucune authentification on peut se connecter au serveur SSH (en tant que celui qui le lance si je ne me trompe pas).

Eh… Oui, en fait c’est tout simple. Je me demanderais presque pourquoi j’ai fais cet article.

Et si la faille est simple, le dev de l’exploit n’est pas beaucoup plus compliqué. Il suffit d’utiliser les libraires déjà existantes comme libssh (bah oui) pour le C ou paramiko pour le python. Ainsi il suffit juste de lancer une connexion au serveur SSH avec le premier message puis d’envoyer le fameux “SSH2_MSG_USERAUTH_SUCCESS”.

Pourquoi c’est “surcôté” ?

J’ai bien dit ça au début de mon article. Et il y a au moins 2 raisons :

La première :

Beaucoup de personne ont confondu OpenSSH et libssh. Rien que dans mon entourage plusieurs personne pensaient que OpenSSH utilisait libssh. Et OpenSSH est l’implémentation de SSH la plus utilisée, celle que l’on voit un peu tout le temps.

La faille sur libssh n’affecte donc pas la majorité des serveurs.

La seconde :

Oui il manquait certaines vérifications dans la libssh. Et il faut aussi savoir que libssh propose des serveurs d’exemple dans son git. Donc si on veut jouer aux apprentis hacker (comme j’ai pu le faire), on va pas se fouler et on va tester la CVE sur les serveurs d’exemple.

Spoiler : ça ne fonctionnera pas.

En effet, le serveur intègre certaines vérifications telle qu’une boucle

while (sdata.authenticated == 0 || sdata.channel == NULL) {
/* code */
}

Où le sdata.authenticated ne changera qu’à la fin d’une authentification réussie (et la CVE permet de ne pas faire d’authentification, pas de s’authentifier).

Alors oui, il reste des applications/services vulnérables. Mais ils ne sont pas si nombreux. Pour ce qui est des grosses applications (GitHub, WALLIX, …) il y a déjà eu des patch/mises à jour de faites. Il ne reste qu’aux utilisateurs de les lancer.

Pour ce qui est des serveurs vulnérables n’ayant pas de patchs, ce sont sans doute des serveurs “faits maison” et pour lesquels il suffira de mettre à jour la libssh.

 

 

Encore une fois, merci d’avoir lu cet article. J’espère qu’il vous a plu.

N’hésitez pas à m’envoyer toute vos questions et remarques, je suis toujours prêt à y répondre et à corriger toute erreurs.

Published inArticle

2 Comments

  1. tuxvador tuxvador

    Très bon article. j’avais une question, comment tu fais tes diagramme de flux d’authentification en ascii?

Leave a Reply

Your email address will not be published. Required fields are marked *