Institut de technologie du Massachusetts. Cours magistral # 6.858. "Sécurité des systèmes informatiques." Nikolai Zeldovich, James Mickens. 2014 année
Computer Systems Security est un cours sur le développement et la mise en œuvre de systèmes informatiques sécurisés. Les conférences couvrent les modèles de menace, les attaques qui compromettent la sécurité et les techniques de sécurité basées sur des travaux scientifiques récents. Les sujets incluent la sécurité du système d'exploitation (OS), les fonctionnalités, la gestion du flux d'informations, la sécurité des langues, les protocoles réseau, la sécurité matérielle et la sécurité des applications Web.
Cours 1: «Introduction: modèles de menace»
Partie 1 /
Partie 2 /
Partie 3Conférence 2: «Contrôle des attaques de pirates»
Partie 1 /
Partie 2 /
Partie 3Conférence 3: «Débordements de tampon: exploits et protection»
Partie 1 /
Partie 2 /
Partie 3Conférence 4: «Séparation des privilèges»
Partie 1 /
Partie 2 /
Partie 3Conférence 5: «D'où viennent les systèmes de sécurité?»
Partie 1 /
Partie 2Conférence 6: «Opportunités»
Partie 1 /
Partie 2 /
Partie 3Conférence 7: «Native Client Sandbox»
Partie 1 /
Partie 2 /
Partie 3 Aujourd'hui, nous allons parler d'un système appelé
Native Client , que
Google utilise dans le monde réel. Il s'agit d'une technologie sandbox pour exécuter du code sur différentes plates-formes. Il est utilisé dans le
navigateur Chrome , permettant aux applications Web d'exécuter du code machine arbitraire. C'est en fait un système plutôt cool. Il illustre également les capacités d'isolation et une technique particulière de séparation des privilèges ou du bac à sable appelée
isolation des pannes logicielles ,
isolation des pannes logicielles , sans utiliser le système d'exploitation ou la machine virtuelle pour créer le bac à sable.

Au lieu de cela, le
client natif adopte une approche complètement différente pour regarder des instructions spécifiques dans un fichier binaire pour savoir s'il est sûr de l'exécuter ou non. Par conséquent, avant de commencer à étudier les détails techniques du système, découvrons pourquoi ces gars-là veulent vraiment exécuter du code machine? Leur intérêt spécifique est d'appliquer cette solution dans un navigateur Web, où vous pouvez déjà exécuter du code
JavaScript ,
Flash Player et d'autres processus. Pourquoi ces gars sont-ils si enthousiastes à l'idée d'exécuter du code sur la plate-forme
x86 ? Après tout, il semble que ce soit un pas en arrière.
Public: ils veulent obtenir des calculs très rapides.
Professeur: oui, c'est un énorme avantage du code machine. Même s'il peut être dangereux à long terme, il offre des performances élevées. Tout ce que vous ne feriez pas en
JavaScript , par exemple, écrire un programme et le compiler, fonctionnera vraiment beaucoup plus rapidement. Y a-t-il d'autres raisons?
Public: exécuter un code existant?
Professeur: à droite. Il est important que tout ne puisse pas être écrit en
JavaScript . Donc, si vous avez une application existante ou, dans la terminologie de l'industrie, du code «hérité» que vous avez l'intention d'exécuter sur Internet, cela semble être une excellente solution. Parce que vous pouvez simplement prendre une bibliothèque existante, par exemple, une sorte de «moteur» graphique complexe qui est à la fois sensible aux performances et à de nombreuses autres choses complexes que vous ne voulez pas réimplémenter, et ce sera une bonne solution.
Si vous programmez simplement une nouvelle application Web, devez-vous utiliser votre propre client si vous n'êtes pas particulièrement préoccupé par l'héritage ou les performances?
Public: Vous n'avez alors pas besoin d'utiliser
JavaScript .
Professeur: oui, c’est une bonne raison. Si vous n'aimez pas
JavaScript , vous n'avez pas besoin de l'utiliser, non? Vous pouvez utiliser, par exemple,
C , vous pouvez exécuter du code
Python , l'écrire en
Haskell , dans n'importe quel langage qui vous semble le plus approprié.
Donc, c'est une liste assez convaincante de motivation pour exécuter votre propre code dans un navigateur, et il est assez difficile d'obtenir des droits sur une telle action. Dans une seconde, nous examinerons les détails techniques, et maintenant je veux vous montrer une démonstration de formation simple que j'ai reçue du site Web
Native Client .

