it-swarm.com.de

Wie ist der Heartbleed-Exploit überhaupt möglich?

Ich habe über die Heartbleed OpenSSL-Sicherheitsanfälligkeit gelesen und verstehe das Konzept. Was ich jedoch nicht verstehe, ist der Teil, in dem wir 64 KB als Länge übergeben und der Server 64 KB zufällige Daten zurückgibt, da nicht geprüft wird, ob wir wirklich 64 KB Echomeldung oder 1 Byte übergeben haben.

Aber wie ist es überhaupt möglich, dass ein Prozess auf einem Server 64 KB zufällige Daten aus dem RAM zurückgibt?

Soll das Betriebssystem nicht den Zugriff auf den realen RAM] verhindern und nur den Zugriff auf den virtuellen Speicher zulassen, wenn ein Prozess nicht auf den Speicherinhalt anderer Prozesse zugreifen kann?

Läuft OpenSSL im Kernel-Modus und hat somit Zugriff auf den gesamten RAM?

Ich würde einen Segmentierungsfehler erwarten, wenn ein Prozess versuchen würde, auf einen Speicher zuzugreifen, den er nicht explizit zugewiesen hat. Ich kann verstehen, dass 64 KB zufällige Daten von dem Prozess abgerufen werden, auf dem das OpenSSL-Programm selbst ausgeführt wird, aber ich sehe nicht, wie es überhaupt das vollständige RAM des Servers sehen kann, um es senden zu können) zurück zum Kunden.

PDATE : @ paj28s Kommentar, ja, genau die falschen Informationen haben mich dazu gebracht, mich darüber zu wundern. Wie Sie sagten, formuliert es sogar das offizielle Gutachten von heartbleed.com auf irreführende Weise (obwohl ich sagen würde, dass sie dies getan haben, weil es für ein viel breiteres Publikum als nur uns Techniker gedacht ist und sie es einfach halten wollten).

Als Referenz ist hier, wie heartbleed.com es ausdrückt (Hervorhebung von mir):

Der Heartbleed-Fehler ermöglicht es jedem im Internet, den Speicher der Systeme zu lesen durch die anfälligen Versionen der OpenSSL-Software zu schützen.

Für jede technische Person, die das vollständige RAM der virtuellen/physischen Maschine) implizieren würde.

126
Talha Sayed

Der Kommentar von @ paj28 deckt den Hauptpunkt ab. OpenSSL ist eine gemeinsam genutzte Bibliothek und wird daher im selben Adressraum im Benutzermodus ausgeführt wie der Prozess, der sie verwendet. Es kann das Gedächtnis eines anderen Prozesses überhaupt nicht sehen; alles, was etwas anderes vorschlug, war falsch.

Der von OpenSSL verwendete Speicher - wahrscheinlich in der Nähe des Puffers, aus dem Heartbleed überliest - ist jedoch voller vertraulicher Daten. Insbesondere ist es wahrscheinlich, dass es sowohl den Chiffretext als auch den Klartext aller jüngsten oder bevorstehenden Übertragungen enthält. Wenn Sie einen Server angreifen, bedeutet dies, dass Sie Nachrichten sehen, die von anderen an den Server gesendet wurden, und Serverantworten auf diese Nachrichten. Dies ist eine gute Möglichkeit, Sitzungstoken und private Informationen zu stehlen, und Sie werden wahrscheinlich auch die Anmeldeinformationen von jemandem abrufen. Andere von OpenSSL gespeicherte Daten umfassen symmetrische Verschlüsselungsschlüssel (für die Verschlüsselung und Integrität von Massendaten über TLS) und private Schlüssel (zum Nachweis der Identität des Servers). Ein Angreifer, der diese stiehlt, kann die gefährdete TLS-Kommunikation in Echtzeit abhören (und sogar ändern) oder sich erfolgreich als Server ausgeben (unter der Annahme einer Man-in-the-Middle-Position im Netzwerk).

