Push-Nachrichten von MacTechNews.de
Würden Sie gerne aktuelle Nachrichten aus der Apple-Welt direkt über Push-Nachrichten erhalten?

Apple führt "BlastDoor" ein – extremer Sicherheitsgewinn bei Nachrichten

Oft hatte Apple in der Vergangenheit damit zu kämpfen, dass die Übermittlung von "defekten" Nachrichten Apps wie Mail oder Nachrichten zum Absturz brachte. Dies ist nicht nur ärgerlich für Nutzer, sondern birgt auch ein immenses Risiko: Durch speziell präparierte Nachrichten ist es so unter Umständen möglich, einen Prozess zu übernehmen und daraufhin Daten auszuspionieren, Spam-Mails zu verschicken oder die Kontrolle über das Zielgerät zu übernehmen.


Parser mit Lücken
Erhält ein iPhone, iPad oder Mac eine externe Nachricht, wird diese zuerst in ihre Bestandteile zerlegt – das Gerät muss die Nachricht verstehen. Hier wird zum Beispiel der Zeitstempel, der Sender und der eigentliche Text der Nachricht ermittelt – solche Aufgaben übernehmen Parser. Ist jedoch die Nachricht nicht im erwarteten Format, können solche Parser sehr schnell verwirrt und zum Absturz oder undefinierten Verhaltensweise gebracht werden. Bestimmte Arten von reproduzierbaren Abstürzen können Hacker für Attacken nutzen. Ist es dem Angreifer möglich, einen Prozess zu übernehmen, ist es umso ärgerlicher, wenn dieser über weitreichende Rechte im System verfügt. Je weniger Rechte zur Verfügung stehen, desto weniger Möglichkeiten hat der Hacker, die Lücke auszunutzen.

iOS 14 mit Verbesserungen
Beim Empfangen einer iMessage-Nachricht hat Apple nun laut den Sicherheitsforschern von Google Project Zero einen neuen Dienst namens BlastDoor eingefügt – zum Dekodieren einer Nachricht sind nun mehr als sieben unterschiedliche Dienste mit verschiedenen Rechten involviert. Apple entwickelte BlastDoor in Swift, um Speichermanagement-Fehler möglichst zu vermeiden.


BlastDoor kommt auf dem Mac und iOS-Geräten (und wahrscheinlich auch auf der Apple Watch und dem Apple TV) zum Einsatz. Seit macOS 11 und iOS 14 übernimmt nun BlastDoor das Parsen von eingehenden Nachrichten – und verfügt über fast keine Rechte im Dateisystem und die Kommunikation mit anderen Diensten ist deutlich eingeschränkt. Nur eine Handvoll Dienste ist erreichbar, zum Beispiel diagnosticd, logd, syslogd und notifyd. Auch ist die Zusammenarbeit mit IOKit-Treibern vollständig untersagt und BlastDoor darf keine Nachrichten ins Netzwerk senden.

Durch die starken Einschränkungen ist es für Angreifer weit weniger erstrebenswert, diesen Dienst zu übernehmen, da dieser auf dem System über fast keine Rechte verfügt. Einem Hacker bringt die Kontrolle über einen Dienst, welcher fast keine Handlungsmöglichkeiten hat, fast keinen Mehrwert.

Meldung von Abstürzen?
Die Sicherheitsforscher von Google Project Zero fanden ferner heraus, dass bei einem Absturz des BlastDoor-Dienstes Apple über den Vorfall unterrichtet wird. Wahrscheinlich will Apple auf diese Art und Weise sofort auf mögliche Attacken reagieren. Es ist jedoch, ohne den Code auf Apples Servern zu kennen, unmöglich herauszufinden, wozu Apple diese Benachrichtigungen genau nutzt.

Weitere Absicherungen
Apple führte aber noch zwei weitere Sicherheitsmechanismen mit iOS 14 ein, welche bisher nicht veröffentlicht wurden: Bereits mit iOS 4.3 erzeugte Apple Zufallsadressen für wichtige Systembibliotheken, so dass Angreifer nicht davon ausgehen konnten, Code-Bestandteile an fixen Speicheradressen vorzufinden. Doch diese Zufallsadressen vergibt das System nur bei einem Neustart und diese bleiben, während das Gerät läuft, stets gleich. Mit iOS 14 hat Apple wohl dieses Verhalten geändert: Von Zeit zu Zeit werden neue Zufallsadressen vergeben, was Angriffe weiter erschwert.

