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 3Conférence 8: «Modèle de sécurité réseau»
Partie 1 /
Partie 2 /
Partie 3 Que se passe-t-il si le navigateur ne traite pas correctement l'objet et ne peut pas identifier son type? Dans ce cas, vous pouvez rencontrer des problèmes de sécurité. L'un d'eux est appelé une attaque MIME.
Vous connaissez probablement MIME - il s'agit d'un type d'en-têtes non chiffrés comme text / html, image.jpeg, etc. Ainsi, les anciennes versions du navigateur IE l'utilisaient car elles pensaient que cela aiderait l'utilisateur. Mais il arrive parfois que les serveurs Web attribuent la mauvaise extension au fichier objet.
Un serveur Web mal configuré peut attacher le suffixe .html à ce qu'il a réellement l'extension .jpeg, ou vice versa, par exemple, créer foo.jpg au lieu de foo.html.

Donc, dans le temps, IE essayait de vous aider. Autrement dit, il est allé prendre une sorte de ressource, tout en pensant: "OK, cette ressource prétend être de ce type, conformément à son extension de nom de fichier." Mais alors il ne regardera que les 256 premiers octets disponibles dans cet objet. Et s'il y trouvait certaines significations magiques qui indiquaient qu'il y avait un type d'extension différent pour cet objet, il dirait simplement: «hé, j'ai trouvé quelque chose de cool ici! "Je pense que le serveur Web a défini cet objet par erreur, alors laissez-moi simplement traiter cet objet comme le type que j'ai trouvé dans ces 256 premiers octets."
Et puis tout le monde devient gagnant, car un navigateur comme a aidé le développeur du serveur Web, car maintenant leur site sera affiché correctement. Et l'utilisateur l'appréciera, car il pourra déverrouiller ce contenu, qui n'était autrefois que des ordures.
Mais c'est une vulnérabilité évidente! Supposons que la page contienne du contenu passif, par exemple, une image d'un domaine contrôlé par un attaquant. Cependant, la page de la victime pense: «même si c'est le contenu d'un site de pirate malveillant, c'est juste du contenu passif. Il ne peut rien me faire! » Dans un cas extrême, une image infructueuse sera affichée, mais elle ne pourra pas ouvrir de code, car le contenu passif n'a aucun privilège.

Mais le fait est qu'IE peut d'abord «renifler» cette image, ses 256 premiers octets. Et un attaquant peut intentionnellement y mettre du code HTML et JavaScript. Il s'avère ensuite que le site de la victime apportera ce qu'il considère être une image, et IE exécutera du code malveillant dans le contexte de la page intégrée.
Ceci est une sorte d'exemple de la complexité des navigateurs et de la façon dont l'ajout, même de très bonnes intentions, peut provoquer des erreurs de sécurité très subtiles. Examinons donc de plus près comment le navigateur protège diverses ressources.
Regardons les cadres et les objets de fenêtre (objets qui sont une fenêtre contenant un document DOM). Les cadres représentent ces univers JavaScript indépendants dont nous avons parlé ici. Je veux dire, JavaScript est une instance du nœud DOM, comme le montre l'image de l'arbre DOM.
De cette façon, le cadre existera en tant qu'objet de nœud DOM quelque part dans cette hiérarchie visible par JavaScript.
En JavaScript, l'objet window est en fait un alias pour l'espace de noms global. Cela ressemble à une idée stupide. Autrement dit, si vous deviez trouver le nom de la variable globale x, vous seriez également en mesure d'y accéder via le nom window.x.
Ainsi, les cadres et les objets de fenêtre sont des références très puissantes pour vous donner l'accessibilité. Et ils contiennent des pointeurs les uns vers les autres. Un cadre peut contenir un pointeur vers un objet fenêtre lié et vice versa. En fait, ces deux choses sont équivalentes.
Les cadres et les objets de fenêtre reçoivent la source d'origine d'origine du cadre URL, ou parce qu'ils sont toujours dans une partie sécurisée du réseau, ils peuvent obtenir le suffixe du nom de domaine d'origine, c'est-à-dire son origine d'origine.
Par exemple, une trame peut commencer comme ceci: .xyzcom, ici vous pouvez ignorer le schéma et le protocole pendant une seconde.
Dans ce cas, nous pouvons supposer que la source d'origine de (document.domain) est le suffixe yzcom. De même, la source d'origine de ce document est l'expression z.com. Ceci est possible car z.com est un suffixe de yzcom.

