MIT-Kurs "Computer Systems Security". Vorlesung 7: Die Native Client Sandbox, Teil 1

Massachusetts Institute of Technology. Vorlesung # 6.858. "Sicherheit von Computersystemen." Nikolai Zeldovich, James Mickens. 2014 Jahr


Computer Systems Security ist ein Kurs zur Entwicklung und Implementierung sicherer Computersysteme. Die Vorträge behandeln Bedrohungsmodelle, Angriffe, die die Sicherheit gefährden, und Sicherheitstechniken, die auf jüngsten wissenschaftlichen Arbeiten basieren. Zu den Themen gehören Betriebssystemsicherheit, Funktionen, Informationsflussmanagement, Sprachsicherheit, Netzwerkprotokolle, Hardwaresicherheit und Sicherheit von Webanwendungen.

Vorlesung 1: „Einführung: Bedrohungsmodelle“ Teil 1 / Teil 2 / Teil 3
Vorlesung 2: „Kontrolle von Hackerangriffen“ Teil 1 / Teil 2 / Teil 3
Vorlesung 3: „Pufferüberläufe: Exploits und Schutz“ Teil 1 / Teil 2 / Teil 3
Vorlesung 4: „Trennung von Privilegien“ Teil 1 / Teil 2 / Teil 3
Vorlesung 5: „Woher kommen Sicherheitssysteme?“ Teil 1 / Teil 2
Vorlesung 6: „Chancen“ Teil 1 / Teil 2 / Teil 3
Vorlesung 7: „Native Client Sandbox“ Teil 1 / Teil 2 / Teil 3

Heute sprechen wir über ein System namens Native Client , das Google in der realen Welt verwendet. Es ist eine Sandbox-Technologie zum Ausführen von Code auf verschiedenen Plattformen. Es wird im Chrome-Browser verwendet , sodass Webanwendungen beliebigen Maschinencode ausführen können. Dies ist eigentlich ein ziemlich cooles System. Es zeigt auch Isolationsfunktionen und eine spezielle Sandbox- oder Berechtigungstrennungstechnik, die als Softwarefehlerisolation , Softwarefehlerisolation bezeichnet wird , ohne das Betriebssystem oder die virtuelle Maschine zum Erstellen der Sandbox zu verwenden.



Stattdessen verwendet der native Client einen völlig anderen Ansatz, um bestimmte Anweisungen in einer Binärdatei zu überprüfen und festzustellen, ob die Ausführung sicher ist oder nicht. Bevor wir uns mit den technischen Details des Systems befassen, wollen wir herausfinden, warum diese Leute wirklich Maschinencode ausführen möchten. Ihr besonderes Interesse gilt der Anwendung dieser Lösung in einem Webbrowser, in dem Sie bereits JavaScript- Code, Flash Player und einige andere Prozesse ausführen können. Warum sind diese Leute so begeistert von der Möglichkeit, Code auf der x86- Plattform auszuführen? Immerhin scheint dies ein Rückschritt zu sein.

Teilnehmerin: Sie möchten sehr schnelle Berechnungen erhalten.

Professor: Ja, das ist ein großer Vorteil des Maschinencodes. Auch wenn es auf lange Sicht unsicher sein kann, bietet es eine hohe Leistung. Alles, was Sie in JavaScript nicht tun würden, zum Beispiel ein Programm schreiben und kompilieren, wird wirklich viel schneller funktionieren. Gibt es noch andere Gründe?

Zielgruppe: Vorhandenen Code ausführen?

Professor: richtig. Es ist wichtig, dass nicht alles in JavaScript geschrieben werden kann. Wenn Sie also eine vorhandene Anwendung oder in der Branchenterminologie „geerbten“ Code haben, den Sie im Internet ausführen möchten, scheint dies eine großartige Lösung zu sein. Da Sie beispielsweise nur eine vorhandene Bibliothek verwenden können, eine komplexe grafische „Engine“, die sowohl auf die Leistung als auch auf viele andere komplexe Dinge reagiert, die Sie nicht erneut implementieren möchten, ist dies eine gute Lösung.
Wenn Sie nur eine neue Webanwendung programmieren, sollten Sie Ihren eigenen Client verwenden, wenn Sie nicht besonders über Vererbung oder Leistung besorgt sind?

