 Okay, everyone, so now please join me in welcoming Eric, who is a PhD student at the FU in Amsterdam, and he will talk about ASLR. Please give him a warm round of applause. Hello. Like the Herald said, I'm Eric. Hallo, wie der Herald schon gesagt hat, ich bin Eric. At the FU in Amsterdam, at the FUSAC Group. Ich arbeite in der FUSAC Group in Amsterdam. In der FUSAC Group, heute. Aber die Arbeit, die ich präsentiere, die meiste Arbeit hat Ben, Grask und Stefan gemacht. Die haben gezeigt, dass der Angriff, den ich präsentiere, alle 22 Mikros funktioniert. Ich versuche, diese Folien, alle meine Talks reinzupacken. Diesmal passt das besonders gut, weil der Talk darüber geht, diese zu finden. Der Talk ist dafür, TSLR anzugreifen. Das ist Adress-Raumverwürflung. Das ist eine erfolgreiche Methode. Es wurde weitreichend benutzt, um viel schwieriger zu machen. Es verändert den Ort, wo der Code und die Daten abgespeichert sind. Jedes Mal, wenn der Prozess läuft, kann der Angreifer sich nicht darauf verlassen, dass bestimmte Adressen die ganze Zeit gleichbleiben. Auf den modernen 486 Architekturen. Man kann nicht in dem ganzen Bereich schreiben und lesen, weil euer Computer vielleicht nicht so viel Speich hat. In der Realität wird der kleine Teil von einem Prozess benutzt. Daher ist es ganz einfach, den Ort dieser Daten zu ändern. Wenn man die Daten nicht weiß und eine Adresse auf dem Stack überschreiben möchte, dann springt man zu dem falschen und dann schützt es ab. Man braucht nur eine Lücke, um die Informationen auszubekommen. Man kann den Back noch einmal benutzen. Man muss eine andere Schwachstelle finden, um das auszunutzen. Diesen Präsentation ist ein Angriff, der benutzt einen Nebenkanal von JavaScript. Es läuft auf dem Prozesslauf und auf der Hardware selber, um den Ort von Daten und Code auf dem Speicher herauszufinden. Die Bundetsee im EU-Architektur hat mehrere Schichten. Wenn man als Programmierer Maschinencode schreibt, ist da ein Zeug, wo man sich nicht kümmern muss. Insbesondere um das Programm schnell zu machen. Der Speicher ist sehr langsam im Vergleich zum CPU in modernen Computern. Daher gibt es einen Cage-Mirchenismus. Andere Sachen sind auch weggekürzt. Die Daten werden in den Cage geschrieben und man bekommt eine virtuelle Adresse zurück. Es gibt eine virtuelle Adresse zu dem CPU und der muss das in eine physikalische Adresse umwandeln. Das wird bei einer Komponentengetannte, die die Speichermanagement-Einheit ist. Man nimmt die Aufgabe von virtuellen Speicher in physischen Speicher umzurechnen. Aber wenn eine Adresse nicht in dem Cage ist, dann muss es diesen Pt-Walk machen. Pt-Walk ist das, was wir versuchen werden, anzugreifen. Wir messen einen Effekt, den der Pt-Walk an den 3 Cage hat. Um herauszufinden, was durch den Band des Pt-Walks stattfindet. Und dann benutzen wir, um zu Messenabspeicher anzusehen. Dafür brauchen wir einen sehr guten Timer, um das festzustellen. Glücklicherweise haben die Prosa-Standard-Committees einen Funktionen eingebaut, um genau zu machen. Dadurch bekommen wir eine sehr klare Zeitmessung, bis jemand einen Paper veröffentlicht hat, das gezeigt hat. Dass man diesen LKH-Angriff auf dem CPU machen kann. Der Browser macht die Messung grüber. Und jede Mikrose bekommt einen kleinen Sprung. Und nichts verändert sich. Aber es ist noch nicht verloren für den Angreifer. Weil man kann den Timer für die Vergröbung ausnutzen. Man nutzt ein Zähler, um diese Sprünge auszurechnen. In Chrome wurde die Zeit variiert. Aber man kann an diese mehrere Messungen machen. Man kann wieder eine gute Messung bekommen. Die Prosa-Macher haben entschieden, das ein bisschen schwieriger zu machen. Die Prosa-Standard-Committee, wenn sie nehmen, es geben, ist auch, sie haben entschieden, etwas zu machen. Das wird der Shared-Array-Buffer genannt. Das erlaubt, mehrere Shareds gleichzeitig zu laufen. Und das ist standardmäßig aktiviert. Und nachdem wir diesen Angriff veröffentlicht haben. Sie haben mir der Wege aufgegeben, diesen Zeitangriff zu verhindern. Der Shared-Array-Buffer kann für anderes benutzt werden, aber darüber will ich heute nicht sprechen. Wie können wir die Zeit messen, in der Shared-Memory genutzt wird? Das eine ist die Zeitmessung und das andere ist die Operation. Der Timer Shared wartet bis die Shared-Operation. Das setzt eine Variable und startet die Operation. Und währenddessen der Timer-Prozess sieht, dass der Oster geändert worden ist und startet das Zählen. Und der zweite Shared startet den Buffer wieder. Und dadurch bekommt man eine sehr klare Messung. Jetzt haben wir eine Skala auf 9 Sekunden Genauigkeit, mit der wir das alles messen können. Wir machen jetzt eine Timer-Attacke, auf den höchstrangigen Cache. Auf der Granulität einer Cache, das heißt, es muss immer eine komplette Cache laden. Wenn ich jetzt eine bestimmte Adresse habe, eine physische Ramadresse, dann meckt die auf eine ganz bestimmte Cache-Set-Adresse. Das heißt, auf meiner normalen Intel Desktop-Maschine hat man 16 verschiedene Cache-Lines in einem Cache-Set. Ich rede jetzt hier über moderne Intel-Maschinen, aber es funktioniert im Prinzip bei anderen Micro-Architekturen genauso. Per Core gibt es 2048 Cache-Sets, die man jeweils ein Slice nennt. Das ist einfach die Art, weil sie hier Intel seinen Cache intern anordnet. Um jetzt die Cache-Set-ID auszurechnen, muss man wissen, welches Slice man aus der Adresse hat. Das heißt, die 6 Bits sind der Becher Slice, und der Rest nächsten 11 Bits sind dann die Cache-Set-Memory. Die Cache-Slice ist ein kompensierter Cache. Das Wichtigste, was man sich merken muss, ist, dass wenn zwei Cache-Lines im physischen Speicher auf das gleiche Cache-Set gemappt werden, dann haben sie denselben Offset. Die selbe physische Adresse, wenn man sich nur die Bits anschaut, haben sie die selbe Adresse Modulo 128 kW. Das ist genau die Größe einer Speicherseite, also quasi die kleinste Einheit des Speicherverwaltungssystems, der meisten Architekturen die heute Tage benutzt werden. Nachdem wir das alles wissen, können wir eine Cache-Side-Channel-Attacke fahren, eine Neben-Channel-Attacke. Viele verschiedene Varianten sind möglich, und wir versuchen einfach mal die Einfaste zu benutzen. Was wir machen müssen, ist, dass die Cache-Side-Memory verdrängt wird, die die Teile in ein bestimmtes Cache-Set und darauf kommen wir zu greifen. Bei einem bestimmten Offset einer Seite sind mit unseren Datwalts gefüllt, dann machen wir eine Operation, dann lassen wir die Operation laufen und schauen, wie lang es gedauert hat. Wenn die Operation irgendwas mit den physischen Speichern machen muss, bei einem Cache-Set, der mit einer Cache-Line im physischen Speichern in diesen Cache-Set reinmärbt, dann dauert es länger, weil Speicherzugriffe dauern sehr lange im Vergleich zu direkt Zugriffen auf den Cache oder einfach nur Ausführungen in den Registern. Das heißt, wir können sehen, ob die Operation von einer physischen Speichern alles abhängt. Wir hängen das jetzt alles zusammen mit dem PageTable-Walk, den wir angreifen wollen. PageTables sind ein Mechanismus, um Prozesse zu adressieren, um einen sehr großen Adressraum adressieren zu können, ohne wirklich viel physische Speicherarbeit zu verborgen. Also am Ende des Tages ist es ein Baum, wobei auf jeder Ebene der Seiten sind und das Ganze in den gleichen Teilen aufzahlen. Bei Intel ist der erste Ebene die vierte Ebene, weil da vier Ebenen sind. Das teilt den Adressraum in Bereiche von 512 Gigabyte auf dem nächsten Level. Die müssen nicht alle ausgenutzt werden, aber sie können. Das teilt es auf den Ein-Gewalt-Bereich, dann auf dem nächsten Ebene in zwei Gigabyte-Bereiche und am nächsten in vier Kilobytes-Bereiche. Jeder Eintrag darin zeigt genau auf eine Adresse im Speicher. So, wenn jetzt was der PageTable-Walk-Prozess macht ist, er nimmt die virtuelle Adresse und benutzt eine Binärdarstellung dieser Adresse. Einfacher ist, den Prozess darzustellen. Die Bits die Eins sind, sind hier schwarz dargestellt, die Eins sind, die weiß. Und jetzt haben wir einen Fehler, also das heißt, der TLB hat die Gezeite nicht sofort gefunden, sondern muss erst suchen. Das CPU zeigt es auf den ersten PageTable. Die Hardware schaut sich dann die neuen, signifikantesten Bits in der Adresse an und benutzt es als ein Index-Pointer in diese Tabelle rein. Damit er das selbe mit dem nächsten Level, dann am Schluss kommt man dann auf der Ebene an, wo wir wissen, dass der Speicher weg ist. Die letzten zwölf Bits sind dann der Offset in diesen Bereich rein. Das ist eine 4-Kilo-Weit-Seite. Jetzt können wir diese Seite benutzen, um einen Nebenkanal-Attack zu fahren. Aber die Beobachtung ist, die PageTables sind selber Pages. Das heißt, wir können auch einen Nebenkanal-Attack auf diese Seiten fahren. Das ist uns das mal anschauen. Was wir dabei finden können. Wir können z.B. finden, dass eine bestimmte Seite ein Traffer hat. Es gibt 8 mögliche Einträge, die diesen Traffer verursachen können. Das heißt, wir wissen noch gar nicht so viel. Wenn wir uns die alle anschauen, merken wir, dass die ersten 6 Bits die gleichen sind. Das heißt, wir wissen, dass es eine Abfolge von 6 Bits in der Adresse gibt, die diesen Wert hat, den wir durch den Nebenkanal-Attack herausfinden können. Es gibt 4 Ebenen an Seiten-Tables. Das ist wie als Teil der verschiedenen Ebenen im Cash-Level. Wir können es annehmen, dass die letzte, die genaue Adresse im Speichere angeht. Es gibt andere Nebenkanal-Attack, mit denen wir das finden können. Das findet man relativ einfach über den Code. Das können wir mit 6 Bits machen, nachdem wir die anderen alle gefunden haben. Wir versuchen das zu ignorieren, damit es uns nicht im Weg umgeht. Wir haben jetzt 4 Cash-Lines gefunden, die für den Page-Table-Wall benötigt werden. Wir sehen, dass es 4 Bereiche gibt, mit jeweils 3 Bits, über die wir nicht wissen. Wir wissen noch nicht, welcher Treffer für welche Cash-Line benutzt wurde. Wir haben noch etwa 16,5 Bits an Entropie übrig. Wir haben immer noch nicht so viel gefunden, weil 16 Bits sind immer noch gar nicht so wenig. Aber jetzt gibt es noch einen Trick. Das ist eine Technik, die als Sliding der Adresse hier erstmal ein Puffer, der groß genug ist. Wir fragen dann bestimmte Seiten allen nach der anderen ab. Das sieht ungefähr so aus. Das ist jetzt jeder der letzte Level an Cash, also der vierte. Immer weiter, immer die nächste Seite. Überwechselt, dann wissen wir, das ist jetzt eine Grenze der Cash-Line. Das heißt für die nächste Seite werden die niedrigsten signifikanten Bits, der Adresse werden alle 0 sein, weil das eine Grenze war. Das heißt, das können wir auch bei den zweiten Ebenen machen. Jedes Mal 2 Megabyte dazu. Das ist immer noch kein großes Problem. Alles aus Java ohne Probleme machbar. Dann kriegen wir den gesamten Eintrag aus dem zweiten Level. Entropie bleibt übrig. Wir haben 2 Chance auf je 3 Bits. Wir wissen mal nicht, in welchem Page, Table und welche Cash-Line gehört zu welchem PT. Damit bleiben uns 7 Bits übrig. Hier gibt es nicht viel zu tun, wenn wir eine gute Zeitmessung in Javascript machen wollen. Aber wir können mehr machen, weil in der Praxis ist nicht optimal. In diesen Tagen fangen wir an, 1 Gigabyte reinzuschreiben. Und das möglich und für die höchste Stufe macht man 512 Gigabyte Allocations. Dann muss man das 8 Mal machen und das funktioniert dann nicht. Aber für Firefox, unter Linux, für ein bestimmtes Objekt, das Arraybuffer genannt wird, Firefox initialisiert den Speicher nicht und fragt einfach den Kernel für den Speicher und lässt ihn da. Der Linux Kernel initialisiert ihn nicht und packt keine Page-Table-Struktur da rein. Und es benutzt keinen Speicher, solange wir es nicht berühren. Wir müssen keinen Speicher verbrauchen. Wir müssen nur darüber gehen und nur eine Seite an, ganz am Ende benutzen. Unter Linux kann man große Bereiche von virtuellem Speicher allokieren. Und innerhalb von Sekunden oder Minuten kann man das ganze berechnen. Man kann den Sliding-Angriff fahren und die Cache-Line umdrehen auf der höchsten Page-Table-Level. Chrome initialisiert den Speicher, was ein bisschen unglücklich für uns ist. Aber es zerteilt Speicher in Heaps. Und wenn der Heap voll ist oder es entscheidet aus Sicherheitsgründen, dass es einen neuen erzeugt und um das ISLR zu vergrößern, es versucht eine große Lücke zwischen den beiden Heaps zu erzeugen. Das bedeutet, wir können schnell vorwärts bewegen im Adress-Raum. Und diese Methode, die neuen Heaps zu erzeugen. Wir können die Adress-Bits des dritten Levels benutzen mit ein paar Bit-Entropied. Überlich unter Windows, ich bin nicht sicher welche. Aber der Angriff auf dem vierten Level würde eine lange Zeit brauchen. Weil Chrome viel Speicher initialisieren muss und das Notebook wird heiß. Und dann gibt es keinen SLR Recovery in diesem Fall. Das war jetzt implementiert auf einer Skylake-Maschine. Aber es ist auch wirklich witzig, dass es auf den 22 Nm Maschinen funktioniert. Und das wurde jetzt gemacht mit einem Nativen-C-Programm. Das ist für ein Demo-Video. Hier haben wir den Browser. Diese Bit-Bits sind die Signals-Tatsächlich-Messung, und das versucht die größtmöglichste Werte zu finden für den Angriff. Das sieht sehr matrixmäßig aus. Das versucht dann Sicherheit zu bekommen und misst zu einem bestimmten Punkt und sagt dann, es ist klar. Dann fügt man noch GDP dazu. Und dann können wir sehen, ob die Adresse ein Ort ist, den wir kennen. Weil wir eine Markierung da gelassen haben. Zusammenfassend, es ist möglich, sehr viele Adressen-Informationen mit JavaScript über Seitenkanal-Angriffe zu bekommen. Alle großen Browser-Hersteller haben aufgegeben, solche Angriffe zu verhindern. Das ist wahrscheinlich die Richtung, in die wir gehen. In welche Fragen? Hast du an Browser-Bugs geguckt und wie viele auslutzbar sind? Normalerweise sind es zwei. In unserer Attacke benutzen wir eine Möglichkeit, um einen Datenpointer rauszuliegen. Wir legen auf einen javascript Code an. Es ist ziemlich hart für Code. Die PageTables, die auf die echten Seiten zeigen, sind relativ einfach. Du hast gerade die Browser-Hersteller kritisiert, die nicht die ganzen Sicherheitsmaßnahmen und Probleme zu verwenden. Welchen Browser würdest du empfehlen? Einst der Dinge, die diese Attacke sehr einfach ist, ist, dass die Browser-Hersteller versucht haben, sich gegen eine andere Artikel zu schützen. Wenn man ein Haufen speichert in anderen Bereichen und dann wieder etwas anderes anzieht, dann kann man relativ übeles Zeug anstellen. Man kann sich versuchen, sich zu überlegen, die so etwas zu erinnern, aber die arbeiten dann wiederum gegen die anderen Sicherheitsmaßnahmen. Es gibt nur sieben Bits, die nicht in der Architektur schon vorgegeben sind. Es mag schon sein, dass es etwas hilft, aber es gibt noch viele Stunden, um das zu implementieren, aber ein Exploitschreiber. Für den ist es immer noch extra Aufwand, aber es macht es nicht unüblich. Ich bin mir so ganz sicher. Die Angreifer werden immer die MMO benutzen, aber die Ort, wo es dann landet, ist etwas schwieriger. Aber ASL wird benutzt gegen lokale Attacken, das zeigt, dass es eigentlich gar nicht so wirklich viel bringt. Kürzlich habe ich etwas gesehen über den Securitiforschelokihard und auf dem Samsung Cortex A7. Was ich mich frage, wenn ich ein Array in JavaScript erzeuge, bin ich dann in der Lage, diesen Angriff mir anzuschauen, wenn ich mit den Adressen angucke? Ich glaube, Shellcode itself ist wirklich nicht ausserbar in einem Array, aber man wird einen Bereich im Speicher kriegen, den man total kontrollieren kann, wenn es das ist, was du willst. Ist es eine PUC, oder ist es eine Klapp-Source? Wir haben es in einem Paper beschrieben, aber es sollte nach baubar sein, hoffe ich. Ich habe die Grafik nicht verstanden in JavaScript. Was waren die Farben für die verschiedenen Sachen, für Y und X? Ich bin nicht ganz sicher, dass die ersten Farben rollen können. Ich bin nicht so sicher, dass die ersten Farben rollen können, aber bei der rechten Seite sind es wahrscheinlich Page Stables C. Die Lookups, die wir suchen. Ich frage mich, ob ihr das an irgendwelchen öffentlichen Sachen ausprobiert habt. Es ist ein Browser, das heißt, es läuft natürlich klein in Seite. Ich möchte weiter machen, wenn es in Ordnung ist. Ich habe mehrere Sachen darüber gelesen, nicht nur als AR, wie die Mitigation für den Schreibzugriff, wie das möglich ist, die Cache zu veröffentlichen. Es gab schon viele Attacke, die man nativ benutzen kann, in einer nativen Umgebung. Da ist ein Browserplugin von der TU Graz, das ist Javascript 0. Was diese Angriffe verändern soll, hast du davon gehört? Hast du ausprobiert, ob es heute diesen Angriffen schüttet? Ich habe es noch nicht ausprobiert, aber es würde sicher sein, dass es dir zu disable Sachen auszuschalten, die du nicht haben willst, inklusive dem Shared Array Buffer war in dem Browser noch nicht vor dem Jahr. Das heißt, ich gehe davon aus, dass viele Public Clouds es benutzen. Ich denke, es ist relativ einfach, Sachen zu disablen, die man nicht will. Javascript baut ständig neue Sachen an, um es passender zu machen für Stilen, Sensorik oder sonst was. Der erste Code benutze ich einfach gar nicht. Ich z.B. benutze Javascript in meinen Pausern nur, wenn die Seite nicht ohne lädt. Ich bin totaler Fan davon, dass man alles mögliche Zeug disablet, was man gar nicht benutzt, aber die Browser scheinen die andere Richtung zu laufen. Wir werden sehen, wie es am Ende ausgeht. Do we have any more questions? No, then please thank our speaker again. Thank you very much.