La seule chose qui ne peut pas servir de telle source est l'expression .ayzcom, car c'est le mauvais suffixe pour la source d'origine d'origine. En outre, le suffixe source correct de la source d'origine ne peut pas être considéré simplement .com, car dans ce cas, le site pourra en quelque sorte affecter les cookies ou quelque chose de similaire sur n'importe quel site comme .com, ce qui peut avoir des conséquences assez dévastatrices.
La raison pour laquelle ces types de choses sont acceptables est qu'elles sont liées à un certain type de relation de confiance existante. Il semble donc qu'avec les trois premiers paramètres, tout est en ordre, et le désordre n'est qu'en .com.
Public: il s'avère qu'il est possible de faire de telles scissions à tout moment ou au point final? Par exemple, votre xyzcom peut-il être changé pour votre z.com?
Professeur: non, cela ne s'applique qu'à tous les points.
Public: y a-t-il une raison pour laquelle cela n'a pas été fait afin que vous puissiez indiquer un super- ou un sous-domaine, mais en même temps, ils devraient en quelque sorte s'entendre sur la provenance des informations? Disons que je ne veux accepter que ce qui a la même origine que le mien, afin que n'importe laquelle de ces ressources puisse m'attaquer. De plus, nous rendrions cette interaction symétrique, pour que je puisse aussi l'influencer. Après tout, le suffixe source .com signifie que tout ce qui a le même suffixe .com peut m'affecter.
Professeur: oui, c'est difficile, il y a donc plusieurs réponses à cette question. Premièrement, les gens étaient très inquiets de la possibilité d'une attaque avec .com. Par conséquent, ils voulaient rendre le langage de manipulation de domaine facile à comprendre. Ainsi, ils n'ont pas permis de gâcher les paramètres.
Dans une seconde, je vais parler d'une chose qui vous permet de faire ce dont vous parlez, mais uniquement en ce qui concerne les suffixes de domaine. Pour l'instant, je tiens à noter que l'interface Post Message permet aux domaines de communiquer entre eux s'ils y consentent. Donc, dans la pratique, les gens utilisent Post Message pour implémenter une communication interdomaine s'ils ne peuvent pas établir la même source d'origine en utilisant les astuces décrites ci-dessus. De cette façon, les navigateurs peuvent restreindre les domaines en fonction de ces suffixes du domaine source. Et ici, il y a aussi une petite nuance intéressante - les navigateurs comprennent quand (document.domain) peut être écrit, et quand il ne peut pas.
Il y a une raison à cela, que nous examinerons dans une seconde. Ainsi, deux trames peuvent accéder l'une à l'autre si au moins une des deux conditions suivantes est vraie:
- les deux ensembles de cadres définissent (document.domain) la même valeur;
- aucun de ces cadres ne peut changer (document.domain), malgré le fait que la valeur de ce document dans les deux cadres est la même.

L'idée principale de ces règles est qu'elles protègent le domaine contre les attaques causées par leurs propres erreurs ou la nocivité de l'un des sous-domaines.
Imaginez que vous disposez d'un domaine xyzcom qui tente d'attaquer le domaine yzcom parce que le premier domaine contient une erreur ou est malveillant. Il essaiera de raccourcir le domaine yzcom en un aspect .com, puis commencera à se «chimiser» avec l'état de JavaScript, des cookies ou d'autres choses.

