Buffer Over-read
Beschreibung
Buffer Over-read tritt auf, wenn ein Programm Daten von Speicherstellen jenseits des Endes eines beabsichtigten Puffers liest. Dies geschieht, wenn Array-Indizes, Pointer-Arithmetik oder Längenparameter die allokierte Größe des Puffers ohne ordnungsgemäße Validierung überschreiten. Anders als Buffer Overflows (Schreiboperationen) legen Over-reads primär vertrauliche Informationen offen, anstatt direkte Code-Ausführung zu ermöglichen. Jedoch können geleakte Speicherinhalte kryptografische Schlüssel, Passwörter, Session-Token und Speicheradressen umfassen, die die Ausnutzung anderer Schwachstellen erleichtern. Die Heartbleed-Schwachstelle demonstrierte, dass Buffer Over-reads katastrophale Sicherheitsimplikationen im Internet-Maßstab haben können.
Risiko
Buffer Over-reads stellen schwere Vertraulichkeitsrisiken dar, indem sie sensible Daten aus angrenzenden Speicherbereichen offenlegen. In kryptografischen Implementierungen können sie private Schlüssel und Session-Geheimnisse leaken. In Webservern können sie Authentifizierungsanmeldedaten, Session-Token und persönliche Benutzerdaten über verschiedene Anfragen hinweg offenlegen. Speicheradressen-Offenlegung ermöglicht ASLR-Umgehung und erleichtert nachfolgende Exploitation. Der Heartbleed-Bug (CVE-2014-0160) ermöglichte Angreifern, 64KB Serverspeicher pro Anfrage zu lesen, was geschätzte 17% aller SSL-aktivierten Websites betraf und unzählige private Schlüssel und Anmeldedaten offenlegte. Bruce Schneier beschrieb es als "katastrophal...auf einer Skala von 1 bis 10 ist dies eine 11."
Lösung
Validieren Sie alle Puffer-Leseoperationen gegen allokierte Puffergrößen. Verwenden Sie längengeprüfte Funktionen und übergeben Sie tatsächliche Puffergrößen als Parameter. Implementieren Sie grenzenprüfende Container (std::vector, std::string in C++). Vertrauen Sie niemals benutzerbereitgestellten Längenwerten ohne Validierung gegen tatsächliche Datengrößen. Verwenden Sie das Minimum aus behaupteter Länge und tatsächlicher Puffergröße für Kopieroperationen. Aktivieren Sie AddressSanitizer während der Entwicklung. Erwägen Sie speichersichere Sprachen für sicherheitskritische Datenverarbeitung. Wenden Sie Defense-in-Depth an, indem Sie die Aufbewahrung sensibler Daten im Speicher minimieren.
Häufige Auswirkungen
| Auswirkung | Details |
|---|---|
| Vertraulichkeit | Bereich: Informationsoffenlegung Sensible Daten einschließlich kryptografischer Schlüssel, Passwörter, Session-Token und persönlicher Informationen können aus angrenzendem Speicher offengelegt werden. |
| Zugriffskontrolle | Bereich: Sicherheitsumgehung Geleakte Speicheradressen ermöglichen ASLR-Umgehung und erleichtern die Ausnutzung anderer Schwachstellen. |
| Verfügbarkeit | Bereich: Verfügbarkeit Das Lesen von nicht gemappten Speicherbereichen verursacht Segmentation Faults und Abstürze. |
Beispielcode + Lösungscode
Anfälliger Code
#include <string.h>
#include <stdlib.h>
// ANFÄLLIG: Heartbleed-artiges Over-read
void send_heartbeat(char *payload, size_t claimed_length) {
char response[65536];
// Vertraut benutzerbereitgestellter Länge ohne Validierung
// Wenn claimed_length > tatsächliche Payload, liest angrenzenden Speicher
memcpy(response, payload, claimed_length);
send_to_client(response, claimed_length); // Leakt Speicher
}
// ANFÄLLIG: Over-read über ungeprüften Index
char get_char_at(char *buffer, int index) {
// Keine Grenzenprüfung - kann über Puffer hinaus lesen
return buffer[index];
}
// ANFÄLLIG: String-Operation Over-read
void process_packet(char *packet, size_t packet_len) {
char type[32];
// strcpy liest bis Null-Terminator
// Wenn Paket nicht null-terminiert, liest über packet_len hinaus
strcpy(type, packet);
}
Korrigierter Code
#include <string.h>
#include <stdlib.h>
#include <stdint.h>
// SICHER: Länge gegen tatsächliche Daten validieren
void send_heartbeat_safe(const char *payload, size_t actual_len,
size_t claimed_length) {
char response[65536];
// Minimum aus behaupteter und tatsächlicher Länge verwenden
size_t copy_len = claimed_length < actual_len ? claimed_length : actual_len;
// Auch gegen Response-Puffergröße prüfen
if (copy_len > sizeof(response)) {
copy_len = sizeof(response);
}
memcpy(response, payload, copy_len);
send_to_client(response, copy_len);
}
// SICHER: Grenzengeprüfter Pufferzugriff
int get_char_at_safe(const char *buffer, size_t buffer_size,
size_t index, char *out_char) {
if (index >= buffer_size) {
return -1; // Fehler: außerhalb der Grenzen
}
*out_char = buffer[index];
return 0;
}
// SICHER: Längenbegrenzte String-Kopie
void process_packet_safe(const char *packet, size_t packet_len) {
char type[32];
// strncpy mit explizitem Limit verwenden
size_t copy_len = packet_len < sizeof(type) - 1 ? packet_len : sizeof(type) - 1;
memcpy(type, packet, copy_len);
type[copy_len] = '\0'; // Null-Terminierung sicherstellen
}
Ausgenutzt in der Praxis
Heartbleed (OpenSSL, 2014)
CVE-2014-0160 war ein Buffer Over-read in OpenSSLs TLS-Heartbeat-Erweiterung, das Angreifern erlaubte, 64KB Serverspeicher pro Anfrage zu lesen. Die Schwachstelle betraf 17,5% der SSL-Websites und legte private Schlüssel, Session-Cookies und Benutzeranmeldedaten in massivem Ausmaß offen. Bemerkenswerte Vorfälle umfassten den Diebstahl von 900 kanadischen Sozialversicherungsnummern.
Cloudbleed (Cloudflare, 2017)
Ein Parser-Bug in Cloudflares HTML-Parser verursachte Buffer Over-reads, die sensible Daten aus anderen Kundenanfragen in gecachte Seiten leakten. Geleakte Daten umfassten Passwörter, API-Schlüssel und Authentifizierungs-Token von Millionen von Websites.
CrowdStrike-Ausfall (CrowdStrike, 2024)
Weitreichende IT-Ausfälle, die Millionen von Systemen betrafen, wurden durch einen Out-of-bounds-Speicherlesefehler in CrowdStrikes Falcon-Sensor-Software verursacht und demonstrierten die Verfügbarkeitsauswirkungen von Over-read-Bugs.
Tools zum Testen/Ausnutzen
-
AddressSanitizer — Laufzeiterkennung von Buffer Over-reads mit detaillierten Fehlerberichten.
-
Valgrind — erkennt ungültige Lesezugriffe über Puffergrenzen hinaus.
-
AFL++ / libFuzzer — Fuzzer, die effektiv beim Auslösen von Over-read-Bedingungen durch fehlerhafte Eingaben sind.
CVE-Beispiele
-
CVE-2014-0160 — Heartbleed: OpenSSL TLS-Heartbeat Buffer Over-read.
-
CVE-2017-0143 — Windows SMB Buffer Over-read (Teil von EternalBlue).
-
CVE-2022-0778 — OpenSSL BN_mod_sqrt Endlosschleife, die Over-read-Bedingungen verursacht.
Referenzen
-
MITRE. "CWE-126: Buffer Over-read." https://cwe.mitre.org/data/definitions/126.html
-
Heartbleed.com. "The Heartbleed Bug." https://heartbleed.com/
-
Wheeler, David. "How to Prevent the Next Heartbleed." https://dwheeler.com/essays/heartbleed.html