Non, ce n'est pas une blague, et oui, vous avez bien compris. À partir d'un simple telnet vers un Solaris 10, on arrive à passer root, juste comme ça. Enfin, presque, parce qu'on peut quand même interdire à root de se loguer directement en telnet, et c'est justement la configuration par défaut. Mais ce n'est pas grave, vous pouvez atteindre n'importe quel compte en fait. Pas mal non ? En fait, tout le crédit revient à IBM qui pouvait se vanter de la même vulnérabilité sur AIX... en 1994...

Comme le faisait remarquer Alain Thivillon sur la liste Sec de l'OSSIR, le soucis se situe vers la ligne 3200 du fichier source in.telnetd.c :

3199 } else /* default, no auth. info available, login
               does it all */ {
3200     (void) execl(LOGIN_PROGRAM, "login",
3201         "-p", "-h", host, "-d", slavename,
3202         getenv("USER"), 0);
3203 }

En gros, on va cherche la variable d'environnement USER qu'on passe directement en paramètre à login. Le contenu de cette variable est l'argument du paramètre -l passé à telnet, qui vaut ici -froot. Je sens que vous commencez à sourire en voyant la blague pointer le bout de son nez... Qu'est-ce que va faire login de ce -froot ? Il va le prendre pour un passage du paramètre -f, introduit il y a peu, permettant d'atteindre un compte sans authentification. Allons voir le code de login.c, vers la ligne 1400 :

1399 case 'f':
1400     /*
1401      * Must be root to bypass authentication
1402      * otherwise we exit() as punishment for trying.
1403      */
1404     if (getuid() != 0 || geteuid() != 0) {
1405         audit_error = ADT_FAIL_VALUE_AUTH_BYPASS;
1406 
1407         login_exit(1);    /* sigh */
1408                           /*NOTREACHED*/
1409     }
1410     /* save fflag user name for future use */
1411     SCPYL(user_name, optarg);
1412     fflag = B_TRUE;
1413     break

Comme in.telnetd tourne en root, il a le droit d'utiliser cette option comme il y est gentillement invité par login, lequel va se faire un plaisir de nous loguer avec le login spécifié par -f. Il doit être noté que le bug est là depuis l'introduction d'OpenSolaris en 2005. Ça laisse songeur et soulève une remarque. Le bug est manifestement présent dans in.telnetd depuis un petit moment, c'est un fait facilement vérifiable. Les gens de Sun arguent qu'il est apparu durant le développement de Solaris 10, pas avant. En fait, personne ne l'avait vu avant l'apparition de cette option -f dans login, introduite avec le concept de Zones, fort bien décrit par Saad Kadhi dans MISC 28, comme le montre Laurent Blume , toujours sur le liste Sec. Voici en effet ce qu'on peut trouver dans les premières lignes du code de "login.c"[1] :

For a complete reference to login(1), see the manual page.
However, login has accreted some intentionally undocumented
options, which are explained here:
[...]
-f <username>: This flag was introduced by PSARC 1995/039 in
    support of Kerberos.  But it's not used by Sun's Kerberos
    implementation. It is however employed by zlogin(1),
    since it allows one to tell login: "This user is
    authenticated." In the case of zlogin that's true because
    the zone always trusts the global zone.

Ce qui a pu amener certains à associer les Zones et ce bug, ce qui est manifestement faux. Cette nouvelle option n'est en effet pas la cause du problème, mais son révélateur. Ce qui veut dire que si un autre programme présente le même genre de gageure dans son traitement de la variable USER, ça risque pêter à nouveau...

Bref, qu'est-ce que ça nous apprend ? D'abord que si vous utilisiez SSH comme tous les administrateurs consciencieux, vous seriez en train de vous marrez vous aussi au lieu de courir derrière vos Solaris pour les corriger autant que faire se peut. Un coup de svcadm disable telnetd et hop. Ensuite, bien que ça n'aide pas forcément beaucoup en l'espèce, que laisser root se connecter en remote, de surcroit en telnet, c'est souvent maaaaal, et plus largement depuis autre chose que /dev/console. Ça se passe dans /etc/default/login. Enfin, que supprimer tous les comptes qui ne servent pas n'est pas qu'un luxe. Dans le cas présent, l'installation de base en propose une bonne douzaine, dont certains ont des droits intéressants dans l'optique d'une escalade locale de privilèges, comme bin qui a le droit de modifier les binaires exécutés par root. Ça se passe de commentaire. Vous pouvez évidemment retrouver ces précieux conseils dans tous les bons guides de durcissement Unix que tout le monde a lu, évidemment, mais que beaucoup ont juste oublié d'appliquer...

Dans un registre légèrement différent, tout ceci me rappelle cette vieille anecdote à propos de telnet et rlogin. Tout commence avec un gars qui se fait défacer son site perso après s'être fait voler le mot de passe de son compte élève sur un réseau local étudiant. Il se loguait en telnet, forcément, puisqu'à l'époque, SSH n'était pas le bienvenu en France. Il s'agissait donc de trouver une solution au problème de ces mots de passe qui voyageaient en clair sur le réseau. C'est alors qu'une brillante idée fit son apparition : si le problème vient de l'envoi du mot de passe, il suffit de trouver un outil qui ne l'envoie pas. Et là, plus de mot de passe à voler, plus de problème, CQFD. Et voilà quelqu'un de conseiller l'usage de rlogin couplé avec un fichier .rhosts dûment rempli. Il n'allait pas se passer trois jours avant que le vilain ne frappe à nouveau sa victime avec succès, au plus grand désarroi de cette dernière... Morale à l'histoire ? On ne fait rien de bon avec des outils bancals. Utilisez SSH, intelligemment[2] !


BTW, le patch officiel, mais provisoire, de Sun est disponible ici[3] : http://sunsolve.sun.com/pub-cgi/tpatch.pl

Update : les patches officiels sont sortis er portent respectivement les numéros 120068-02 et 120069-02 pour Sparc et x86. L'installation se fait par smpatch update -i 120068-02 ou smpatch update -i 120069-02 selon votre architecture.

Sinon, il vous suffit de regarder le diff entre les deux dernières révisions... À lire également, le billet du SANS ISC Diary sur la question[4].

Notes

[1] Vous pourrez apprécier en connaisseur l'implémentation de ces options intentionnellement non documentées...

[2] J'en ai aussi une bonne sur le SSH Agent Forwarding, pour une prochaine fois...

[3] Vous apprécierez en connaisseur le nombre de fois vous devez acceptez des clauses...

[4] Celui sur le Black Tuesday est intéressant aussi, mais je le laisse à Newsoft ;)