C'est assez simple, car vous pouvez prendre
C ++ ou un programme
C et l'exécuter dans un navigateur. Vous pouvez consulter cette page Web, qui est un fichier
HTML qui contient un tas de code
JavaScript .

La raison de l'existence de ce code
JavaScript est qu'il vous permet d'interagir avec des parties du
client natif . En ce qui concerne le fonctionnement du navigateur, la signification d'une telle solution est que vous avez une sorte de page Web contenant du code
JavaScript . Et cette solution fonctionne avec les privilèges des pages et vous permet de faire diverses choses sur la page Web elle-même, par exemple, communiquer avec le réseau dans certaines circonstances.
Native Client vous permet d'exécuter votre module à l'intérieur du navigateur, afin que le code
JavaScript puisse interagir avec lui et recevoir une réponse. Cela montre une partie du code
JavaScript nécessaire au
Native Client pour interagir avec le module
NaCl spécifique que nous sommes sur le point d'exécuter.

Et vous pouvez envoyer des messages à ce module. Comment cela se fait-il? Vous prenez l'objet de ce module en
JavaScript , l'appelez
postMessage, et supportez donc l'envoi de ce message au module
NaCl . Lorsque le module
NaCl répond, il lance la fonction de message en
JavaScript . Et dans ce cas particulier, une boîte de dialogue apparaît simplement dans le navigateur.

Donc, du côté
JavaScript , il s'agit d'une interface de page Web assez simple. La seule chose que vous devez faire en plus est d'affecter le module
NaCl de cette façon. Autrement dit, vous insérez simplement un module avec un
ID spécifique
ici . Le plus intéressant ici est le code
hello avec l'extension
nmf . Il dit simplement qu'il existe un fichier exécutable que vous devez télécharger et commencer à travailler avec lui dans un environnement
NaCl .

Ce code natif est vraiment comme tout autre code C ++ que vous pourriez écrire. La partie intéressante est cette fonction de traitement des messages
HandleMessage .

Il s'agit d'une classe
C ++ et chaque fois que le code
JavaScript envoie un message au code
natif , il exécute cette fonction. Il effectue une vérification
if (message = = 'hello') . Si c'est le cas, il créera une sorte de ligne de réponse et la renverra. C'est assez simple. Mais pour plus de détails, essayons de l'exécuter et voyons ce qui se passe.
Nous pouvons construire et exécuter un petit serveur Web qui servira cette page et le module
Native Client . Ici, je peux aller à cette
URL , et ici nous voyons la page Web
NaCl . Le module a reçu notre message de bienvenue de
JavaScript , a répondu en retour avec une chaîne en
JavaScript et le code
JavaScript a déclenché une boîte de dialogue contextuelle contenant cette réponse.

Donc ça marche vraiment.
Essayez de savoir si nous pouvons provoquer le crash du
Native Client . J'espère que non, mais nous pouvons prendre ce code et ce tampon et y écrire un tas de bêtises, par exemple 65536 et voir ce qui se passe.

J'espère que cela ne devrait pas faire planter mon navigateur car le
client natif essaie de fournir l'isolement. Mais voyons ce qui se passe.
Redémarrez le serveur Web. On voit que l'entrée du module est toujours réussie, notre navigateur n'a pas été blessé. Cependant, la messagerie avec le client n'a pas eu lieu, donc la boîte de dialogue est manquante. Regardons la console
JavaScript au bas de la page et voyons que le module
Native Client nous informe de l'échec du module
NaCl .

