Post by Carsten ThumullaMan legt in Pascal
üblicherweise Strings ab,
Nö. Bytearrays werden auch benutzt und sie haben in bestimmten Situationen
sogar Vorteile, z. B. dann, wenn ihr Inhalt eben kein String ist.
Post by Carsten Thumullaund die haben eine Länge, und da gibt es
Kontrollen.
Man kann in Pascal durchaus einen nicht initialisierten String erzeugen. Der
hat zwar die angeforderte Länge, enthält aber zunächst nur Kauderwelsch.
Post by Carsten ThumullaNimmt man etwas entgegen, dann hat das eine Länge und Man greift
nicht in die Wüste dahinter.
Du hast offenbar immer noch nicht verstanden: in meinem Beispiel wird nicht
"in die Wüste gegriffen", sondern nur auf den reservierten Speicherbereich
einer ordnungsgemäß deklarierten Variablen. Nur ist die halt nicht
initialisiert und enthält daher nur undefinierte Werte.
Der Zugriff auf den Speicherbereich einer Variablen ist übrigens in allen
Programmiersprachen völlig alltäglich. Schließlich werden die Variablen ja
deswegen deklariert, damit man etwas damit machen kann. Man darf halt nur die
Initialisierung nicht vergessen.
Post by Carsten ThumullaWenn das Programm selbst den Speicher füllt, dann hat es die Länge der
empfangenen Daten.
Das tut der Heartbeat-Code ja. Er empfängt Daten (eine Payload) und schreibt
die in den dafür vorgesehenen Puffer.
Zusätzlich zur Payload wird auch eine Größeninformation übertragen. Diese
Größeninformation wird aber offenbar beim *Beschreiben* des Puffers nicht
genutzt. Begründung: der Exploit basiert darauf, eine sehr kleine Payload in
Verbindung mit der maximalen Puffergröße als Größeninformation zu übermitteln.
Damit soll der Server veranlasst werden, nicht nur die Payload, sondern den
gesamten Pufferinhalt als Antwort zurückzuschicken. Damit das funktioniert,
ist der Exploit darauf angewiesen, dass der nicht von der Payload belegte
Speicher unangetastet bleibt. Das scheint auch tatsächlich der Fall gewesen zu
sein. Der Heartbeat-Code hat also beim Beschreiben des Puffers nicht die
(absichtlich falsche) Größeninformation genutzt (andernfalls hätte er den
Puffer komplett mit unbrauchbaren Daten gefüllt), sondern die tatsächliche
Größe der Payload auf andere Art ermittelt. Man kann also davon ausgehen, dass
dem Code die Größe der Payload bekannt gewesen sein muss.
Dummerweise hat der Code die ihm bekannte Payload-Größe beim Generieren der
Antwort nicht mehr berücksichtigt, sondern stattdessen die mitübertragene
Größeninformation, die im Falle des Exploits gleichbedeutend mit der
Puffergröße war. Es fand offenbar auch kein Vergleich zwischen
Größeninformation und tatsächlicher Payload-Größe statt, bei der der Fehler
sofort aufgefallen wäre. Stattdessen wurde ungeprüft der gesamte Puffer incl.
der uninitialisierten Daten ausgelesen und aus diesen die Antwort erzeugt.
Danach musste der Angreifer nur noch den uninitialisierten Teil der Antwort
nach für ihn nützlichen Informationen durchsuchen. Da OpenSSL einen eigenen
Speicherbereich für die Verschlüsselung verwendet, der sonst von keinem
anderen Prozess genutzt wird, ist die Wahrscheinlichkeit, dort
verschlüsselungs-relevante Daten zu finden, relativ hoch.
Gruß
Michael