Die zweite Verbesserung betrifft launchd – ein Prozess, welcher für das Starten von Systemdiensten verantwortlich ist. Stürzt ein Dienst wiederholt ab, startete launchd diesen stets sofort neu – und dieses Verhalten konnten Hacker für Angriffsversuche in rascher Abfolge nutzen. Seit iOS 14 ist es möglich, Systemdienste nicht sofort erneut zu starten, sondern bei wiederholten Abstürzen etwas abzuwarten. Somit hat ein potenzieller Angreifer nicht so viele "Versuche" zur Verfügung, um ein Gerät zu kompromittieren.

Kommentare

Tenner
Tenner29.01.21 10:03
Interessantes Thema!

Ich frage mich, wie die Lage beim Einsatz anderer Messenger aussieht (im Vergleich zum wohl tiefer ins System integrierten iMessage)?

Da ich bei dritten ja explizit Freigaben für Zugriff auf Bilder, Mikrofon etc. erteilen muss:
ist hier trotz Fehlen der oben beschriebenenTechnologie die Sicherheit aufgrund dieser Restriktionen etwas höher einzuschätzen?
Sprich: wurde in iMessage nun ein Nachteil des grundsätzlichen Zugriffs auf Schnittstellen und Medien reduziert?

Oder überragt iMessage jetzt alle anderen Messenger in der Sicherheit bei Darstellung von Nachrichteninhalten?
+4
Eventus
Eventus29.01.21 11:31
Tenner
Gute, interessante Fragen. Hoffe, jemand hier kann diese beantworten.
Live long and prosper! 🖖
+1
cpack29.01.21 14:20
Wie verhält sich Signal??
0
Mecki
Mecki29.01.21 22:59
Ich sehe den Aufwand nur bedingt als gerechtfertigt. Egal ob es um das Parsen von Plisten, XML oder Unicode geht, man kann grundsätzliches alles sicher parsen, wenn man dabei nur eine Hand voll ganz einfachen Regeln befolgt:

  • Verlasse dich nie darauf, dass sich die Daten an irgend einen Standard halten. Natürlich werden sie das tun, wenn die Daten vom eigenen Dienst kommen, aber letztlich kann man nie mit 100%tiger Sicherheit sagen woher sie kommen und Angreifer interessiert der Standard nicht. Wessen Parser <text> sieht und davon ausgeht, dass da jetzt sicher irgendwo </text> kommen muss, der hat schon verloren. Wer sich drauf verlässt, dass ein Unicode Text nur gültige Unicode Zeichen enthält, der auch.
  • Verlasse dich nie auf Angaben, die die Daten über sich selber machen, weil natürlich können die Daten lügen. Wenn das Datenformat sagt "da kommen jetzt 50 Bytes und dann der nächste Datenblock", dann können da auch nur 30 oder 70 Bytes kommen. Wer also 50 Byte Speicher reserviert und einfach Daten bis zum Ende ließt und in diesen Block schreibt, der schreibt dann fröhlich über den Speicherblock hinaus, wenn das gelogen war. Angreifer können irgendwo in einen Datenstrom Daten hinzufügen oder auch entfernen.
  • Verlasse dich nie darauf, dass die Daten irgend eine von dir festgelegte Grenze einhalten werden. Nachrichten können nie größer als 5 MB sein? Objekte nie mehr als 20 Level Verschachtelt sein? Falsch! Denn wenn du dich darauf verlässt, dann sendet der Angreifer dir 10 MB und verschachtelt eben 40 Level um Heap- oder Stacküberläufe zu provozieren. Wenn es solche Grenzen gibt, dann muss der Parser diese permanent überwachen und sofort abbrechen, wenn eine davon überschritten wird.
  • Wenn ich deinem Parser zufälligen Datenmüll sende, dann darf das zu keinen Problem führen. Es muss dem Parser komplett egal sein, was man ihn schickt. Er muss erkennen, dass etwas nicht stimmt, dass die Daten nicht zu den Vorgaben passen oder eben Standards verletzen und dann sofort den Vorgang mit einem Fehler abbrechen und die Daten verwerfen.
  • Vor jedem Speicherzugriff, also bevor der Parser irgendwas ließt oder schreibt, egal was, egal von wo, egal wohin, muss er immer erst einmal prüfen, ob er das tun darf und ob es sicher ist das zu tun. Würde er dabei über die Grenzen eines Speicherblocks hinaus lesen oder schreiben? Sofortiger Abbruch und Daten verwerfen. Würde er dabei mehr Daten lesen oder Schreiben als an dieser Stelle normal wäre? Sofortiger Abbruch.
  • Der Parser muss zu jedem Zeitpunkt, seinen internen Status im Auge behalten. Wenn z.B. etwas rekursiv oder iterativ implementiert ist, muss er zu jedem Zeitpunkt im Blick haben, wie oft er schon in diese Rekursion gelaufen oder diese Schleife wiederholt hat. Dafür muss es auf jeder Ebene Zähler geben und es muss Obergrenzen geben, die zum sofortigen Abbruch führen, wenn einer dieser Zähler so eine Grenze erreicht, da die Grenzen so hoch festgelegt wurden, dass sie mit validen Daten nie erreicht werden können und solange der Parser unter diesen Grenzen bleibt, garantiert nichts schief laufen kann.