Il est possible que l'argument que j'ai entré ait provoqué un débordement de tampon ou un accès à une mauvaise adresse, mais dans tous les cas, le module
NaCl est vraiment capable d'isoler la corruption de mémoire accidentelle de telle manière qu'elle n'affecte pas le navigateur.
Il s'agit d'une démonstration rapide de ce système sous la forme dans laquelle vous pouvez l'utiliser en tant qu'utilisateur final ou développeur. Regardons quelques autres exemples. Par exemple, comment le
Native Client fonctionnera, ou pourquoi nous en avons besoin, et non une conception alternative.
Par conséquent, si votre objectif est d'isoler votre propre code, il existe plusieurs alternatives avec lesquelles vous pouvez le faire. En fait, les gens avaient du mal à utiliser le code hérité et d'autres langues avant l'apparition du
Native Client . Ils les ont résolus de diverses manières, qui n'étaient peut-être pas aussi sécurisées et pratiques que le
client natif , mais fournissaient les mêmes capacités d'isolement.
Alors, que devez-vous faire si vous voulez vraiment exécuter le code machine dans un navigateur? Une option est la confiance dans le développeur. Une variante de cette approche consiste peut-être à demander à l'utilisateur s'il souhaite exécuter un morceau de code dans son navigateur ou non.
Donc, tout le monde comprend à peu près de quel type de plan il s'agit, non? Par exemple, au lieu de toute cette stratégie de compilation
Native Client , je pourrais simplement créer un programme
C , l'exécuter dans un navigateur, et il me demanderait si je veux exécuter ce site ou non? Et si je clique sur "oui", "tondant" accidentellement dans la mémoire du navigateur, il se bloquera. C'est donc possible, non? Bien sûr, cela résout tous ces problèmes, mais qu'est-ce qui ne va pas?
Je pense que la mauvaise chose est que cette solution n'est pas sûre. C'est une façon de contourner ce système et de nombreux autres systèmes.
Microsoft avait un système appelé
ActiveX qui implémentait essentiellement ce plan. Vous pouvez envoyer les fichiers binaires à
IE , le navigateur de votre ordinateur, et jusqu'à ce qu'ils reviennent avec un certificat d'un développeur spécifique signé par, disons,
Microsoft ou quelqu'un d'autre, le navigateur n'exécutera pas votre code. Pensez-vous que ce soit un plan utile?
Public: C'est une question de confiance!
Professeur: oui, ça l'est. Vous devez vraiment faire confiance un peu au développeur qui ne signera que les «binaires» qui ne feront rien de mal. Mais il est souvent impossible de déterminer si c'est une mauvaise chose ou non, alors ils écrivent simplement du code
C et le signent aveuglément sans faire énormément de travail. Dans ce cas, vous pourriez bien rencontrer certains problèmes à l'avenir.
De même, la décision de demander à l'utilisateur s'il veut vraiment exécuter une chose ne garantit pas du tout la sécurité. Même si l'utilisateur veut être prudent, on ne sait pas vraiment comment il doit décider? Supposons que je veuille vraiment comprendre si je peux laisser ce programme fonctionner? On me dit que tout va bien, peut-être qu'il a été créé par des développeurs réputés de
Google.com ou
Microsoft.com . Cependant, il s'agit du fichier exécutable
foo.exe et je ne sais absolument pas ce qu'il
contient . Même si je démonte son code, il sera très difficile de dire s'il va faire quelque chose de mal ou non. Par conséquent, il est vraiment difficile pour l'utilisateur de décider si l'exécution du code est sûre pour le système.