Nun, es gibt eine seltsame Sache an Heartbleed, die es schlimmer macht, als Sie vielleicht erwarten. Normalerweise besteht eine gute Chance, dass Sie beim Versuch, 64 KB Daten ausgehend von einer beliebigen Heap-Adresse innerhalb eines Prozesses zu lesen, auf eine nicht zugewiesene Speicheradresse stoßen (virtueller Speicher, der durch nichts gesichert und daher unbrauchbar ist) schnell. Diese Lücken in einem Prozessadressraum sind ziemlich häufig, denn wenn ein Prozess Speicher freigibt, den er nicht mehr benötigt, fordert das Betriebssystem diesen Speicher zurück, damit andere Prozesse ihn verwenden können. Wenn Ihr Programm nicht wie ein Sieb Speicher verliert, befinden sich normalerweise nicht so viele Daten im Speicher, wie derzeit verwendet werden. Der Versuch, nicht zugewiesenen Speicher zu lesen (z. B. der Versuch, auf freigegebenen Speicher zuzugreifen), führt zu einer Verletzung des Lesezugriffs (unter Windows)/Segmentierungsfehler (unter * nix), wodurch ein Programm abstürzt (und abstürzt, bevor dies möglich ist) so etwas wie Daten zurückschicken). Das ist immer noch ausnutzbar (als Denial-of-Service-Angriff), aber bei weitem nicht so schlimm, als würde der Angreifer all diese Daten abrufen.

Mit Heartbleed stürzte der Prozess fast nie ab. Es stellt sich heraus, dass OpenSSL, das anscheinend entscheidet, dass die Speicherverwaltungsbibliotheken der Plattform zu langsam waren (oder so; ich werde nicht versuchen, diese Entscheidung zu rechtfertigen), eine große Menge an Speicher vorab zuweist und dann seine eigenen Speicherverwaltungsfunktionen verwendet innerhalb dessen. Dies bedeutet ein paar Dinge:

  • Wenn OpenSSL Speicher "freigibt", wird er für das Betriebssystem nicht freigegeben, sodass der Speicher für den Prozess weiterhin verwendet werden kann. Der interne Speichermanager von OpenSSL könnte denken, dass der Speicher nicht zugewiesen ist, aber was das Betriebssystem betrifft, besitzt der OpenSSL-Verwendungsprozess diesen Speicher weiterhin.
  • Wenn OpenSSL Speicher "freigibt", behält dieser Speicher alle Werte bei, die er vor dem "Freigeben" hatte, es sei denn, er löscht die Daten explizit vor dem Aufrufen seiner Funktion free. Dies bedeutet, dass viele Daten gelesen werden können, die noch nicht verwendet werden.
  • Der von OpenSSL verwendete Speicherheap ist zusammenhängend. In Bezug auf das Betriebssystem gibt es keine Lücken. Es ist daher sehr unwahrscheinlich, dass das Überlesen des Puffers auf eine nicht zugewiesene Seite stößt, sodass ein Absturz nicht wahrscheinlich ist.
  • Die Speichernutzung von OpenSSL hat eine sehr hohe Lokalität - das heißt, sie konzentriert sich auf einen relativ kleinen Adressbereich (den vorab zugewiesenen Block) - und wird nicht nach Lust und Laune des OS-Speicherzuweisers über den Adressraum verteilt. Wenn Sie also 64 KB Speicher lesen (was selbst neben dem typischen 2-GB-Bereich eines 32-Bit-Prozesses nicht viel ist, geschweige denn der enorme Bereich eines 64-Bit-Prozesses), werden wahrscheinlich viele Daten abgerufen Derzeit (oder vor kurzem) verwendet, obwohl sich diese Daten im Ergebnis einer Reihe von angeblich getrennten Zuordnungen befinden.
209
CBHacking

Ich würde einen Segmentierungsfehler erwarten, wenn ein Prozess versuchen würde, auf einen Speicher zuzugreifen, den er nicht explizit zugewiesen hat

Hier liegt das Missverständnis.

Jeder unterbrochene Speicherzugriff könnte zu einem Segmentierungsfehler führen. Wenn die angeforderte Speicheradresse jedoch im Adressraum des aktuellen Prozesses liegt (z. B. eine gerade freigegebene Variable), ist dies höchst unwahrscheinlich.

Deshalb sollten Sie sich nicht auf Segmentierungsfehler verlassen, um Speicherzugriffsfehler zu finden!