Zielgruppe: Dann müssen Sie kein JavaScript verwenden .

Professor: Ja, das ist ein guter Grund. Wenn Sie JavaScript nicht mögen, müssen Sie es nicht verwenden, oder? Sie können beispielsweise C verwenden , Python- Code ausführen und in Haskell in einer Sprache schreiben, die Sie für geeigneter halten.

Dies ist also eine ziemlich überzeugende Liste von Motivationen für die Ausführung Ihres eigenen Codes in einem Browser, und es ist ziemlich schwierig, Rechte für eine solche Aktion zu erhalten. In nur einer Sekunde werden wir die technischen Details betrachten, und jetzt möchte ich Ihnen eine einfache Schulungsdemo zeigen, die ich von der Native Client- Website erhalten habe.



Dies ist recht einfach, da Sie C ++ oder ein C- Programm in einem Browser ausführen können. Sie können sich diese Webseite ansehen, bei der es sich um eine HTML- Datei handelt, die eine Menge JavaScript- Code enthält.



Der Grund für das Vorhandensein dieses JavaScript- Codes besteht darin, dass Sie mit Teilen des nativen Clients interagieren können. In Bezug auf den Betrieb des Browsers bedeutet eine solche Lösung, dass Sie eine Art Webseite haben, die JavaScript- Code enthält. Diese Lösung arbeitet mit den Berechtigungen der Seiten und ermöglicht es Ihnen, verschiedene Dinge auf der Webseite selbst zu tun, z. B. unter bestimmten Umständen mit dem Netzwerk zu kommunizieren.

Mit Native Client können Sie Ihr Modul im Browser ausführen, sodass JavaScript- Code mit ihm interagieren und eine Antwort erhalten kann. Dies zeigt einen Teil des JavaScript- Codes, den der native Client benötigt, um mit dem spezifischen NaCl- Modul zu interagieren, das wir ausführen möchten.



Und Sie können Nachrichten an dieses Modul senden. Wie wird das gemacht? Sie nehmen das Objekt dieses Moduls in JavaScript , nennen es postMessage und unterstützen somit das Senden dieser Nachricht an das NaCl- Modul. Wenn das NaCl- Modul antwortet, startet es die Nachrichtenfunktion in JavaScript . In diesem speziellen Fall wird im Browser nur ein Dialogfeld angezeigt.



Auf der JavaScript- Seite ist dies also eine ziemlich einfache Webseitenoberfläche. Das einzige, was Sie zusätzlich tun müssen, ist, das NaCl- Modul auf diese Weise zuzuweisen. Das heißt, Sie fügen hier einfach ein Modul mit einer bestimmten ID ein . Am interessantesten ist hier der Hallo- Code mit der Erweiterung nmf . Er sagt nur, dass es eine ausführbare Datei gibt, die Sie herunterladen und in einer NaCl- Umgebung damit arbeiten müssen.



Dieser native Code ist wirklich wie jeder andere C ++ - Code, den Sie schreiben können. Der interessante Teil ist diese HandleMessage- Nachrichtenverarbeitungsfunktion.



Dies ist eine C ++ - Klasse. Wenn JavaScript- Code eine Nachricht an Native Code sendet, wird diese Funktion ausgeführt. Es führt eine if (message = = 'hello') Prüfung durch. In diesem Fall wird eine Art Antwortzeile erstellt und zurückgesendet. Das ist ziemlich einfaches Zeug. Aber für Einzelheiten versuchen wir, es auszuführen und zu sehen, was passiert.

Wir können einen kleinen Webserver erstellen und ausführen, der diese Seite und das Native Client- Modul bedient. Hier kann ich zu dieser URL gehen und hier sehen wir die NaCl- Webseite. Das Modul erhielt unsere Begrüßungsnachricht von JavaScript , antwortete mit einer Zeichenfolge in JavaScript und der JavaScript- Code löste einen Popup-Dialog mit dieser Antwort aus.