Donc, ces deux règles signifient que si yzcom ne veut pas permettre à quiconque d'interagir avec lui, il ne changera jamais la valeur (document.domain). Donc, lorsque le cadre xyzcom veut le raccourcir, le navigateur dira: "Oui, vous voulez le raccourcir, mais vous n'avez pas le droit de le faire!" Il y a une coïncidence de valeurs, mais le domaine yzcom n'a pas indiqué qu'il souhaite y participer. Est-ce clair? Dans ce cas, on peut voir que la plupart des cadres fonctionnent avec la même politique d'origine.
Nous pouvons maintenant voir comment notre nœud DOM est traité. C'est assez simple. En règle générale, les nœuds DOM tirent leur origine du cadre environnant. Dans le cas des cookies, c'est un peu plus compliqué. Les cookies ont un domaine et ils ont leur propre chemin. Par exemple, vous pourriez imaginer qu'un cookie pourrait être associé aux informations suivantes, par exemple * .mit.edu / 6.858. Dans ce cas, le cookie a un * .mit.edu / domain et un chemin d'accès 6.858.

Veuillez noter que ce domaine peut être le suffixe complet des pages du domaine actuel. Vous pouvez donc effectuer avec lui les mêmes astuces que celles dont nous avons parlé plus tôt. Notez que ce chemin 6.858 peut également être représenté comme une barre oblique, suivie de rien, ce qui indique que tous les chemins de domaine doivent avoir accès au cookie situé ici.
Mais dans ce cas, nous avons une adresse de chemin spécifique. Ainsi, celui qui définit ces cookies a la possibilité de voir à quoi ressemblent le domaine et le chemin. Et ces valeurs peuvent être définies à la fois côté serveur et côté client. Côté client, vous aurez un objet JavaScript appelé document.cookie. Il s'agit du format utilisé pour indiquer tous les chemins d'accès à des objets similaires.
Il existe un indicateur de sécurité d'indicateur sécurisé que vous pouvez définir sur un cookie pour indiquer qu'il s'agit d'un fichier HTTPS. Dans ce cas, le contenu HTTP ne devrait pas avoir accès à ce cookie. C'est l'idée principale des cookies.
Veuillez noter que chaque fois qu'un navigateur génère une demande à un serveur Web spécifique, il va inclure tous les cookies pertinents dans cette demande. Il existe une sorte de ligne de correspondance et d'algorithmes qui permettent de savoir que ce sont les bons cookies qui doivent être envoyés en réponse à une demande, car ils peuvent avoir des choses étranges avec des suffixes de domaine, etc.
Public: les cadres peuvent-ils accéder aux cookies les uns des autres s'ils respectent ces règles?
Professeur: oui, les cadres peuvent le faire. Mais cela dépend de la façon dont le document.domain est défini, du domaine des cookies et du chemin. Ainsi, les cadres peuvent accéder aux cookies les uns des autres, d'où la question qui se pose: peut-il y avoir un problème si nous permettons à des cadres arbitraires d'écrire des cookies arbitraires aux gens? Il suffit de dire que ce sera mauvais. La raison pour laquelle cela est mauvais est que ces cookies permettent au côté client de l'application de stocker des données utilisateur.
Vous pouvez donc imaginer que si un attaquant peut contrôler ou redéfinir les cookies utilisateur, il peut, par exemple, modifier le cookie pour Gmail afin que l'utilisateur se connecte via le compte Gmail appartenant à cet attaquant. Dans ce cas, toute lettre d'utilisateur pourrait être lue par un attaquant. Vous pouvez imaginer que quelqu'un pourra obtenir des cookies d'Amazon.com pour mettre toutes sortes d'achats ridicules et autres dans votre panier.
Ainsi, les cookies sont une ressource très importante pour la protection. Et de nombreuses attaques de sécurité réseau sont conçues pour les voler et les utiliser pour nuire.
Il y a une autre question intéressante concernant les cookies. Supposons que vous ayez un site foo.co.uk. Que faire si un site avec ce nom d'hôte est en mesure de définir des cookies pour co.uk?