Ainsi, le
client natif peut agir comme un mécanisme par lequel les utilisateurs peuvent obtenir une certaine confiance s'ils doivent dire oui ou non à un programme.
Donc, dans la pratique, je pense, il devrait y avoir une option proposée par notre conférencier invité Paul Yang la semaine dernière. Il a conseillé d'exécuter le plug-in "
play extension " ou "play the extension" dans le
navigateur Chrome . Autrement dit, il s'avère qu'avant de démarrer une extension, y compris le
client natif , vous devez cliquer sur cette chose. D'une certaine manière, cela revient à demander à l'utilisateur. Mais dans ce cas, même si l'utilisateur décide de répondre «oui», le système sera toujours sûr, car le
Native Client sera inclus dans le travail. En ce sens, nous avons un double mécanisme de sécurité: demandez d'abord à l'utilisateur, puis, avec une réponse positive, démarrez le client sandbox, ce qui ne permettra pas au navigateur de planter.
Ainsi, une autre approche qui devrait être appliquée est d'utiliser le bac à sable, implémenté au moyen du système d'exploitation ou du matériel, ou d'isoler les processus. C'est ce que nous avons examiné dans les 2 dernières conférences.
Peut-être que vous utiliseriez
des mécanismes d'isolement
Unix . Si vous aviez quelque chose de plus complexe, vous utiliseriez
FreeBSD ou
Capsicum . Il est idéal pour isoler un morceau de code dans le bac à sable, car vous pouvez limiter ses capacités.
Linux a un mécanisme similaire appelé
Seccomp , que nous avons brièvement abordé dans la dernière conférence, il vous permet également de faire de telles choses.
Ainsi, il existe déjà un mécanisme pour écrire du code de manière isolée sur votre machine. Pourquoi ces gars-là sont contre l'utilisation de cette solution existante? Il semble qu'ils «inventent la roue» pour une raison quelconque. Alors qu'est-ce qui se passe?
Public: peut
- être qu'ils veulent minimiser les erreurs?
Professeur: oui, d’une certaine manière, ils ne font pas confiance au système d’exploitation. Peut-être sont-ils réellement préoccupés par les erreurs du système d'exploitation. Il est probable que le noyau
FreeBSD ou le
noyau Linux contiennent beaucoup de code
C dont ils ne veulent pas ou ne peuvent pas vérifier l'exactitude, même s'ils le voulaient. Et dans
Capsicum ou
Seccomp, le travail se fait sur la base d'un plan d'isolement, il suffit donc que le noyau ne dispose que d'un petit morceau fidèle de code, pour que le bac à sable conserve et applique l'isolement.
Public: étant donné que vous disposez de beaucoup plus de façons d'utiliser les navigateurs, vous devez gérer différents systèmes d'exploitation, tels que iOS et Android, et accéder à ...
Professeur: oui, en fait, une autre considération intéressante est que généralement de nombreux systèmes d'exploitation ont des erreurs. De plus, en fait, différents systèmes d'exploitation sont en quelque sorte incompatibles entre eux. Cela signifie que chaque système d'exploitation a son propre mécanisme, comme indiqué ici:
Unix a
Capsicum ,
Linux a
Seccomp , mais ce ne sont que des variantes d'
Unix .
Mac OS a la
ceinture de sécurité ,
Windows a autre chose et la liste continue.
Donc au final, chaque plateforme avec laquelle vous travaillez a son propre mécanisme d'isolement. Et ce qui ne les dérange pas vraiment, c'est qu'ils devront écrire du code différent pour
Mac ,
Windows et
Linux . Mais plus encore, cela affecte la façon dont vous écrivez ces choses pour qu'elles fonctionnent à l'intérieur du bac à sable. Parce que dans le
client natif, vous écrivez en fait un morceau de code qui s'exécute de la même manière que le code de système d'exploitation "natif", de la même manière que
le code
Apple ,
le code
Windows ou le code système
Linux s'exécute.
Et si vous utilisez ces mécanismes d'isolement, ils imposent en fait différentes restrictions au programme placé dans le bac à sable. Vous devez donc écrire un programme qui s'exécutera à l'intérieur du bac à sable
Linux , un autre programme à exécuter à l'intérieur du bac à sable
Windows , etc.
C'est ce qui est vraiment inacceptable pour eux. Ils ne veulent pas faire face à des problèmes de ce genre. Quelles autres considérations avez-vous?
Public: vraisemblablement les performances du système. Parce que si vous utilisez
Capsicum , vous devez prendre soin de ressources suffisantes pour vous assurer que les processus fonctionnent à l'intérieur du bac à sable. Ici, ils peuvent être confrontés au même problème.
Professeur: oui, c'est vrai. Le plan d'isolation des plantages logiciels est en fait très gourmand en ressources, ce qui au niveau du système d'exploitation peut entraîner un manque de ressources pour prendre en charge le bac à sable. Il s'avère que dans leur propre
client natif, ils utilisent en fait à la fois leur sandbox et leur sandbox OS pour fournir une sécurité supplémentaire. Ainsi, en fait, ils ne gagnent pas dans la performance de leur mise en œuvre, même s'ils le pourraient probablement.
Public: peut
- être qu'ils veulent tout contrôler. Parce qu'ils peuvent contrôler ce qui se passe dans le navigateur, mais s'ils l'ont envoyé à l'ordinateur du client sur le système d'exploitation, ils ne savent pas ce qui pourrait s'y passer.
Professeur: on peut dire que oui, le système d'exploitation peut avoir des erreurs ou ne pas gérer assez bien le bac à sable. Ou l'interface est un peu différente, donc vous ne savez pas ce que le système d'exploitation est sur le point de révéler.
Public: cela n'empêchera pas le code de faire de mauvaises choses. Il y a beaucoup de choses que le code fait, par exemple, vous voulez effectuer une analyse statique, mais les boucles de code empêchent le programme d'agir.
Professeur: en fait, il est très difficile de déterminer s'il existe un processus en boucle infinie ou non, mais en principe, cette approche vous permet de détecter certains problèmes de code. Je pense qu'un exemple vraiment intéressant, que je ne connaissais pas avant d'avoir lu leur article, montre que ces gars sont inquiets des erreurs matérielles, et pas seulement des vulnérabilités du système d'exploitation qui peuvent être exécutées par le code. Par exemple, le processeur lui-même contient des instructions qui peuvent entraîner le gel ou le redémarrage de l'ordinateur. Fondamentalement, votre équipement ne devrait pas avoir une telle erreur, car le système d'exploitation repose sur le fait que le matériel l'aidera en tout cas à atteindre le noyau afin de prendre soin d'éliminer les conséquences d'une erreur utilisateur.
Mais il s'avère que les processeurs sont si complexes qu'ils ont des erreurs, et ces gars-là disent qu'ils en ont trouvé la preuve. S'il existe des instructions complexes que le processeur ne s'attendait pas à recevoir, il s'arrêtera au lieu de traiter le cœur du système. C'est mauvais. Je pense que ce n'est pas catastrophique si je lance juste quelques choses utiles sur mon ordinateur portable, mais bien pire si l'ordinateur se bloque lorsque je visite une sorte de page Web.
Ainsi, ils voulaient créer un niveau de protection plus élevé pour les modules
Native Client que celui qui assure l'isolement au niveau du système d'exploitation, même sans erreurs matérielles. Donc, en ce qui concerne la sécurité, ils se comportent comme des paranoïaques, y compris le problème de sécurité du matériel.
Voyons maintenant comment le
client natif isole réellement les processus dans le bac à sable. Ainsi, le
client natif adopte une approche différente, qui peut être appelée «isoler les pannes logicielles».