Also funktioniert es wirklich.

Versuchen Sie herauszufinden, ob der native Client abstürzen kann. Ich hoffe nicht, aber wir können diesen Code und diesen Puffer nehmen und eine Menge Unsinn darin schreiben, zum Beispiel 65536, und sehen, was passiert.



Ich hoffe, dies sollte nicht zum Absturz meines Browsers führen, da der native Client versucht, eine Isolation bereitzustellen. Aber mal sehen, was passiert.

Starten Sie den Webserver neu. Wir sehen, dass der Zugang zum Modul noch erfolgreich ist, unser Browser wurde nicht verletzt. Das Messaging mit dem Client fand jedoch nicht statt, sodass das Dialogfeld fehlt. Schauen wir uns die JavaScript- Konsole unten auf der Seite an und sehen wir, dass das Native Client- Modul uns über den Ausfall des NaCl- Moduls informiert.



Es ist möglich, dass das von mir eingegebene Argument einen Pufferüberlauf oder den Zugriff auf eine falsche Adresse verursacht hat. In jedem Fall kann das NaCl- Modul jedoch eine versehentliche Speicherbeschädigung so isolieren, dass der Browser nicht beeinträchtigt wird.

Dies ist eine kurze Demonstration dieses Systems in der Form, in der Sie es als Endbenutzer oder Entwickler verwenden können. Schauen wir uns noch ein paar Beispiele an. Zum Beispiel, wie der native Client funktioniert oder warum wir genau dies und kein alternatives Design benötigen.

Wenn Sie also Ihren eigenen Code isolieren möchten, gibt es verschiedene Alternativen, mit denen Sie dies tun können. Tatsächlich hatten Benutzer Probleme mit der Verwendung von Legacy-Code und anderen Sprachen, bevor der native Client angezeigt wurde. Sie lösten sie auf verschiedene Weise, die möglicherweise nicht so sicher und bequem waren wie der native Client , aber dieselben Isolationsfunktionen bereitstellten.

Was sollten Sie also tun, wenn Sie wirklich Maschinencode in einem Browser ausführen möchten? Eine Option ist das Vertrauen in den Entwickler. Möglicherweise besteht eine Variante dieses Ansatzes darin, dass Sie den Benutzer fragen, ob er einen Code in seinem Browser ausführen möchte oder nicht.

Jeder versteht ungefähr, was für ein Plan das ist, oder? Anstelle all dieser Native Client- Kompilierungsstrategie könnte ich beispielsweise einfach ein C- Programm erstellen, es in einem Browser ausführen und er würde mich fragen, ob ich diese Site ausführen möchte oder nicht. Und wenn ich auf "Ja" klicke und versehentlich im Speicher des Browsers "mähe", stürzt es ab. Also ist es möglich, richtig? Dies löst natürlich all diese Probleme, aber was ist daran falsch?

Ich denke, das Schlimme ist, dass diese Lösung unsicher ist. Dies ist eine Möglichkeit, dieses System und viele andere Systeme zu umgehen.

Microsoft hatte ein System namens ActiveX , das diesen Plan im Grunde implementierte. Sie können die Binärdateien an IE , den Browser auf Ihrem Computer, senden. Bis sie mit einem Zertifikat eines bestimmten Entwicklers zurückkehren, das beispielsweise von Microsoft oder einer anderen Person signiert wurde, führt der Browser Ihren Code nicht aus. Halten Sie dies für einen nützlichen Plan?

Teilnehmerin: Dies ist Vertrauenssache!

Professor: Ja, das ist es. Sie müssen wirklich ein wenig darauf vertrauen, dass der Entwickler nur die „Binärdateien“ signiert, die nichts falsch machen. Aber es ist oft unmöglich herauszufinden, ob dies eine schlechte Sache ist oder nicht, also schreiben sie einfach C- Code und signieren ihn blind, ohne viel Arbeit zu erledigen. In diesem Fall können in Zukunft möglicherweise bestimmte Probleme auftreten.