Il y a ici une subtilité liée aux règles dont nous avons parlé plus haut, car le premier site devrait pouvoir raccourcir son domaine et paramétrer les cookies pour le second, tout semble légal ici. Mais d'un point de vue humain, nous le regardons avec suspicion, car nous comprenons que co.uk est un domaine atomique unique. Cependant, cela équivaut à .com. On peut dire que les Britanniques ont foiré qu'ils devraient avoir raison ici. Mais ce n'est pas de leur faute. D'un point de vue moral, il s'agit d'un seul domaine unique qui ne peut pas être rompu. Par conséquent, nous devons disposer d'une infrastructure spéciale pour que les cookies fonctionnent correctement.
Mozilla a un site Web appelé publicsuffix.org qui contient des listes de règles sur la façon dont les cookies, l'origine et les domaines doivent être raccourcis, en tenant compte du fait qu'il peut y avoir des points dans certaines choses, alors qu'en fait ils doivent être considérés comme un seul atomique le tout.
Ainsi, lorsque votre navigateur découvrira comment il doit manipuler différents cookies, il devra alors vérifier ce côté du problème. Ou assurez-vous que foo.co.uk ne peut pas raccourcir le domaine en co.uk. Il y a donc ici un problème très sensible.
Nous découvrons de nombreux problèmes de sécurité Web plus intéressants au cours du processus, car une grande partie de l'infrastructure d'origine a été développée spécifiquement pour la langue anglaise. Par exemple, du texte ASCII ou quelque chose comme ça. Il n'a pas été initialement conçu pour être utilisé par la communauté internationale.
Mais comme Internet est devenu plus populaire, les gens ont commencé à dire: «hé, au début, nous avons créé une conception assez large de solutions et maintenant nous devons l'adapter aux personnes qui sont obligées d'utiliser notre compréhension étroite de ce que signifie la langue.» Par conséquent, nous sommes maintenant confrontés à tous ces problèmes fous.
Considérez comment les réponses XML HTTP sont gérées par la même stratégie source d'origine. Par défaut, JavaScript ne peut en générer qu'un s'il est construit sur son serveur d'origine. Cependant, il existe une nouvelle interface appelée Cross Origin Request, ou CORS.
Il s'agit donc de la même origine, sauf si le serveur a activé ce gizmo CORS. Fondamentalement, un nouvel en-tête de réponse HTTP est ajouté appelé Access-Control-Allow-Origin.

Supposons que JavaScript de foo.com veuille faire une requête HTTP XML à bar.com. Comme décrit dans les règles, l'origine croisée a lieu ici. Et si le serveur bar.com veut autoriser cela, il retournera sa réponse HTTP avec le titre: "oui, je laisse foo.com m'envoyer ces requêtes XML XML d'origine croisée."
En fait, le serveur bar.com peut répondre «non», c'est-à-dire qu'il peut refuser la demande. Dans ce cas, le navigateur ne peut pas terminer la requête XML HTTP. C'est donc une sorte de nouveauté, qui est apparue principalement en raison d'applications mixtes. Il est nécessaire pour les applications de différents développeurs et de différents domaines, afin qu'ils aient la possibilité d'échanger des données entre eux.

Ainsi, au lieu de foo.com, il peut y avoir des astérisques ici si quelqu'un veut obtenir des données d'origine croisée, etc. Je pense que c'est assez simple. Il y a un tas d'autres ressources que nous pourrions regarder, comme les images. Grâce à Access-Control-Allow-Origin, un cadre peut charger des images à partir de n'importe quelle source de son choix. Mais il ne peut pas vérifier les morceaux de cette image, car on pense qu'avec différentes politiques de sources d'origine, il n'est pas bon de vérifier le contenu de leurs fichiers respectifs.
Bien que le cadre ne puisse pas vérifier les bits, il peut toujours déduire la taille des images car il voit comment ils sont placés sur la page. Il s'agit donc d'un autre de ces cas étranges où la même politique de source d'origine tenterait d'empêcher toutes les fuites d'informations. Mais en fait, il n'est pas en mesure d'empêcher tout cela, car l'intégration de l'héritage, en fait, affiche certains types d'informations.
Le CSS est similaire aux images, donc un cadre peut intégrer du CSS à partir de n'importe quelle source. Cependant, il ne peut pas vérifier directement le texte à l'intérieur du fichier CSS s'il provient d'une autre source. Mais il peut reconnaître ce que fait ce CSS car il crée simplement un tas de nœuds et regarde ensuite comment leur style change. Et ça a l'air un peu étrange.
JavaScript est mon exemple préféré de la façon dont cette même politique d'origine essaie de prendre en charge tout type de séquence intelligente. L'idée ici est que si vous effectuez une récupération croisée de JavaScript, cela est autorisé. Vous pouvez activer l'exécution de JavaScript externe dans le contexte de votre propre page, mais vous ne pouvez pas regarder le code source.