Le plan n'est pas de s'appuyer sur le fait que le système d'exploitation ou l'équipement vérifiera les choses pendant que le programme est en cours d'exécution, mais de s'appuyer sur eux pour revoir les instructions à l'avance et décider qu'elles peuvent être exécutées en toute sécurité. Ainsi, en fait, il suffit de regarder le fichier binaire pour vérifier toutes les instructions possibles et voir si elles seront sûres ou non. Une fois que vous avez décidé que tout sera en sécurité, vous pouvez simplement démarrer le processus car vous savez qu'il se compose de choses sûres et qu'il n'y aura pas d'échecs.
Donc, ce qu'ils vont faire, c'est regarder presque toutes les instructions du code binaire qui est envoyé au navigateur et décider si des instructions spécifiques sont sûres ou non.
? . ? , , .
-
ALU , , . , . , , . , , , .

? , , . , , , . , «» , ? .
, , , - , . «» , - . , «» , . , , , , .
, ( ) . . ,
if , , . , , – .
, , , . . , , . , , , , «» .

. , , . , , .
, , , , - , . , , , , .
Trusted Service Runtime , . .
Google . ,
NaCl .
, , , , , — , — . , .
: , ,
NaCl ? , ?
: , , ,
NaCl . ,
malloc pthread_create ,
Trusted Service Runtime . - ,
Unix , - . , ,
JavaScript -.
RPC JavaScript , .

, ,
NaCl Unix -, - , -.
. ,
Native Client . –
Native Client ?
,
Native Client . , , . , ,
x86 . , , «», .
, . , , 0 256 . , , , , .
? , ?
: , .
: , . , , . , , ? , ?
: .
: !
: -, , . .
: , . , . , , . , , ,
Trusted Service Runtime . , ,
Trusted Service Runtime , . , .
, ,
NaCl , . , 0. ,
NaCl . .
28:00
:
Cours MIT "Sécurité des systèmes informatiques". 7: « Native Client», 2.
, . Aimez-vous nos articles? Vous voulez voir des matériaux plus intéressants? Soutenez-nous en passant une commande ou en le recommandant à vos amis, une
réduction de 30% pour les utilisateurs Habr sur un analogue unique de serveurs d'entrée de gamme que nous avons inventés pour vous: Toute la vérité sur VPS (KVM) E5-2650 v4 (6 cœurs) 10 Go DDR4 240 Go SSD 1 Gbps à partir de 20 $ ou comment diviser le serveur? (les options sont disponibles avec RAID1 et RAID10, jusqu'à 24 cœurs et jusqu'à 40 Go de DDR4).
3 mois gratuits lors du paiement d'un nouveau Dell R630 pour une période de six mois - 2 x Intel Deca-Core Xeon E5-2630 v4 / 128GB DDR4 / 4x1TB HDD ou 2x240GB SSD / 1Gbps 10 TB - à partir de 99,33 $ par mois , uniquement jusqu'à fin août, commandez peut être ici .Dell R730xd 2 fois moins cher? Nous avons seulement
2 x Intel Dodeca-Core Xeon E5-2650v4 128 Go DDR4 6x480 Go SSD 1 Gbps 100 TV à partir de 249 $ aux Pays-Bas et aux États-Unis! Pour en savoir plus sur la
création d'un bâtiment d'infrastructure. classe utilisant des serveurs Dell R730xd E5-2650 v4 coûtant 9 000 euros pour un sou?