Ebenso garantiert die Entscheidung, den Benutzer zu fragen, ob er wirklich etwas ausführen möchte, überhaupt keine Sicherheit. Auch wenn der Benutzer vorsichtig sein möchte, ist nicht klar, wie er sich entscheiden soll. Angenommen, ich möchte wirklich verstehen, ob ich dieses Programm funktionieren lassen kann? Mir wurde gesagt, dass alles in Ordnung ist, vielleicht wurde es von seriösen Entwicklern von Google.com oder Microsoft.com erstellt . Dies ist jedoch die ausführbare Datei foo.exe und ich weiß absolut nicht, was sich darin befindet. Selbst wenn ich seinen Code zerlege, wird es sehr schwierig sein zu sagen, ob er etwas Schlechtes tun wird oder nicht. Daher ist es für den Benutzer wirklich schwierig zu entscheiden, ob die Codeausführung für das System sicher ist.



Auf diese Weise kann der native Client als Mechanismus fungieren, mit dem Benutzer sicher sein können, ob sie zu einem Programm Ja oder Nein sagen sollen.

In der Praxis sollte meiner Meinung nach letzte Woche eine Option von unserem Gastdozenten Paul Yang vorgeschlagen werden. Er empfahl, das Plugin " Play Extension " oder "Play the Extension" im Chrome-Browser auszuführen . Das heißt, es stellt sich heraus, dass Sie vor dem Starten einer Erweiterung, einschließlich des nativen Clients , auf dieses Element klicken müssen. In gewisser Weise entspricht dies der Frage an den Benutzer. In diesem Fall ist das System jedoch auch dann sicher, wenn der Benutzer mit „Ja“ antwortet, da der native Client in die Arbeit einbezogen wird . In diesem Sinne haben wir einen doppelten Sicherheitsmechanismus: Fragen Sie zuerst den Benutzer und starten Sie dann mit einer positiven Antwort den Sandbox-Client, damit der Browser nicht abstürzt.

Ein weiterer Ansatz, der angewendet werden sollte, ist die Verwendung der Sandbox, die mithilfe des Betriebssystems oder der Hardware implementiert wird, oder die Isolierung von Prozessen. Dies haben wir in den letzten beiden Vorlesungen untersucht.

Vielleicht würden Sie Unix- Isolationsmechanismen verwenden. Wenn Sie etwas komplexeres hätten, würden Sie FreeBSD oder Capsicum verwenden . Es eignet sich hervorragend zum Isolieren eines Codeteils in der Sandbox, da Sie dessen Funktionen einschränken können. Linux hat einen ähnlichen Mechanismus namens Seccomp , den wir in der letzten Vorlesung kurz behandelt haben. Er ermöglicht es Ihnen auch, solche Dinge zu tun.

Daher gibt es bereits einen Mechanismus zum isolierten Schreiben von Code auf Ihrem Computer. Warum sind diese Leute gegen die Verwendung dieser bestehenden Lösung? Es scheint, als würden sie aus irgendeinem Grund „das Rad erfinden“. Also, was ist los?

Teilnehmerin: Vielleicht wollen sie Fehler minimieren?

Professor: Ja, in gewisser Weise vertrauen sie dem Betriebssystem nicht. Vielleicht sind sie tatsächlich besorgt über Betriebssystemfehler. Es ist wahrscheinlich, dass der FreeBSD- Kernel oder der Linux-Kernel ziemlich viel C- Code enthält, den sie nicht wollen oder nicht auf Richtigkeit prüfen können, selbst wenn sie wollten. In Capsicum oder Seccomp erfolgt die Arbeit auf der Grundlage des Isolationsplans. Es reicht also aus, dass der Kernel nur über einen kleinen, zuverlässigen Code verfügt, sodass die Sandbox die Isolation beibehält und anwendet.



Zielgruppe: Da Sie viel mehr Möglichkeiten zur Verwendung von Browsern haben, müssen Sie sich mit verschiedenen Betriebssystemen wie iOS und Android auseinandersetzen und auf ...