Par conséquent, si vous avez une source de balise de script égale à quelque chose en dehors de votre domaine, lorsque cette source est exécutée, vous pouvez y initier des fonctions. Mais vous ne pourrez pas y voir le code source JavaScript.
Tout cela semble très bien, mais il a un tas de "trous". Par exemple, JavaScript est un langage de script dynamique. Et les fonctions sont des objets de première classe. Ainsi, pour n'importe quelle fonction f, vous pouvez simplement utiliser la fonction f.tostring (), et cela vous donnera le code source de la fonction f. Et les gens font ça tout le temps, ils font de la réécriture dynamique, etc.

Ainsi, bien que les stratégies d'origine ne vous permettent pas d'afficher directement le contenu de la balise de script, vous pouvez simplement effectuer l'opération spécifiée et obtenir le code source.
De même, vous pouvez obtenir votre serveur domestique à partir de votre domaine, juste pour y récupérer le code source, puis vous le renvoyer. En fait, vous venez de demander à votre serveur domestique d'exécuter le programme Wget pour obtenir le code source de cette manière. Cela semble donc un peu idiot, c'est-à-dire que la politique d'origine ici est un peu étrange.
Public: Supposons que la raison pour laquelle ils le font est d'empêcher l'utilisateur de recevoir JavaScript, car des cookies peuvent également être envoyés. Autrement dit, l'utilisateur pourra adapter le JavaScript résultant à ses besoins.
Professeur: oui, ça l'est.
Public: si vous demandez à votre serveur de le faire, il ne pourra pas vous fournir de cookies personnalisés.
Professeur: c'est vrai, bien qu'en pratique le code source "brut" ne soit pas destiné à être retravaillé par l'utilisateur. Mais vous avez raison, cela empêchera certaines attaques.
, , JavaScript, . , - , -, , . , , , . , , .
, . - - , - HTML JavaScript. , , . .
, JavaScript, , . Java, .

, HTML5 , , , , Java. , .
, HTTP, cookie. , URL, ?

, URL- bank.com. , - . , URL, , , $500 . , .
— , origin, bank.com - , , cookie . : «, , , $500 attacker! , ».
. , , , , . . , , , , - . , , CSRF.
, URL. , c .
, - . – , , :
<form action = “/transfer.cdi”…>
Et à l'intérieur de ce formulaire, nous aurons les données d'entrée, qui sont généralement utilisées pour saisir du texte, des frappes, des clics de souris, etc. En fait, nous pouvons masquer cette entrée afin qu'elle n'apparaisse pas sur la page de l'utilisateur: type d'entrée = "caché", attribuez-lui le nom d'attribut = "csrf" et la valeur aléatoire valeur = "a72f ...". Ce formulaire sera généré sur le serveur.

Ainsi, lorsque l'utilisateur accède à cette page, côté serveur, le serveur génère cette valeur aléatoire = "a72f ..." et l'intègre dans le code HTML que l'utilisateur reçoit. Par conséquent, lorsque l'utilisateur remplit ce formulaire, cette URL du formulaire:
bank.com/xfer?amount=500&to=attackerIl est complété par un jeton aléatoire:
http:
Cela signifie que l'attaquant devrait maintenant pouvoir deviner le jeton spécifique que le serveur génère pour l'utilisateur à chaque fois qu'il accède à la page de la banque. Donc, si nous avons une valeur suffisamment aléatoire, le pirate ne pourra rien simuler, car s'il indique le mauvais jeton, les règles du serveur rejetteront sa demande.
58:00 min
Suite:
Cours MIT "Sécurité des systèmes informatiques". Conférence 8: Modèle de sécurité réseau, partie 3La version complète du cours est disponible
ici .
Merci de rester avec nous. 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).
VPS (KVM) E5-2650 v4 (6 cœurs) 10 Go DDR4 240 Go SSD 1 Gbit / s jusqu'en décembre gratuitement en payant pour une période de six mois, vous pouvez commander
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?