Fast alle Sicherheitslücken durch Parserfehler, die ich mir in den letzten 10 Jahren angeschaut habe, waren nur möglich, weil eine der oben genannten Regel sträflich außer acht gelassen wurde. Da war nicht ein kleiner Bug oder da hat sich jemand vertippt, es wurde einfach nicht gemacht. Da war kein Code, der das hätte machen können. Nur bei einem ganz kleinen Teil der Lücken wollte man alles richtig machen, hat es aber trotzdem verbockt, weil man einen von zwei typischen Programmierfehlern begangen hat:

  • Zu große und damit viel zu komplexe Funktionen. Eine Funktion sollte einfach sein, möglichst wenig Code besitzen und nur genau eine Sache tun. Sobald eine Funktion in Unterfunktionen aufgeteilt werden kann, sollte man das auch immer tun (das können Entwicklungsumgebungen heute sogar schon automatisch). Denn ist eine Funktion nur 5 Zeilen groß, dann ist es leicht zu erfassen was sie macht und ob sie das für alle Eingabedaten auch richtig machen wird. Aber praktisch kein Mensch kann das bei einer Funktion mit 300 Zeilen Code noch sagen. Das schafft höchstens noch ein Analysetool und auch das kann sich mal irren. Das Zauberwort hier heißt SRP.
  • Und der Grund warum die Funktionen oft so groß sind ist der zweite Fehler: Premature Optimization. Weil man annahm, es ist zu teuer, wenn die Implementierung zwischen 30 Funktionen hin und her springt, hat man alles in eine Funktion gepackt. Aber diese Annahme basiert nicht auf Fakten. Compiler vereinen von sich aus diese 30 Funktionen zu einer, wenn sie keinen sinnvollen Grund sehen, warum das einzelne Funktion sein müssen im Endprodukt. Auch führt PO oft dazu, dass eben Tests weggelassen wurden, weil man annahm, dass man das hier nicht testen muss, da das ja bereits weiter oben schon getestet wurde bzw. aufgrund andere Fakten, dieser Test hier nie anschlagen kann und um nicht unnötig oder mehrfach zu testen, hat man sich die Tests gespart. Nur hat man dabei manchmal Randfälle übersehen oder der Code hat wirklich mal weiter oben getestet, aber irgendwer hat dann später den Test oben entfernt, ohne zu wissen, dass Code weiter unten sich auf den verlässt. Und auch hier ist die Annahme falsch, denn die meisten Tests sind zum einen so billig (auch weil CPUs Sprungvorhersagen machen), dass es fast keinen Unterschied macht, selbst wenn man alles 10x testet, und zum anderen erkennen Compiler auch viele unnötige Tests und werfen die sowieso am Ende raus (lassen sie aber später drinnen, wenn sie durch einen Änderung auf einmal doch nötig werden).