Professor: Ja, eine weitere interessante Überlegung ist, dass normalerweise viele Betriebssysteme Fehler aufweisen. Darüber hinaus sind verschiedene Betriebssysteme in gewisser Weise nicht miteinander kompatibel. Dies bedeutet, dass jedes Betriebssystem seinen eigenen Mechanismus hat, wie hier gezeigt: Unix hat Capsicum , Linux hat Seccomp , aber dies sind nur Variationen von Unix . Mac OS hat Sicherheitsgurt , Windows hat etwas anderes und die Liste geht weiter.

Letztendlich verfügt jede Plattform, mit der Sie arbeiten, über einen eigenen Isolationsmechanismus. Und was sie wirklich nicht allzu sehr stört, ist, dass sie unterschiedlichen Code für Mac , Windows und Linux schreiben müssen. Dies wirkt sich jedoch mehr darauf aus, wie Sie diese Dinge schreiben, damit sie in der Sandbox funktionieren. Denn im Native Client schreiben Sie tatsächlich einen Code, der genauso ausgeführt wird wie der "native" Betriebssystemcode, genauso wie Apple- Code, Windows- Code oder Linux -Systemcode ausgeführt werden.

Wenn Sie diese Isolationsmechanismen verwenden, unterliegen sie tatsächlich unterschiedlichen Einschränkungen für das in der Sandbox platzierte Programm. Sie müssen also ein Programm schreiben, das in der Linux- Sandbox ausgeführt wird, ein anderes Programm, das in der Windows- Sandbox ausgeführt wird, und so weiter.

Das ist für sie wirklich inakzeptabel. Sie wollen sich nicht mit solchen Problemen befassen. Welche anderen Überlegungen haben Sie?

Zielgruppe: vermutlich Systemleistung. Wenn Sie Capsicum verwenden , müssen Sie auf ausreichende Ressourcen achten, um sicherzustellen, dass die Prozesse in der Sandbox funktionieren. Hier können sie das gleiche Problem haben.

Professor: Ja, das stimmt. Der Isolationsplan für Software-Abstürze ist tatsächlich sehr ressourcenintensiv, was auf Betriebssystemebene zu einem Mangel an Ressourcen zur Unterstützung der Sandbox führen kann. Es stellt sich heraus, dass sie in ihrem eigenen nativen Client sowohl ihre Sandbox als auch ihre Betriebssystem-Sandbox verwenden, um zusätzliche Sicherheit zu bieten. Tatsächlich gewinnen sie also nicht an der Leistung ihrer Implementierung, obwohl sie dies wahrscheinlich könnten.

Teilnehmerin: Vielleicht wollen sie alles kontrollieren. Da sie steuern können, was im Browser passiert, aber wenn sie es an den Computer des Clients unter dem Betriebssystem senden, wissen sie nicht, was dort passieren könnte.

Professor: Man kann sagen, dass das Betriebssystem möglicherweise Fehler aufweist oder die Sandbox nicht gut genug verwaltet. Oder die Benutzeroberfläche ist etwas anders, sodass Sie nicht wissen, was das Betriebssystem preisgeben wird.

Zielgruppe: Dies verhindert nicht, dass der Code einige schlechte Dinge tut. Es gibt viele Dinge, die Code tut, zum Beispiel, wenn Sie eine statische Analyse durchführen möchten, aber Code-Schleifen verhindern, dass das Programm funktioniert.

Professor: Tatsächlich ist es sehr schwierig festzustellen, ob es einen Prozess mit Endlosschleifen gibt oder nicht, aber im Prinzip können Sie mit diesem Ansatz einige Codeprobleme erkennen. Ich denke, dass ein wirklich interessantes Beispiel, von dem ich bis zum Lesen ihres Artikels nichts wusste, zeigt, dass diese Leute sich Sorgen über Hardwarefehler machen und nicht nur über Betriebssystemschwachstellen, die vom Code ausgeführt werden können. Beispielsweise verfügt der Prozessor selbst über einige Anweisungen, die dazu führen können, dass der Computer einfriert oder neu gestartet wird. Grundsätzlich sollte Ihr Gerät keinen solchen Fehler aufweisen, da das Betriebssystem darauf angewiesen ist, dass die Hardware in jedem Fall dazu beiträgt, den Kernel zu erreichen, um die Folgen eines Benutzerfehlers zu beseitigen.

