 Herzlich willkommen zu diesem Talk. Willkommen alle auf dem Stream, alle die zuhören. Es großartig euch hier in dieser großen Halle zu sehen. Und unser nächster Gast ist Fefe, das ist ein Security Consultant. Ja, ein Security Consultant. Er ist auch einer der Gründer von der Firma Die Blau heißt, die machen Sicherheitskonzepte. Und Fefe gehört zum CCC, zum Inventar, fast so wie die Downtime des Wikis. Und für die, die nicht aus Deutschland sind, Fefe hat ein kleines Block in Deutschland. Ein kleines und hübsches, also ein wirklich wirklich kleines, also es lesen kaum Leute. Können wir vielleicht das Thema wechseln? Ich möchte gern sagen, dieses Block ist die einzige Webseite, die kommt, wenn, wenn ihr in die Berliner U-Bahn geht. Also die schnellste Webseite aller Webseiten. Und Fefe redet heute über Programme, die sich selbst zentboxen und warum das eine gute Idee ist. Und in diesem Talk checkt mal eure Privilegien. Ja, bitte begrüßt mit mir Fefe. Guten Morgen, schön, dass ihr da seid. Also bei diesem Talk hier geht es darum, wie ihr eure eigenen Programme so schreiben könnt, dass selbst wenn sie exploitet werden, weil ihr ein Buck eingebaut habt, dass das der Schaden niedrig ist. Und die Idee ist ziemlich alt. Also sie ist wahrscheinlich älter als wo ich angefangen habe, also wo ich darüber geblockt habe in 2007. Das ist der älteste Eintrag, den ich gefunden habe. Und ich habe also eine ganze Weile da drauf, da drüber Dinge dazu gemacht und habe zumindest darüber nachgedacht. Und jetzt gibt es dann langsam die Teile dafür, die man braucht. Und jetzt kann ich euch zeigen, wie das funktioniert. Also bevor wir anfangen, ich möchte eins klarstellen, das macht man nicht anstatt, dass man seinen Code fehlerfrei macht, sondern man macht seinen Code erst gut und dann ist es so eine Art Versicherung. Es kann euch retten, aber es gibt halt keine Bezahlung, wenn ihr nachlässig seid. Also der Plan ist, dass ich euch zeige, welches Problem ich lösen will. Ihr denkt, wenn ihr Software planen wollt, dann sieht es so aus und wenn ihr es dann wirklich schreibt, dann sieht es halt so aus. Und wir hängen ab von Code, der viele, viele Bucks enthält in unseren täglichen Leben und viele von diesen Bucks sind sicherheitsrelevant. Und wenn jemand was angreift, dann hat es normalerweise was mehr Rechte hat, als der Angreifer hat. Und wenn der Angriff erfolgreich ist, dann hat der Attacker Privilegien gewonnen in dem System. Also wie können wir das Problem lösen? Und die offensichtliche Idee ist, naja, stellt halt einfach sicher, dass dein Code keine Bucks enthält. Ja, stellt sich raus, das ist nicht ganz so einfach. Und die zweite offensichtliche Möglichkeit ist, die sicherzustellen, dass der Code nur von wenigen Stellen aus erreichbar ist, zum Beispiel nur aus dem Internet. Also das ist zum Beispiel nur nach HTTPS, über HTTPS, nachdem man sich authentifiziert hat, erreichbar ist. Und das macht es vielleicht nicht leichter, für zum Beispiel deinen E-Mail-Provider, weil jeder Sachen seinen Account besorgen kann. Oder es ist ein interner Microservice, den man halt von dem Internet gar nicht sehen kann, oder es ist hinter sieben Proxies. Oder Leute können sich ziemlich absturl, struse Szenarien ausdenken. Ja, man könnte den Code auch auf die Sonde Voyager 1 legen. Man möchte die Wahrscheinlichkeit minimieren, dass das was gehackt wird. Aber selbst wenn man das macht, dann kann man trotzdem exploitet werden. Und wie können wir das schwerer machen, dass jemand den Code exploitet? Und darauf ist jetzt die meiste Forschung gerichtet aktuell. Also man kann nicht ausführbaren Stack haben, das ein ziemlich praktisches Feature ist. Man kann Cookies auf dem Stack haben, man kann den Heap haden. Es gibt ASLR, positionsunabhängige ausführbare Dateien, Rope-Schutz. Man kann gefährliche Arpies verbieten, man kann die Developer besser ausbilden, die Entwickler besser ausbilden. Oder ein Bug Bounty-Programm, wenn man also Geld rumliegen hat, das ist dann auch eine gute Idee. Oder man kann den Code auf eine Architektur ausführen, wo man hoffen kann, dass niemand weiß, wie man das exploitet. Aber am Ende ist die Reduzierung nur das Risiko, man kann immer noch nicht gut schlafen. Und die Idee über dich heute rede, da geht es darum, vielleicht kann ich den Code in meine Zwangsjacke packen und die Privilegien abwerfen. Das heißt, selbst wenn jemand den Code ausnutzt, dann ist die Rechte, die er dadurch bekommt, das minimal. Also umso weniger du selbst machen kannst, kann auch der Angreifer an Rechten gewinnen. Und jetzt gibt es einen großen Unterschied zwischen, was der Code tun kann und was der Code eigentlich macht. Und ich werde jetzt drüber reden, was der Code machen kann. Also es geht nicht darum, dass ich sage, na ich schreibe nirgendwo Dateien, also sollte ich sicher sein, nein, wenn jemand Code ausführen kann in deinem Prozess und dann kann er irgendwo hinschreiben, dann ist das ein Problem. Und es geht also nicht darum, was euer Programm versucht zu machen, sondern was es eben machen könnte mit den Privilegien, die es aktuell auf dem System hat. Also ein Angreifer ist nicht eingeschränkt dadurch, was euer Code versucht zu tun. Das ist ganz wichtig, dass man das versteht. Also wenn man sowas ausführt wie Ping, dann ist ein SUID-Root-Programm auf Linux oder einen HTTP-Demon oder irgendein Systemdienst, das läuft normalerweise als Super-User, zumindest traditionell. Und der Super-User hat Zugriff auf alles in dem System und das ist wirklich, wirklich schlecht. Und die erste Idee ist das ein bisschen zu reduzieren, dass das ein Symbolbild für was der Super-User machen kann. Also wir reduzieren die Privilegien, ich laufe als normaler Nutzer und habe ich aber immer noch eine ganze Menge Privilegien, aber es ist besser. Und bei diesem Talk hier geht es jetzt darum, vielleicht können wir sogar mehr Privilegien noch abgeben. Der Service kann also wirklich nur sehr, sehr kleine Dinge im System, das ist die Idee. Und übliche Muster, um das zu erreichen, naja, die Applikation wirft Privilegien ab. Man macht das gefährliche Zeug ganz am Anfang und gibt dann die Privilegien ab und man hofft, dass der Bug in dem Code ist, nachdem ich die Privilegien abgeben. Und das mag eine gute Annahme sein, aber vielleicht auch nicht, denn das ist also gefährlich. Also es ist aber ein gewöhnlicher Weg, das zu machen. Also ich werde gleich detailliert darüber reden, was man Privilegien-Trennung nennt. Also ich nenne einen gefährlichen, nehm einen gefährlichen Peil und packe den in einen anderen Prozess. Und was man sonst häufigweise macht ist, man kann der Applikation nicht vertrauen, weil sie zum Beispiel sehr groß ist und dann tue ich sie in eine virtuelle Maschine oder in den Jail und hoffe, dass diese Mechanismen reichen, dass quasi wenn es schief geht, was dann alles passieren kann. Aber möglicherweise kann sich die App auch selbst einschränken. Und das ist eine neue Idee, glaube ich. Also wurde zumindest erst in den letzten Jahren benommen, angefangen zu machen. Und dann gibt es die Möglichkeit zum Broker-Service zu benutzen. Also man teilt einen Prozess auf. Die linke Hälfte des Prozesses kann keine Dateien öffnen, aber es kann zur rechten Hälfe, mit der rechten Hälfe reden und die darf Dateien reden. Und die linke Seite fragt dann quasi die rechte Seite. Und das ist ein ganz kleines Stück Code. Das heißt, wir können sicherer sein, dass das auf eine sichere Art und Weise passiert. Und es ist wichtig, dass, wenn man Privilegien ablegt, dass die endgültig weg sind. Das heißt, dass ich quasi nur runtergehen kann, aber eben nicht die Privilegien mir wieder zurückholen. Und das klingt ganz einfach, aber in der Praxis ist es schwieriger, als man denkt. Und klassischerweise geht es eben nur darum, naja, ich möchte nur privilegierte Prozesse irgendwie einschränken. Also wenn man sagt, es läuft und dann einen normalen Nutzer, naja, dann ist es schon irgendwie sicher. Aber daher kommt eben die, aus diesem Bereich kommt die Idee ursprünglich. Wenn man Programme als Route startet, Beispiele sind zum Beispiel Pings, dann das braucht rohe Socket und dafür muss es Super-User sein. Früher war auch der X-Server als Route ausgeführt. Früher zumindest. Mittlerweile gibt es andere Wege, denn das braucht Zugriff auf die Grafik-Hardware. Und ein Beispiel ist auch X-Term, denn das möchte einen TTIY, also einen Pseudoterminal erstellen. Und das sollen nur Super-User dürfen. Und die Idee ist, wir geben den Programmen erst Privilegien und dann werfen wir die Privilegien weg. Und die Hoffnung ist, der Attacker kann eben nur den zweiten Teil ausnutzen. Privileg, die Trennung von Privilegien ist eine ganz alte Idee, bereits im SSR-Bereich. Die SSR-Community hat quasi angefangen, diese Ideen zu machen, die haben das Konzept soweit ich weiß erfunden. Die Idee ist, dass du deinen Prozess auftrennst, also gehen wir davon aus, du hast diesen ganz komplexen Krypto-Code und das Paarsen der ganzen Low-Level-Krypto, die SSR macht und du denkst, du machst es richtig oder bist nicht ganz sicher, also packst du das in einen eigenen Prozess und diesen Prozess, den gibst du nur einen ganz kleinen leeren Teil des Arteisystems, gibst du da Zugang und dann gibst du, dass der nichts tun kann, außer das Protokoll zu paarsen. Das heißt, wenn der also irgendwann hier, irgendwas hier explodiert, dann explodiert nur dieser kleine Teil und nicht das große Ding, das große Ding macht dann Diagnostik und stellt dann nur fest, oh, irgendwas hat mich wohl gehackt. Die andere Idee ist die, dass der Administrator eine App einsperrt in einem Art Gefängnis oder Container oder virtueller Maschine. Im Prinzip funktioniert das so, dass man das komplette System da angeht, man kann das Feinkranularer machen, aber normalerweise sind einfach das ganze Ding, pockt es in eine Art eingeschränkte Umgebung und das tut der Administrator nicht die Anwendung selbst. Das Problem ist, wenn du so einen Regelsatz hast, gibt es verschiedene Arten, weil sie mir das machen kann, aber läuft immer so, wenn du so einen Regelsatz hast, was die Programm kann das und das machen und sonst nichts, wo gibt es diesen Satz, wo holst du diesen Satz regel her? Das ist erschreckend schwierig, wenn das kein einfaches Programm ist, diesen Regelsatz zu bekommen. Für einfache Programme kann man das machen und das ist hinreichend einfacher, hinreichend okay, aber das sind nicht die Programme, um die wir uns Sorgen machen, richtig? Wir sorgen uns komplicierte Programme wie Firefox. Außerdem kann man nicht davon ausgehen, dass der Admin diese Regeln sich ausdenkt oder die irgendwie ermittelt. Es ist nicht der Job des Admins herauszukriegen, was die Anwendung unter welchen Bedingungen möglicherweise in irgendeinem Fehlercode machst. Du weißt überhaupt nicht als Admin, ob du alle Funktionalität des Programms überhaupt verwendet hast. Bist du sicher, dass du jeden Knopf in Firefox überhaupt mal ausprobiert hast? Und du musst sicher sein, dass das der Fall ist, um zu gucken, dass dein Profil vollständig ist. Das heißt, was man üblicherweise hat in diesem Szenario ist, es gibt irgendeinen obscuren Fehlerfall und das Programm konnte den nicht ordentlich abfangen, wie zum Beispiel nicht genug Speicher oder was in der Art. Und auf einmal fällt sich das Programm anders und das ist eine Verletzung des Profils, was du gesetzt hast und das Programm explodiert. Deswegen ist die Sache mit den Profilen schwierig und ich glaube, das ist nicht der richtige Ansatz. Du kannst das zusammen machen, damit ist das Programm sich selbst Sandbox. Das sind unabhängige Ideen. Aber ich denke nicht, es sollte das Einzige sein, was wir machen, um Programme einzuschränken. Die andere Idee ist, vielleicht sollte nicht der Admin das machen, aber der Typ in der Distribution, also zum Beispiel der Debian-Paketverwalter macht das, aber ich glaube auch nicht, dass das eine gute Idee ist. Du kannst auch von denen nicht erwarten, dass die das machen. Das sind im Wesentlichen Studenten, die das in ihrer Freizeit machen. Woher sollen die das Jahr haben, um Firefox sich vorstellig anzuschauen und dieses Profil zu bauen? Die zentrale Idee meines Vortrags ist also, dass die Anwendung sich selber einschränkt. Also denk im Wesentlichen über Nacht, das ist der Wehrwolf, der sich selber ankettet, bevor der Vollmond kommt. Nach dem Motto, selbst wenn irgendwas passiert, ist das Problem immer noch eingeschränkt. Das heißt, was du tust, ist, du hast einen kleinen Teil vom Dateisystem, nur da Kram drin ist ne wirklich Brauch, so nur dort kannst du drauf zugreifen. Da gibt es verschiedene Art und Weise, wie man das machen kann. Wir werden darüber reden. Du kannst nicht Dateien zugreifen, die außerhalb dieses kleinen Teils liegen oder vielleicht kannst du gar keine Dateien aufmachen. Du brauchst nicht so oft Dateien aufmachen, wie du brauchst. Aber manchmal muss man Dateien aufmachen, zum Beispiel fürs DNS-Lookup. Und dann stellt man fest, der Teufel schreckt üblich im Detail. Es ist einfacher, darüber zu reden, als es wirklich zu machen. Was anderes, was oft übersehen wird, ist, selbst wenn du das Dateisystem nicht zugreifen kannst, gibt es vieles, was du machen kannst. Der System 5 Inter Process Communication, zum Beispiel ist ein eigener Namespace. Du kannst Shared-Speich, geteilten Speicher mit anderen Prozessen machen, andere Art von Inter Process Communication. Du kannst Signalesentenprozesse töten. Du kannst P-Trace benutzen, eine Debug-API von Unix, um dich als Debug an einen anderen Prozess anzuschließen und dann außerhalb deiner Umgebung auf Dinge zuzugreifen. Es reicht nicht einfach nur, das Dateisystem einzuschränken, da muss man Moa mehr machen. Die Hauptsache, die man also hier mitnehmen sollte, ist, du musst vermutlich deine Anwendung umstrukturieren, der Art und Weise, wie sie läuft. Du schränkst ein, was die Hauptanwendung tun kann, damit du Teil kleiner Sachen machen kannst, über den du wirklich sicher sein musst, was er tut. Und dieser Broker-Service ist dann komplett getrennt von dem Hauptprogramm, der macht Entscheidungen wie, ich möchte diese allen Datei zum Lesen aufmachen, da fragt das Programm den Broker-Service oder diese Datei fürs Schreiben aufmachen. Und das Broker-Service macht zusätzlich Gechecks über das, was das Betriebssystem eh schon macht. Damit das wirklich die Sache wert ist, muss man sicher gehen, dass der Hauptprozess wirklich keine Rechte hat, selber auf das Datei-System zuzugreifen. Da gibt es verschiedene Arten und Weisen, das zu machen, über die ich reden werde. Alles der Probleme ist, manchmal gibt es Wege für das Hauptprogramm, um den Broker, den Verhandler, auszutricksten. Also wenn man zum Beispiel einfach nur einen getrennten Prozess macht, der als derselbe User läuft, dann kann man da sich als Debugger dran anschließen. Wenn das Hauptprogramm dann also gehackt wird, könnte es P-Trace benutzen, um den Code-Execution, um die Code-Ausführung im Broker zu überschreiben und dafür zu sagen, dass er macht, was er will. Das heißt, das ist alles wieder schwieriger, als man vielleicht oberflächig denkt. Also lass uns in die Details gehen. Erstens, der Oldschool-Weg, der alte Weg, so zum Beispiel das, was Ping machen sollte, so was man in den 90ern gemacht hat. Also was du grundlegend hier hast, ist, du hast zwei Benutzer-IDs im Prozess in der Datenstruktur, die das Betriebssystem für den Prozess hat. Da gibt es zwei. Benutzer-IDs, die wirkliche und die effektive Nutzer-ID. Wenn das Programm als Set-UID ausgeführt wird, dann ist die effektive User-ID, die, die das Programm sagt, was das Programm Set-UID zu ist. Also wenn das Programm irgendwas macht, dann guckt es sich nicht die echte UID an, sondern die effektive UID. Also wenn du immer aufstattest, du hast das verstanden, du wirst eine Privilegien wegwerfen. Du könntest dann einfach, um zurückzugehen auf deine alten Nutzer-Rechte, könntest du Set-Effektive-UID von Get-UID machen. Und du solltest denken, das reicht, richtig? Stellt sich raus, nein, das ist nicht genug. Denn es gibt noch eine dritte UID, die einem erlaubt, wieder zurückzugehen, sogar nachdem jemand die Privilegien weggeworfen hat. Dass jede Version von Unix und BSD hat, die haben an diesem Punkt alle leicht unterschiedliches Verhalten. Es war zeitlang also sehr schwierig, Code zu schraben, wenn ich das wirklich richtig gemacht habe. Dann ist irgendwann eine neue API erfunden worden, die heißt ZResueID, wo man alle drei User-IDs mit setzen kann. Und das ist okay, das ist ein guter Weg, Privilegien zu setzen. Aber das ist nicht genug, das einfach aufzurufen, man muss den Rückabewert prüfen. Wenn du das nicht machst, dann können Sachen wirklich schiefgehen. Es könnte auch sein, dass es nicht ausreicht, die User-ID zurückzusetzen. Es gibt auch noch Gruppen-IDs, die Privilegien haben, also der Teufel steckt immer im Detail. Also was könnte z.B. passieren, wenn ich der Super-Jutzer bin und ich setze ZResueID auf irgendeinen User, wie könnte das schiefgehen? Naja, also z.B. gibt das System weiter Ressourcen-Limits für die Nutzer-IDs, da kann es z.B. Limit geben, dass so ein User-ID nur 10 Prozesse haben kann. Und wenn diese User-ID schon 10 Prozesse hat und der Super-User will Privilegien auf diese Prozesse, auf diese ID herunter machen, dann wird das schiefgehen. Und wenn du den Rückgabewert nicht prüfst, dann hast du im Wesentlichen quasi keine Privilegien weggeworfen. Also wenn du irgendwas hier vor machst, dann sei vorsichtig und sei sicher, dass du alle Nebeneffekte beachtest und Dinge auf der achten musst. Es war sogar früher noch schlimmer. Es gab noch einen anderen App hier auf, wo wir uns RE-UID, der so aussah, als würde er das wirklich machen, aber er tut es nicht. Und du findest immer noch in vielen Programmen heute Code, aus Rückwärts-Complety-Plats gründen, der diesen, wenn Z-Res-UID nicht da ist, Z-Re-ID-Aufruf, dieser Code ist eigentlich immer schlecht. Also wenn du mein Rad, wenn du auf dem System bist, das Z-Res-UID nicht hat, dann baut das Programm nicht. Du brauchst es. Es gibt keinen Weg drum herum. Also ein Beispiel hier ist von einem Apple Security-Hinweis, Apple Security-Hinweis, von der Weile. Im Wesentlichen sagt er, das Problem war, dass der Z-Re-GID es nicht geschafft hat, Privilegien wegzuwerfen. Und ja, das ist das, was dieser Aufruf machen soll. Also seid sehr vorsichtig damit. Tastet, ob es auch wirklich funktioniert, prüft alle Rückgabewerte. Tja, also haben wir jetzt wirklich die Privilegien abgegeben. Sagen wir mal, wir sind Ping und wir haben uns einen rohen Socket besorgt und wollen jetzt gucken, also haben jetzt die Privilegien weggeworfen und jemand greift uns erfolgreich an. Und jetzt ist halt die Sache, na gut, wir sind jetzt vielleicht nicht mehr ruht, aber was ist, wenn der Angreifer tatsächlich nur den rohen Socket haben wollte? Na ja, den hat er jetzt. Das heißt, Privilegien abgeben, das ist mehr. Und das Konzept, okay, wir machen jetzt erst mal das gefährliche Zeug, das kann auch schwieriger sein, als es aussieht. Also was ist zum Beispiel, wenn wir Command Line Arguments, also Kommando-Zahlen-Argumente, pasen? Das kann auch voller Fehler sein. Und dann sagen die Leute, na gut, wir müssen das zuerst machen und dann machen wir das Hardware-Zeug und dann werfen wir die Privilegien weg. Also das ist, also Kommando-Zahlen-Argumente-Pasen ist auch gefährlich. Und was ist, wenn der Angreifer-Umgebungsvariablen benutzt? Und was ist, wenn der Fehler in dem dynamischen Linker ist? Also das ist sogar noch bevor dein Main-Programm aus, also deine Main-Funktion ausgeführt wird. Also Privilegien abzugeben ist ein schwieriges Konzept, als das zunächst aussieht. Und wie gesagt, wenn ich nur den rohen Socket haben wollte, dann kann ich nicht viel machen, das muss Pinga am Ende können. Also reden wir zuerst über Privilegien-Trennung. Also sagen wir mal, ich habe einen Dienst und möchte hochgeladene Bilder konvertieren, um zum Beispiel ein Vorschau-Bild, also, oder ich will sicherstellen, ich entferne Metadaten aus einem JPEG, also die Exif-Daten zum Beispiel, sowas in der Art. Und wie ich das normalerweise mache ist, ich muss alle Bilderformate unterstützen und niemandem Welt machen. Und deswegen lade ich mir eine Bibliothek runter. Und das sind riesige Programme, die auch in der Vergangenheit viele Sicherheitsprobleme hatten. Und das gibt eigentlich keinen Grund, den jetzt zu vertrauen. Und das könnte also ein guter Grund sein, Privilegien-Trennung zu machen. Man schiebt das Ganze in einen anderen Prozess, der keine Privilegien hat und der muss auch nicht auf das Datei-System zugreifen, weil der kriegt das Bild über eine Pipe oder einen Socket und gibt das Ergebnis über einen anderen Pipe oder Socket zurück. Das könnte man also einschränken. Und es gibt eine Unterschied zwischen, ob man die Bibliotheken direkt benutzt oder noch einen Rapper benutzt, also das ist sogar noch populärer, sowas wie Image-Magic, egal wie man es macht. Das ist ein großes, große Menge an Code, dem man auf keinen Fall vertrauen sollte. Und wenn man das macht, dann wäre das ein guter Zeitpunkt, um er nachzudenken, Privilegien-Trennung zu benutzen. Und die Idee ist also, diese Bildbearbeitung schieben wir in einen anderen Prozess und geschränken den ein. Und was meinen wir mit Einschränken? Also, wir wollen die offensichtlichen Sachen, Dateisystemzugriff, System5-IPC, andere Prozesse, IPC, also sicherstellen, dass es keine neuen Kanäle für Interprozess-Kommunikationen geben kann, die man im Gab, als es erstellt wurde, das kann er natürlich weiterhin benutzen. Wenn möchte ich sicherstellen, dass der Angreifer keine Shell bekommt oder keinen Network-Socket erstellen kann. Also, das kann auch schlimm sein, wenn der keinen Zugriff hat auf BNSH. Vielleicht gibt es ein Routing-Problem. Also, es soll also nur ein Microservice sein, der also nicht sichtbar ist von dem einen Rechner in der DMZ, aber es hat eine Default-Route, die da nicht sein müsste. Also, das könnten wir auch einschränken. Und das gibt also viele, viele Ideen, was ihr versuchen könntet, einzuschränken. Und übliche Ansätze sind Namespaces oder ein Gefängnis und ein Wächter. Und die Namespace-Idea, da bastel ich mir quasi ein gefälschtes Dateisystem, das aussieht wie ein echtes Dateisystem, aber es hat nur die Teile drin, die der Prozess tatsächlich auch braucht. Und das ist das, dieses gefälschtes Dateisystem ist das Einzige, dass der Prozess tatsächlich sieht. Das ist einer der Möglichkeiten, wie man das machen kann. Das macht man normalerweise so was wie ETC-Hosts oder ETC-Resolve.conf, die kann man benutzen, also, wenn der Prozess, den man versucht, einzuschränken, DNS-Lookups macht. Also, das sind Dateien, die man dann braucht, auch in dem gefälschtes Dateisystem. Und wenn das gefälschtes Dateisystem auf var.jl.1 liegt, dann gibt es also eine Datei var.jl.1.etc-Hosts. Und das Namespace-Konzept kann man auch für UIDs, also für BenutzerIDs und ProzessIDs benutzen. Und der Unterschied wäre, wenn man einen ArtContainer hat und in dem Container gibt es einen init, was der PID1, also der init hat der dann ProzessID 1 oder nicht. Also, wenn ihr einen in einer Jail habt, könnt ihr mehrfach PID1 haben. Und das ist halt eine Detailfrage, die euch vielleicht nicht interessieren. Vielleicht braucht ihr gar keinen init in eurer Jail. Aber wenn ihr ein Namespace habt und jeder Container hat seinen eigenen ProzessID Namespace, dann gibt es also keine Gefahr, dass es irgendwie eine Interaktion gibt, zum Beispiel, wenn man Kill oder Signale, P-Trace, alles, was irgendwie davon abhängt, dass eine ProzessID benutzt wird. Das kann also niemals außerhalb dieser Jail gehen. Und der andere Ansatz ist, eine Art Gefängnis zu haben. Bei FreeBSD gibt es einen Namen, der heißt Jail. Das ist so was Ähnliches wie Unix-Berechtigungen werden da überprüft. Das wird genauso gemacht bei Windows. Das ist ein altes Konzept. Also, wenn man einen Falldeskript bekommt, dann kann man da nochmal öffnen da drauf, obwohl man später eigentlich gar keinen Open mehr machen kann. Also, die Zugriffszeiten, die Checks werden quasi gemacht, wenn man die Datei öffnet und nicht, wenn man schreibt oder liest das Einzige, was Lesen und Schreiben macht, dass die Lesen und Schreibberechtigungen abprüfen. Das heißt, man verhindert das Öffnen und man hat so eine Art Wächter. Und wenn der Code irgendwas öffnen möchte, dann muss es zu dem Wächter sprechen oder auch wieder so eine Art Broker-Service. Na gut, der kann dann sagen, Naja, ETC Host ist okay, um da zu lesen, aber ETC Host zu schreiben, nee, das ist nicht in Ordnung. Und das ist die andere Art und Weise, das zu machen. Und das kann man ganz analog machen für Sockets, solange es am Ende irgendwie um einen Dateideskript da gibt, dann kann man das eben so weitergeben, wie man das mit Unix-Datei-Deskriptoren macht. Okay, und bei Deskriptor weitergeben, da ist das Konzept recht einfach, aber wie man es wirklich macht, das ist relativ schwierig, und ich würde euch empfehlen, das nicht selber zu machen, findet Code, der das macht. Ihr könnt Main benutzen, den gibt es in dieser Bibliothek, das ist ziemlich fies. Das ist also wie so eine Wüste aus... Also ich meine, es kann passieren, ihr lauft auf irgendein Betriebssystem, von dem habt ihr noch nie gehört. Das ist ziemlich böse. Es sind also am Ende nur drei Zeilen Code, aber es sind für fast jedes Unix, was es gibt, sind es drei verschiedene Zeilen. Und wenn man das jetzt abstrahiert, dann sollte das in Ordnung sein. Also wie schränken wir den Zug auf das Heißsystem ein? Die alte Lösung dazu heißt the Change Route, also die Wurzel des Heißsystems zu wechseln. Was man da macht ist, man erzeugt ein neues Leeresverzeichnis, das Route gehört, das nur lesend ist, das nennt man Vagile, oder wie man es nennen soll. In dem Dienst sagt man dann Change Stil zu diesem Verzeichnis, da macht man alle offenen Details zu, dann sagt man Change Route auf dasselbe Verzeichnis, und dann gibt man seine Privilegien ab. Weil wenn du die Privilegien zuerst abgibst, dann kann man Change Route nicht machen. Change Route braucht Super-User-Privilegien. Das ist also das, was man tun muss, bevor man seine Privilegien abgibt. Gehen wir also mal davon aus, wir machen das, und der Prozess wird dann FU aufmachen. Dieses FU wird dann relativ zum aktuellen Verzeichnis sein. Das ist offensichtlich, aber selbst wenn man versucht aufzumachen, jetzt Punkt, Punkt, Slash, FU, das Punkt, Punkt wird nicht klappen, weil das gehört zu den Dingen, die Change Route sicherstellt, dass es nicht klappt. Auch wenn es nen symbolischer Link ist, der Punkt, Punkt enthält, auch das wird nicht funktionieren. Man kommt also nicht aus diesen Teilsystems raus. Es sei der, man hat nen offenen Descriptor, der raus zeigt, der außerhalb dieses Unterteilsystems zeigt. Das klingt doch alles mal ganz schön. Wir haben Regenbögen und Einhörner. Nein, leider nicht. Man kann rauskommen aus so nem Change Route-Gefängnis, wenn man selber Route ist. Weil zum Beispiel Change Route nestet, wird Arbeit nicht verschachtelt unter den Niedungs. Wenn man also ein neues Change Route macht, wäre man noch ein Teil Descriptor auf das alte Change Route hat. Dann ist man raus. Hier ist der Code, der das macht, damit ihr es auch mal gesehen habt. Wenn also dein Prozess innerhalb des Change Route Umgebungen, wenn der irgendwie ein Detail Descriptor geben kann, auf ein Detail Descriptor, der außerhalb vom Change Route ist, dann kann er da rausgehen. Entweder mit Change Stil oder mit fChange Stil. fChange Stil ist die Alternative. Change Route selbst wechselt nicht das Verzeichnis. Man muss beides machen. Wenn man nicht beides macht, dann ist es nicht effektiv. Und man muss die Rückgabewerte prüfen. Wiedermal. Sogar wenn man in einem Change Route Gefängnis ist, alles, was das macht, ist der Teilsystem Zugriff prüfen. Sockets, Signale und so weiter funktioniert immer noch alles. Ist also nicht wirklich eine gute Lösung, nur für der Teilsystem Zugriff nicht vollständig. Man muss mehr machen. Mehr Probleme mit Change Route sind das Funktionen in Bibliotheken, manchmal auf der Teilsystem zugreifen, ohne die das mitzuteilen. Das bekannteste Beispiel hier ist der DNS-Zugriff Get Host by Name. Abhängig vom Betriebssystem kann es sein, dass der Hunderte von Dateien aufmachen will. Resolve.conf, Resolve.conf, NS.irgendwas. Man muss dann wirklich schocken, was gucken, was die eigenen Lipsi, die man verwendet, da macht. Und man muss sich erstellen, dass all diese Dateien in dem Change Route Gefängnis zur Verfügung stehen. Besonders problematisch sind hier, wenn das Programm, dass man einschränken will, nicht in der kompalierten Sprache ist, sondern z.B. in Perl. Perl wird dann versuchen, andere Module zum Beispiel aufzumachen. Wenn das Programm anfängt mit Use irgendwas, irgendein Perl-Modul, dann wird Perl versuchen, dieses Perl oder Python, werden versucht, dieses Modul zu laden. Skriptsprachen sind ziemlich schwierig hier. Man muss diesen ganzen Perlcode komplett im Gefängnis haben in der Change Route Umgebung, damit Perl den auch finden und laden kann. Und in diesem Moment riskiert man dann, dass irgendjemand in diesem Jail die Dateien verändern kann. Das heißt, man muss auf die Berechtigungen für die Dateien sehr vorsichtig darauf achten. Noch schlimmer, der übliche Weg, diese Dateien in so ein Gefängnis reinzumachen, ist ein Hard Link. Wenn ich also ein Hard Link mache und jemand ändert die Datei in dem Change Route Jail, dann ändert das die Datei auch außerhalb des Change Route Gefängnisses. Also, jetzt, wenn sie aus dem Gefängnis nicht rauskommen, können sie immer noch dein System komprimitieren. Also, man muss wirklich vorsichtig mit so Sachen sein. Lassen Sie uns anschauen, was für Lösungen verschiedene Betriebssysteme hier haben. Eine der ersten Ideen, die ich persönlich sehr gut finde, ist das BSD-Secure Level Sicherheitsstufe. Das ist im Wesentlichen dieselbe Idee, die ich schon erwähnt habe, die man innerhalb eines Prozesses macht. Man macht zuerst die gefährlichen Sachen, wie Dateisysteme einhängen, Dateisystem Prüfungen durchvornhmen. Die müssen alle das Roh- und Datei-Block, die weil sie der Festball zugreifen. Aber wenn man das fertig ist, dann braucht man vielleicht so einen Zugang nicht. Das ist ein Server im Produktivbetrieb. Also, könnte man den ganzen System das Recht nehmen, Roh-Block-Geräte zuzugreifen. Und Secure Level kann genau das machen. Man kann es nur erhöhen, nur Route kann es erhöhen und niemand kann es verringern, ohne das System neu zu starten. Das bedeutet auch, dass man Zugang auf Def Cayman verbieten muss und Sachen, ähnliche Sachen. Secure Level macht das alles auch. Dann, ich habe bereits geredet über Change Route. Jail ist so was Ähnliches, nur viel besser. Das Jail hat sein eigenes Wurzelverzeichnis für das Asset-System. Man kann außerdem IP-Adressen für verschiedene Jails setzen. Das heißt, im Endeffekt hat man ein Route-Verzeichnis in dem Gefängnis. Aber man hat nicht das Problem, was man sonst hat, wenn man Route im Gefängnis hat. Also, ein Route im Gefängnis ist nicht wirklich ein Route. Ein Route im Namespace ist so eine Art Zwischending zwischen Namensräumen, zwischen Namespaces. Das ist alles noch in Entwicklung. Die werden gerade jetzt im Wesentlichen noch immer erweitern. Also schaut euch weiterhin an, wie die Fähigkeiten von Jails sich weiterentwickeln. Der wird auch daran gearbeitet. Der Administrator, der diese Jails einrichtet, kann festlegen, ob, zum Beispiel, System 5 Inter-Prozess-Kommunikation erlaubt ist oder ob Rohersockets erlaubt sind. Und Dinge wie dies hier, das ist wirklich gut. Und es wurde verwendet, zum Beispiel, um eine containerartige Hosting-Lösung für FreeBSD zu bauen. Eines der Probleme mit Jail, vielleicht kein Problem, aber es macht mich ein bisschen unzufrieden zurück. Es ist nicht wirklich ein Namespace. Es ist mehr so eine Markierung, ein Flag am Prozess. Sie haben die Datenschruktur für Prozesse im Kernel erweitert. Wo dann drinsteht, das hier ist relativ zu Jail 5. Und man kann das theoretisch immer noch sagen, kill Pit 5, Prozess 5, aber das geht nicht, weil es ein Extra-Check ist, aber das heißt, es muss überall ein Extra-Check, wo was mit PEDs getan wird, muss ein Extra-Check sein, um diese Jails zu prüfen. Ich denke, das ist riskant, aber scheint ziemlich stabil zu sein. Es sind keine Probleme bekannt, die sie damit hatten. Die Prozesse, die eins ist immer im äußeren Haus, nicht in irgendeinem der Jails der Erfängnisse. Wenn man PED 1, Prozess 1 töten will von irgendeinem Jail, wird das nie gutgehen, weil PED dann nicht hingehört. Also es ist wie so Namespaces light, wenn man so will. Aber das heißt, wenn es zwei Prozesse in verschiedenen Jails gibt, können die nicht dieselbe Prozesse, die haben. Das ist ein leichtes League an Informationen. Es ist nicht klar, ob das ein Problem ist, aber nur, damit man mit allen klar ist, wie das hier funktioniert. Also, lass uns anschauen, die APIs, die Programmbibliotheken, die einschränken können, was Programme tun. Capsicum ist der FreeBSD-Weg, das zu machen. Das ist insgesamt eine ziemlich coole Idee. Die Idee ist, dass man einen Broker-Service abtrennt und man benutzt Capsicum, um sicher zu machen, dass alle Zugriffen auf globalen Namespaces öffnen einen Datei, erstellen einen Socket, dass die alle schiefgehen. Und der einzige Weg, einen Falldeskriptor zu bekommen, ist, durch den Broker zu gehen. Um sicherzustellen, es gibt ein paar mehr Einschränkungen in Capsicum. Man kann zum Beispiel sagen, P-Trace ist verboten. Man kann auch sagen, Apparitionen auf Sockets, nur diese einige Socket-Apparitionen sind erlaubt, um ein bisschen mehr detaillitere Kontrolle zu haben. Aber es ist nicht wirklich super detailliert. Man kann zum Beispiel nicht sagen, M-Map ist verboten, als man wollte. OpenBSD hat sich dann noch eine neue IPA ausgedacht. Die heißt Tame, Zamen. Das ist ähnlich wie Capsicum. Aber schränkt die Sache noch ein bisschen weiter ein. Mein Problem mit dieser IPA ist, dass sie diese Flags haben, die sie brauchen. Und wenn du irgendwelche anderen Wege brauchst, deinen Prozess einzuschränken, geht das nicht. Alles, was du hast, sind genau die Flags, die sie für dich zur Verfügung stellen. Es ist also nicht wirklich programmierbar, wenn man so will. Es ist nicht so flexibel wie Linux. Aber wenn diese Flags alles sind, was du brauchst, und meistens, du solltest reichen, dann ist das insgesamt ziemlich gut. Das Problem ist, dass die Feins sind in C, wenn man also verschiedene Versionen von OpenBSD unterstützen will, hat man eine Hölle von iftevs. Wenn dieses Flag zur Verfügung steht, dann ist das nicht so ganz portabel danach. Fühlt sich alles nicht so super an für mich. Aber die OpenBSD-People haben da schon dazu. Deswegen haben sie jetzt eine neue API. Ja, die heißt Pledge. Und was man damit macht, ist, man macht im Prinzip dasselbe wie die Flags, nur man macht so einen String. Und der String wird dann vom Kernel ausgelesen. Und wenn man versucht, man irgendwas mit Pledge aufzurufen, was der Kernel nicht kennt, dann passiert irgendwas nicht. Aber der Kernel muss jetzt Strings pausen, und das ist auch gefährlich. Also ich weiß nicht, ob das jetzt wirklich eine Verbesserung ist, aber es gibt es halt auch. Eine ziemlich gute Idee da drin ist, die es sonst nirgendwo gibt, ist, man kann auch eine Liste von Faden übergeben. Und Dateisystemzugriffe funktionieren nur, wenn der Dateiname in einem von diesen Faden liegt. Das heißt, man muss jetzt keine Jail aufsetzen oder Change Route benutzen, sondern man kann einfach sagen, okay, ETC Host ist okay. Aber ansonsten, mein Homeverzeichnis in Ordnung. Aber alle anderen, Slash Temp ist in Ordnung. So eine Art Liste. Und mein Programm muss ich dann nie, also mein Programm muss halt niemals nach User bin, irgendwelche Aufrufe machen. Das ist eigentlich ganz praktisch. Das würde ich mir bei den anderen APIs auch wünschen. Also gucken wir uns Linux an. Linux hat ein recht früheres Konzept von Kapabilities, von Fähigkeiten. Das war noch aus der Zeit, als wir noch gar nicht darüber nachgedacht haben, mehr als nur Privilegien abzulegen. Das heißt, die Idee ist, anstelle von Privilegien, geben wir dir erst gar nicht die Privilegien, die du nicht brauchst, aber das ist nie wirklich benutzt worden. Das heißt, es könnte also einen Ping geben, was kein Super-User läuft, sondern es kriegt nur den Teil, wo man ROASockets anlegen kann. Also es könnte jetzt zum Beispiel nicht irgendwie so ein Device direkt zugreifen. Aber das ist nie wirklich benutzt worden, soweit ich weiß. Und dann gibt es ein kombiniertes Ding. Das gibt es bei OpenBSD und Linux. Das heißt Systrace, das ist auch ziemlich alt. Und die Idee ist, es gibt ein systemweites Profil, das sagt, Ls kann OpenDear, ReadLink, ReadDear und Riot machen. Das ist ein Systemaufrufe, weil es halt den Output zum Beispiel schreiben muss. Aber wenn es sonst irgendwas macht, dann geht ein Alarm los. Und das ist die Idee. Aber das Profil gehört halt nicht zum Programm und das Programm kann sein eigenes Profil nicht setzen, sondern das ist wieder was, was der admin einstellt oder wird bei Installation eben mitinstalliert. So sieht dann so ein Profil aus zum Beispiel. Ihr müsst es jetzt nicht genau angucken, aber nur damit ihr eine Idee habt, was ihr erwartet. Es ist eine Textarteil. Und das Problem dabei ist, woher kommt das Profil? Also, naja, die Antwort ist, der admin ist irgendwie geschult oder hat so ein Training-Modus. Und da habe ich vorher schon drüber geredet. Ich glaube nicht, dass das eine gute Idee ist, weil es ist schwierig, so ein Programm zu prüfen, was man selber geschrieben hat. Und die meisten Leute können noch nicht mal Unit-Tests so schreiben, dass sie alles abdecken. Also, wie kann man erwarten, dass der admin das hinbekommt? Also, ich glaube nicht, dass das eine gute Idee ist. Und dann gibt es eine Serie von Patches für den Kernel, der heißt GR Security. Der bietet Features an. Die sind vom Konzept her ähnlich wie Systrace. Die gehören nicht zu dem normalen Kernel. Also, ich mache jetzt hier keine Werbung dafür. Aber ich denke, wenn ihr so was haben wollt, dann sollte es halt eigentlich in dem normalen System drin sein und braucht keine externen Abhängigkeiten. Und dann gibt es SE-Linux. Das ist auch relativ bekannt. Das ist vom Konzept her dasselbe wie Systrace ein bisschen mächtiger. Aber kann wieder nicht benutzt werden, um euch selbst zu sendboxen. AbArmor ist auch wieder so ein ähnliches Ding. Kann auch wieder nicht benutzt werden um sich selbst zu sendboxen. Und die API, die man benutzt um sich selbst zu sendboxen, die heißt Seccom Filter. Das ist von einem Start-up-Firma von 2005. Und die Idee war, okay, ihr könnt eure CPU-Zyklen, die ihr nicht braucht, für Wissenschaftliessrechner und Cloud Computing, spenden. Aber weil man den fremden Code halt nicht trauen kann, benutzt ihr halt so ein Sicherheitssystem. Und die Idee ist, benutzt Berkeley Packet Filter. Wer weiß denn, was das ist? Das ist eine virtuelle Maschine, die mit Bitecode arbeitet. Das ist ganz, ganz schlimm. Das ist eine Stackmaschine mit sehr eingeschränktem Instruktionen. Und es gibt Tools, aber dann ist es immer noch schrecklich. Aber es gab jetzt im Linux-Kernel einen Just-in-Time-Compiler. Die haben gedacht, das ist schnell, das sollten wir mehr benutzen. So sieht ein Programm aus für TCP-Dump, wo es dafür gedacht wurde. Wenn ihr sagt, okay, port 22, dann wird Bitecode zusammengestellt. Der dann schaut, okay, das Paket ist IP, TCP oder UDP. Und das ist eben port 22. Das ist ziemlich abstoßend. Und die Idee mit second mode 2 war, dass man statt Paketen jetzt einen Speicherbuffer reingibt, der diese Syscon-Nummer reingibt und alle, also zu dem Syscall und alle Argumente dazu. Und dann kann man ein kleines Programm oder Bitecode schreiben, die sich das Ding anguckt. Und dann kann man sagen, nee, also dieser Syscall ist jetzt nicht erlaubt. Es gibt noch ein paar Details im Hintergrund, aber es läuft darauf hinaus. Wir haben ganz viele Makros und das ist wirklich hässlich. Aber ich dachte, ihr sollt das wirklich mindestens einmal sehen. Ihr würdet also sowas machen wie allow, syscall open, allow, syscall exit. Und das ist dann alles, wenn man nicht die Argumente sich anguckt. Aber es gibt noch zusätzliche Tricks, was auch ursprünglich ein Sicherheitsproblem war. Es gab eine Plattform, die verschiedene Binär-Dateien erlaubt. Und da musste man dann zusätzlich noch mal einen Check machen. Aber darüber rede ich hier jetzt nicht. Und dann baut ihr ein Programm, das sieht dann so aus. Da habt ihr also so diese ganzen BPF-Jump-Aufrufe und BPF-Statement. Also es gibt hier zum Beispiel BPF-LD ist ein Load und dann gibt es ein Jump. Und BPF-Red sagt, na gut, hier ist das Programm zu Ende. Und dann setzt man das hier so auf mit PR-CTL. Das ist also ein Linux-Syscall. Also soweit ich weiß, gibt es hier nur auf Linux. Und der Vorteil ist, es funktioniert. Also wenn man es wegabstrahiert, dann riecht es nicht mal so schrecklich. Und das ist tatsächlich relativ effizient durch den Just-in-Time-Compiler. Und das ist auch relativ mächtig. Aber auf der Gegenseite, was zur Hölle haben Sie sich beigedacht? Also wenn man denkt, Leute schreiben so einen Code, dann sollte also die Komplexität von dem Überprüfungskode nicht genauso kompliziert sein, wie der ursprüngliche Code. Sonst sind da ja auch wieder Fehler drin. Und das gibt alle möglichen Wunderlichkeiten, wenn man sie benutzt. Also zum Beispiel aus historischen Gründen gibt es verschiedene Art und Weisen, manche Dinge zu machen, zum Beispiel Exit gegen Exit Group oder M-Map und M-Map 2. Alle möglichen Sachen. Und am Ende macht man irgendwie beides, auch wenn man nur einen von den Calls benutzt, weil sie dasselbe machen. Aber es ist halt eine ganze Menge Sachen, die man wissen muss, damit man es tatsächlich benutzen kann. Und für M-Map gibt es sogar noch ein echtes Problem, weil M-Map hat mehr Argumente, als es bei 386 für Register gibt. Und die erste Version für den M-Map-Syscall hat tatsächlich die Register gar nicht benutzt, sondern einen Pointer auf einen Puffer benutzt. Und diesen Puffer kann man sich nicht angucken von Seccom-Filter aus. Das heißt, wenn jemand das alte M-Map benutzt, dann gibt es keine Möglichkeit, Seccom-Filter zu benutzen, um das einzuschränken, um auf die Argumente zu gucken. Gott sei Dank hat GLPC das schon sehr lange nicht mehr benutzt. Also solltet ihr irgendwie kein großes Problem haben. Und wenn ihr jetzt Argumente angucken wollt, dann sieht es halt irgendwie so aus. Also in dem Fall haben wir Open und ihr wollt sicherstellen, dass ihr nur lesend öffnen könnt. Und das ist ziemlich hässlich, das CTR. Aber ihr könnt versuchen, das weg zu abstrahieren. Also lass uns mal davon ausgehen, ihr wollt Open erlauben, aber nur für itcreserve.conf. Das ist eine Sache, die man oft machen will. Kann man nicht mit Seccom-Filter machen. Warum? Weil man sich den Speicher nicht anschauen kann. Du könnt euch jetzt wundern, warum erlauben Sie das nicht? Na ja, selbst wenn es getan werden könnte, wäre es immer noch unsicher. Denkt an diese Szene. Wenn du zuerst prüfst und guckst, okay, das ist itcreserve.conf. Und dann erlauben wir, der Open-Syscall darf passieren. Dann gibt es eine gewisse Zeit, die vergeht zwischen der Kontrolle und dem Open und anderer Thread von denselben Prozess, den Buffer mit dem Datein am Ende an könnte. Das heißt, selbst wenn Sie die Check erlauben würden, würde es nicht funktionieren. Das heißt, du kannst dir die Puffer mit Seccom-Filter nicht anschauen, das ist gut so. Wenn du das wirklich machen willst, dann brauchst du so ein Broker Service im Wesentlichen. Es gibt ein paar Dinge, die man versuchen könnte. Man könnte z.B. M-Map einschränken und sagen, es muss ein Read-Only-Seite sein für das Argument oder nur diese Adresse ist zugelassen. Und wenn ich dann den Seccom-Filter einrichte, nur diese eine Adresse ist als Argument erlaubt. Aber das wird wirklich eklig. Ich würde euch nicht raten, das zu machen. Wenn man darüber nachdenkt, M-Protect wäre der Syscall, den man braucht, um ein Read-Only-Map auf eine Read-Write-Map. Also nur auf Lesen auf Schreibenzugriff zu ändern, das muss man auch verbieten. Und man muss sicherstellen, dass wenn jemand M-Map-Aufruf auf einer Speicherbereich, der sich überlappt, dass das auch nicht geht, das wird auch wirklich eklig. Also lassen Sie das nicht machen. Jedoch zum Glück ist Linux nicht Unix. Und das in einem Broker zu machen ist relativ einfach. Man kann einfach einen Open in dem Broker machen und sich dann den kompletten Part der Datei über das Proctor-System anschauen. Das wäre ein Weg, das möglich zu machen. Oder man benutzt die Namespace-Namensräume, was wahrscheinlich der bessere Weg ist. Ja, im Wesentlichen ist das, wie man das machen würde, mit einem Broker. Du musst dir die Frage stellen, haben wir wirklich irgendwas eingeschränkt, wenn wir durch diesen ganzen Aga uns hier machen? Also gehen wir uns mal davon aus, im einen hast du sowas wie Firefox, und der hat die Speichern unter Funktionen, der hat dem Firefox. Und die Idee ist, dass du damit überall ein Datei-System hinschreiben kannst. Wie schränkst du das ein? Selbst wenn du das in einem Broker-Service tust, wenn jetzt jemand Firefox angreift, könnte dieser jemand immer noch, er könnte nicht schreiben, aber er könnte dem Broker-Service fragen, irgendwo hinzuschreiben. Und weil der nun mal das Schreiben erlauben soll, dann wird der Broker-Service das erlauben. Oder z.B. nicht Speichern untereinander das Öffnen lokalen Dateien. Du darfst Öffnen sagen im Firefox, und dann im Detail geben. Das heißt, der Broker-Prozess müsste das Öffnen von Dateien erlauben, von lokalen Dateien. Das bedeutet also, selbst Dateien, die gar nicht für Firefox brauchbar sind, wie dein privater SSH-Schlüssel, Firefox kann sie öffnen. Also selbst wenn du Firefox einschränkst, und Firefox ist hier wirklich nur eine Metapher für irgendeinen x-beliebigen komplexen Prozess, also z.B. MySQL, das selbe Sache. MySQL braucht die Berechnung Dateien aufzumachen, weil es Funktionalität gibt, für die das nötig ist. Man kann das vielleicht wegspachen, wenn man es speziell fängt, wenn man es nicht braucht, aber man kann das nicht generell für alle machen. Das ist generell ein Problem. Du kannst mehr Einschränkungen machen, wenn du mehr weißt über deine Anwendung, und das ist eines meiner Argumente, weil der Administrator weiß das üblicherweise nicht, der Programmierer weiß das. Der große Elefant im Raum ist, auf jeden Fall hier sind die Bugs im Körnel, die fehlen im Körnel. Wir haben einen kritischen Körnelfreder, normalerweise alles sechs bis zwölf Monate, wenn wir uns auf ein Sicherheitsmechanismus wie Namensräume oder Seccom Filter verlassen, dann wird das nächste Sicherheitsproblem dort drin sein. Das komplizite Code, das komplizite Code hat Bugs, richtig? Die Erwartungshaltung ist also, die meisten nicht gefundenen Bugs sind in obscuren Orten des Körnels. Also mein Beispiel, zum Beispiel wäre das Handling von X-25 Sockets. Wahrscheinlich Bugs sind da, was niemanden kümmert. Wenn wir das einschränken können, würde uns das etwas bringen. Es hat also Sinn, nicht nur Berechtigungen einzuschränken, sondern darüber hinaus hat es Berechtigungen, den Sinn einzuschränken, die Körnel APIs einzuschränken, die der Programmierer verwenden darf. APIs einzuschränken, die ein Problem in der Zukunft haben könnte, ist auch ein Gewinn. Selbst wenn wir jetzt nichts Konkretes damit davon haben, dann ist das quasi Versicherung für die Zukunft. Also die erste Regel in Seccom Filter, die erste Regel in Seccom Filter ist Sperreaufrufe an Seccom Filter. Also zum Beispiel habe ich versucht, meine Ping-Implementierung einzuschränken, um ein bisschen das Gefühl für die ganze Implementierung zu kriegen. Also was du machst ist, okay, du holst dir einen rohen Zocker, du gibst eine Privilegien ab und jetzt willst du einschränken, was der Angreifer tun kann. Also bevor du anfängst, die Kommandozeile zu pausen. Du schränkst das ein, die Regumentation sagt, wenn du zwei Filter mit Seccom Filter anwendest, dann gelten beide. Das ist ja super. Das heißt ich kann das in mehreren Stadien machen. Das erste Stadium beschränkt die Sachen, die ich nie brauche. Das heißt aus dem Zugriff, das kann ich erst einschränken, wenn ich DNS-Far Deck habe. Das kann ich erst machen, nachdem ich die Kommandozeilangamente gemacht habe. Das heißt ich habe mehr Rechte als ich brauche, während ich die Kommandozeilangamente pausen. Das heißt ich habe mehrere Aufrufe an Seccom Filter gemacht und ich habe herausgefunden, das funktioniert nicht so, wie dokumentiert. Das solltet ihr beachten. Ich konnte einen Filter installieren, der Seccom Filter verbietet, zweimal. Guckt nach, dass ihr Unitests habt für eure Einschränkungsmechanismen. Unter Windows kann man das theoretisch machen, aber es ist so schwierig, dass ich euch davon abraten würde. Wenn du wirklich sicher bist und willst das unter Windows machen, dann schaut euch an, wie Chrome seine Sandbox macht. Das ist Open Source. Es ist wirklich harig und ich würde mich nicht sicher fühlen, wenn ich irgendein Stück Code in meine Projekte daily zu sein. Es ist irgendwie kein Verbreitet Windows, dafür grundsätzlich. Das könnt ihr zum Beispiel machen, indem ihr ihren App-Lockdown verwendet und sie anbieten. Das ist nicht euer Fehler, wenn es schlecht ist, aber das selber zu machen, ist keine gute Idee unter Windows. Also kommen wir zur Zusammenfassung. Ich denke, insgesamt von der Funktionalität her sind wir ziemlich gut dran. Wir können die meisten Dinge tun, die wir tun können wollen, unter Linux FreeBSD und OpenBSD zumindest. Das detaillierte Einschränken ist möglich, aber es ist schwierig und knibbelig, das zu machen. Wenn ihr Code schreibt, dann ist dieser Code natürlich auch kompliziert. Also von daher ist kein so wirkliches Argument. Wenn du wirklich paranoider Autor von Software bist, dann kannst du ein bisschen Performance opfern, um Sicherheit zu gewinnen. Die Spur, die Spur gibt hier vor im wesentlichen OpenSSR, deren Sandbox Code sollte euch wirklich mal anschauen, wenn ihr wissen wollt, wie man das selber macht. Persönlich muss ich sagen, ich hab das Gefühl, ich kann nachts gut schlafen, weil ich weiß, dass sich die Prozesse alle eingeschränkt haben an der Prozesse und ich weiß, dass das Einschränken wirkt. Arbeitet. Funktioniert. Also abschließende Worte. Benutzt das in eurem eigenen Code. Ich denke, das sollte quasi immer passieren, wenn wir Unit tests beim Deployment. Jeder soll das machen. Wenn ihr denkt, dein Prozess ist zu groß, dann kommt es auf. Ich denke, wir sollten hoffen, wir sollten zuarbeiten auf eine Zukunft in 10 Jahren, wo keine Software mehr verteilt wird, die nicht in irgendeiner Art und Weise sich selber einschränkt. Wenn dein Code nicht mehr funktioniert nach irgendeinem Updates, weil der Einschränkung zu eng ist, weil sie jetzt mehr Rechte braucht, dann hast du es richtig gemacht, weil das heißt, deine Einschränkungen waren sehr präzise. Das ist das harte Arbeit. Ich darf euch stark konzentrieren. Ihr müsst genau prüfen, ob ihr wirklich auch erreicht habt, was ihr wolltet. Aber ihr könnt es schaffen, ich denke, ihr solltet es tun. Irgendwelche Fragen? Ich glaube, wir haben nur 5 Minuten, also von daher. Wir haben so circa 8 Minuten. Ich kann mir immer eine E-Mail sagen, aber ich bin hier auch immer verfügbar. Erste Frage aus dem Internet. Die erste Frage aus dem Internet ist, falls du den Talk gesehen hast, bezüglich der Cloud API, was denkst du darüber? Der Talk über die Cloud API. Den habe ich nicht wirklich gesehen, aber ich habe es wie dir angeschaut. Ich denke, die benutzen im Wesentlichen dieselben Mechanismen. Ich glaube, der Ankündigung, die sie gemacht haben, nicht vertrauen, dass man da ungeprüften Code ausführen kann, wenn man ihn einschränkt. Im Wesentlichen, was sie machen, ist das selbe. Die benutzen diese Mechanismen, um das einzuschränken und das ist die Art und Weise, wie ihr es machen müsst. Mikrofon 1? Was genau war deine Kritik am SecComp2-Mechanismus? Ist das das Design der virtual Maschine, der konkrete Befehlssatz für alle? Ich meine, ihr müsst die Makros nicht benutzen. Es gibt eine Bibliothek, die das wegabstrahiert, aber nachdem der Punkt ist, das zu benutzen, weil ihr euren Bibliotheken nicht vertraut, dann solltet ihr diese Bibliotheken nicht benutzen. Ein Punkt ist, das ist zu kompliziert. Die OpenBSD-App ist relativ gut, dass es relativ einfach zu benutzen und man kann nicht viel falsch machen. Es gibt so etwas leichter zu machen, auch bei Linux. Mikrofon 2, was hältst du von dem XDG-Ansatz zum Einsetzen von Anwendung und XDG-App, was das Genomenprojekt macht, um größere Beschenke, Prozesse einzuschränken, die übliche Weise nicht, als rotlaufen, sondern als normaler Nutzer? Da habe ich mir die Details leider noch nicht angeschaut. Tut mir leid. Mikrofon 4? Diese ganzen das ganze Wegwerfen von Privilegien ist, das passiert zur Laufzeit. Es gibt jetzt ein paar Prozesse oder Werkzeuge, wo man weiß, von Anfang an ich brauche bestimmte Rechte überhaupt nicht. Würde es nicht Sinn machen, wenn man nicht, wenn man so etwas hätte, wie ZECOMP in der speziellen Sektion von den, von der Elfbanner, wie denn der Colonel schon lädt und von Anfang an das anzuwenden? Ja, also das wäre total großartig, aber dafür haben wir halt bislang noch keine Werkzeuge, wenn das jemand zusammen basten würde, das wäre klasse. Eine Frage aus dem Internet. Die Frage ist, was hältst du davon eine Anwendung in sowas wie Docker in der harden Version von Docker zu laufen zu lassen? Ja, also ich denke, das ist eine gute Idee, aber woher wisst ihr, also ich meine, Docker schränkt nicht wirklich alles an, Docker benutzt Namespaces, was eine gute Idee ist. Aber wenn ihr einen Colonel-Bug habt, dann kann man halt mehr machen und auch ums zu vermeiden. Also nicht in allen Fällen, aber ich fühle mich nicht so sicher mit Docker, wie ich mich zum Beispiel mit Docker und einer Applikation, die zusätzlich noch ZECOMP macht. Microphone 3? Microphone 3. Alles was du uns erklärt hast, klingt so wie ich muss all diese Funktionen von C aus aufrufen. Was ist das für ein Weg, all diese Einschränkungs-EPRs von irgendwelchen Sprachen, die typssicher sind oder speichersicher? Ja, wahrscheinlich, aber da müsst ihr halt verstehen, was die Runtime von diesen Sprachen macht und das ist noch ein ganz großes, zusätzliche Komplexität. Also normalerweise kann man von hochleveligen Sprachen auch immer C-Grot in irgendeiner Art und Weise aufrufen. Also sollte es möglich sein. Es hängt mit der vorherigen zusammen. Du hast Resolve.conf erwähnt, dass es gelesen wird, üblicherweise während des DNS-Lookup. Gibt es irgendwelche Ansätze, das Ganze ein bisschen modularer zu machen, weil man zum Beispiel eine Bibliothek hat und dann kann man auf irgendeiner Art und Weise dokumentieren oder spezifizieren, was genau dieser Aufruf oder jener Aufruf genau braucht und das ist eben so. Also ich kenne da gar nichts, aber die meisten Betriebssysteme dokumentieren das irgendwie in ihrer eigenen Dokumentation. Aber wenn ihr Software schreibt, dann wollt ihr normalerweise, dass die besser übertragbar ist. Also nicht nur funktioniert mit dieser Version von libc. Das heißt, man muss halt dann präziser sein, was die Blockierung angeht oder man muss eben potabel sein. Und ich glaube, das ist ungut, das ist die falsche Ansatz. Nicht wirklich vom Internet, aber von einem der Engel hier, ich werde das Mikrofon gerade weitergeben. Du hast erwähnt, dass man mit den Broker-Diensten zum Beispiel das Öffnen von Dateien verhindern kann und dass das nicht hilft mit Prozessen, wie Firefox die beliebige Dateien aufmachen können. Was wir jetzt noch machen ist, ein Broker-Service ist wie verwenden ein Broker-Service und das ist der Broker-Service, der den Usage-Datei fragt, die aufgemacht werden soll, sodass also der Programm im Hintergrund nicht fragen muss, welcher Datei. Wenn ich von Broker-Service rede, dann meine ich nicht, dass der Betriebssystem irgendwas startet, sondern das Programm teilt sich am Anfang auf und einer von diesen zwei Prozessen ist dann der Broker für die andere Hälfte. Also, wenn ihr wollt, dass der Administrator irgendwas installiert, damit die Applikation sicherer ist, dann darauf solltet ihr euch nicht verlassen, denn ihr wollt, dass eure Applikation immer sicher ist. Also, ihr solltet es selber machen als Programmierer. Mikrofon 8. Hallo. Es ist nicht ein Problem, dass die Meister dieser Mechanismen zum Einschränken vom Privilegien voraussetzen, dass man Super-Userrechte vorher hat. Das zeigt also nicht in zusätzlicher Zeit der Verletzbarkeit für Programme, die wirklich eigentlich gar nicht Super-Userrechte brauchten, aber sich selber einschränken wollen? Also, ich glaube nicht, dass die meisten APIs Super-Userrechte brauchen. Second Filter braucht es nicht, Tame und Bletch glaube ich nicht. Ich bin bei Capsicom nicht sicher, aber ich denke auch nicht, Jane Shrut braucht es und Jail braucht es, denn die sind eigentlich für andere Sachen gemacht. Aber ihr habt einen externen Mechanismus, den rohen Sockezug bekommen und ihr braucht nicht als Ruhe zu laufen, dann könnt ihr dieses APIs natürlich benutzen, ohne Ruhe zu sein.