Davon ab muss immer das KISS Prinzip gelten. Halte den Code, das Datenformat und den Programmablauf so einfach wie nur irgendwie möglich! Wann immer du nicht auf die einfachste der Möglichkeiten zurück greifst, musst du diese Entscheidung rechtfertigen können. Warum kann es nicht die einfachste sein? Wenn es dafür einen nachvollziehbaren Grund gibt, in Ordnung, aber in mehr als 9 von 10 Fällen sind Dinge einfach komplex und sie sind es völlig grundlos, weil dadurch rein gar nichts gewonnen wird.

Das ist mein Hauptkritikprunk an Matrix gegenüber Signal. Der gesamte Matrix Protokoll Stack ist locker 10x komplexer als der von Signal. Das Signal Protokoll ist maximal einfach gehalten und die Implementierung ist winzig im Vergleich zu Matrix (das komplette Signal Protokoll ist kleiner als bei Matrix die Middleware, auf die das Matrixprotokoll dann überhaupt erst aufbaut). Aber mehr Komplexität heißt nur mehr Angriffsfläche für Hacker und das ohne Mehrwert, denn abgesehen davon dass Matrix ein vielfaches an CPU Zeit und Arbeitsspeicher verschlingt, kann es nichts, dass das Singal nicht auch kann oder das man Signal nicht problemlos leicht beibringen könnte. Denn statt wie die Signal Entwickler einen maßgeschneiderten Protokoll zu entwerfen, wurde einfach alles auf bestehende komplexen Protokolle und Datenformate aufgebaut, die für sich alleine aber schon diverse Probleme mit der Sicherheit in der Vergangenheit hatten und somit ein Monsterstack geschaffen.

Und was ich hier im Diagramm sehen, hat Apple genau den gleichen Fehler begangen, was sie jetzt zu diesem komplexen Ablauf zwing, weil sie das Monster anders nicht mehr in den Griff bekommen, denn den Stack ändern ist nicht möglich, ohne die Abwärtskompatibilität komplett aufzugeben.
+2
sierkb30.01.21 12:30
MTN
Apple entwickelte BlastDoor in Swift, um Speichermanagement-Fehler möglichst zu vermeiden.

This! Das ist DER Hauptgrund, warum es Swift überhaupt gibt und warum sie das nicht mit C oder einem C-Derivat wie Objective-C machen. Grund: Sichereres Programmieren, weniger Speicher-Lecks, weniger Sicherheitslücken.

Weil:

GammaTech: Memory Safety Issues Are Still the Leading Source of Security Vulnerabilities

ZDNet (11.02.2019): Microsoft: 70 percent of all security bugs are memory safety issues
Percentage of memory safety issues has been hovering at 70 percent for the past 12 years.

Microsoft Security Response Center (MSRC) (18.07.2019): We need a safer systems programming language

Microsoft Security Response Center (MSRC) (16.07.2019): A proactive approach to more secure code

The Programming Languages Enthusiast (13.08.2018): Software Security is a Programming Languages Issue

Das hat nicht nur Microsoft schon längst erkannt und steuert um. Sondern u.a. auch Intel (). Und Google. Und Mozilla. Und einige Andere (u.a. auch Amazon). Sondern eben auch Apple. Deswegen gibt es von Apple die Nicht-C-Sprache Swift, deswegen gibt es von Mozilla die Nicht-C-Sprache Rust, deswegen gibt es von Google die Nicht-C-Sprache Go.
-1
MacBlack
MacBlack30.01.21 19:46
Mecki
Ich sehe den Aufwand nur bedingt als gerechtfertigt. Egal ob es um das Parsen von Plisten, XML oder Unicode geht, man kann grundsätzliches alles sicher parsen, wenn man dabei nur eine Hand voll ganz einfachen Regeln befolgt:
...

Und was ich hier im Diagramm sehen, hat Apple genau den gleichen Fehler begangen, was sie jetzt zu diesem komplexen Ablauf zwing, weil sie das Monster anders nicht mehr in den Griff bekommen, denn den Stack ändern ist nicht möglich, ohne die Abwärtskompatibilität komplett aufzugeben.

Danke für deine ausführlichen Erläuterungen!
Ich als Laie freue mich immer, wenn ich ein wenig dazulernen kann.
0
macuser11
macuser1131.01.21 05:29
Mecki
...man kann grundsätzliches alles sicher parsen, wenn man dabei nur eine Hand voll ganz einfachen Regeln befolgt:
-1

Kommentieren

Sie müssen sich einloggen, um die News kommentieren zu können.