Aber es stellt sich heraus, dass die Prozessoren so komplex sind, dass sie Fehler haben, und diese Leute sagen, dass sie Beweise dafür gefunden haben. Wenn der Prozessor einige komplexe Anweisungen nicht erwartet hat, wird er gestoppt, anstatt den Systemkern zu verarbeiten. Das ist schlecht. Ich denke, das ist nicht katastrophal, wenn ich nur ein paar nützliche Dinge auf meinem Laptop laufen lasse, aber viel schlimmer, wenn der Computer beim Besuch einer Webseite einfriert.

Daher wollten sie ein höheres Schutzniveau für die Native Client- Module schaffen als dasjenige, das eine Isolation auf Betriebssystemebene bietet, auch ohne Hardwarefehler. In Bezug auf Sicherheit verhalten sie sich also wie paranoide, einschließlich des Hardware-Sicherheitsproblems.

Lassen Sie uns nun sehen, wie der native Client Prozesse in der Sandbox tatsächlich isoliert. Daher verfolgt der native Client einen anderen Ansatz, der als "Isolieren von Softwarefehlern" bezeichnet werden kann.



Es ist nicht geplant, sich darauf zu verlassen, dass das Betriebssystem oder die Ausrüstung die Dinge überprüft, während das Programm ausgeführt wird, sondern sich darauf zu verlassen, dass sie die Anweisungen im Voraus überprüfen und entscheiden, dass sie vollständig sicher ausgeführt werden können. Daher reicht es in der Tat aus, die Binärdatei zu überprüfen, um alle möglichen Anweisungen zu überprüfen und festzustellen, ob sie sicher oder unsicher sind. Sobald Sie entschieden haben, dass alles sicher ist, können Sie den Prozess einfach starten, da Sie wissen, dass er aus sicheren Dingen besteht und keine Fehler auftreten.

Sie sehen sich also fast alle Anweisungen im Binärcode an, der an den Browser gesendet wird, und entscheiden, ob bestimmte Anweisungen sicher sind oder nicht.

? . ? , , .

- 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

:

MIT-Kurs "Computer Systems Security". 7: « Native Client», 2


.

, . Gefällt dir unser Artikel? Möchten Sie weitere interessante Materialien sehen? Unterstützen Sie uns, indem Sie eine Bestellung aufgeben oder sie Ihren Freunden empfehlen. Habr-Benutzer erhalten 30% Rabatt auf ein einzigartiges Analogon von Einstiegsservern, das wir für Sie erfunden haben: Die ganze Wahrheit über VPS (KVM) E5-2650 v4 (6 Kerne) 10 GB DDR4 240 GB SSD 1 Gbit / s $ 20 oder wie teilt man den Server? (Optionen sind mit RAID1 und RAID10, bis zu 24 Kernen und bis zu 40 GB DDR4 verfügbar).

3 Monate kostenlos bei Bezahlung eines neuen Dell R630 für einen Zeitraum von sechs Monaten - 2 x Intel Deca-Core Xeon E5-2630 v4 / 128 GB DDR4 / 4 x 1 TB Festplatte oder 2 x 240 GB SSD / 1 Gbit / s 10 TB - ab 99,33 USD pro Monat , nur bis Ende August, Bestellung kann hier sein .

Dell R730xd 2 mal günstiger? Nur wir haben 2 x Intel Dodeca-Core Xeon E5-2650v4 128 GB DDR4 6 x 480 GB SSD 1 Gbit / s 100 TV von 249 US-Dollar in den Niederlanden und den USA! Lesen Sie mehr über den Aufbau eines Infrastrukturgebäudes. Klasse mit Dell R730xd E5-2650 v4 Servern für 9.000 Euro für einen Cent?

Source: https://habr.com/ru/post/de418223/


All Articles