Verwendung nach Freigabe
Beschreibung
Verwendung nach Freigabe (Use After Free, UAF) ist eine Schwachstelle, die auftritt, wenn Software einen Pointer weiterhin verwendet, nachdem der Speicher, auf den er verweist, freigegeben wurde. Sobald Speicher freigegeben ist, kann er für andere Zwecke neu allokiert werden. Wenn der hängende Pointer anschließend dereferenziert wird, kann das Programm Speicher lesen oder beschreiben, der jetzt für andere Datenstrukturen verwendet wird, was zu Datenkorruption, Informationsoffenlegung oder Codeausführung führt. Use-After-Free-Schwachstellen sind besonders verbreitet in komplexen Anwendungen mit manueller Speicherverwaltung, einschließlich Browsern, Dokumentenparsern und Betriebssystem-Kerneln.
Risiko
Use-After-Free-Schwachstellen sind hochgradig ausnutzbar und rangieren konstant unter den gefährlichsten Software-Schwachstellen. Angreifer nutzen Heap-Manipulationstechniken, um zu kontrollieren, welche Daten den freigegebenen Speicher belegen, wenn der hängende Pointer dereferenziert wird. Durch Platzierung von angreifergesteuerten Objekten (die Funktionszeiger oder vtables enthalten) im freigegebenen Speicherbereich wird Codeausführung erreicht, wenn der veraltete Pointer verwendet wird. Browser sind häufige Ziele aufgrund komplexer JavaScript/DOM-Interaktionen, die Race Conditions und Speicherverwaltungsfehler erzeugen. UAF-Fehler haben zahlreiche browserbasierte Angriffe, Privilegieneskalations-Exploits und Malware-Kampagnen ermöglicht.
Lösung
Implementieren Sie strikte Besitzsemantik und Lebenszyklusverwaltung für allokierten Speicher. Verwenden Sie Smart Pointer (std::unique_ptr, std::shared_ptr in C++), die Speicher automatisch verwalten und hängende Referenzen verhindern. Setzen Sie Pointer unmittelbar nach der Freigabe auf NULL. Verwenden Sie speichersichere Sprachen (Rust mit Ownership-System, Go mit Garbage Collection). Aktivieren Sie AddressSanitizer während der Entwicklung, um UAF zu erkennen. Implementieren Sie Referenzzählung für gemeinsam genutzte Objekte. Vermeiden Sie nach Möglichkeit das Speichern von rohen Zeigern auf Heap-Objekte. Führen Sie gründliche Code-Reviews von Speicherallokations-/Freigabemustern durch.
Häufige Auswirkungen
| Auswirkung | Details |
|---|---|
| Zugriffskontrolle | Umfang: Codeausführung Angreifer platzieren bösartige Objekte im freigegebenen Speicher; das Dereferenzieren beschädigter vtables oder Funktionszeiger ermöglicht beliebige Codeausführung. |
| Integrität | Umfang: Integrität Das Schreiben durch hängende Pointer beschädigt unzusammenhängende Datenstrukturen, die jetzt den freigegebenen Speicher belegen. |
| Vertraulichkeit | Umfang: Vertraulichkeit Das Lesen durch hängende Pointer kann sensible Daten offenlegen, die im neu allokierten Speicher gespeichert sind. |
Beispielcode
Anfälliger Code
// ANFÄLLIG: Verwendung nach Freigabe
struct User {
char *name;
void (*callback)(void);
};
void vulnerable_function() {
struct User *user = malloc(sizeof(struct User));
user->name = strdup("admin");
user->callback = normal_callback;
// ... einige Operationen ...
free(user); // Speicher freigegeben
// ... mehr Code ...
// UAF: user-Pointer nach Freigabe weiterhin verwendet
user->callback(); // Wenn Angreifer freigegebenen Speicher kontrolliert, beliebige Ausführung
}
// ANFÄLLIG: Doppelte Freigabe führt zu UAF
void double_free_uaf(char *ptr) {
free(ptr);
// ... Code der möglicherweise allokiert und ptrs Speicher wiederverwendet ...
free(ptr); // Doppelte Freigabe - kann UAF oder Heap-Korruption verursachen
}
Korrigierter Code
#include <stdlib.h>
// SICHER: Pointer nach Freigabe auf NULL setzen
void safe_function() {
struct User *user = malloc(sizeof(struct User));
if (!user) return;
user->name = strdup("admin");
user->callback = normal_callback;
// Ordnungsgemäße Bereinigung
free(user->name);
user->name = NULL;
free(user);
user = NULL; // Verwendung nach Freigabe verhindern
// Jede nachfolgende Verwendung von user wird NULL-Dereferenzierung sein (Absturz, kein Exploit)
}
// SICHER: Referenzzählung verwenden
struct RefCountedUser {
int ref_count;
char *name;
};
void release_user(struct RefCountedUser **user_ptr) {
if (*user_ptr && --(*user_ptr)->ref_count == 0) {
free((*user_ptr)->name);
free(*user_ptr);
}
*user_ptr = NULL;
}
// BESTE LÖSUNG: C++ Smart Pointer
#include <memory>
class User {
public:
std::string name;
std::function<void()> callback;
};
void safe_cpp_function() {
auto user = std::make_unique<User>();
user->name = "admin";
// unique_ptr automatisch freigegeben wenn außerhalb des Gültigkeitsbereichs
// Kein hängender Pointer möglich
}
Ausgenutzt in der Praxis
Chrome Zero-Days (Chrome, fortlaufend)
Mehrere Use-After-Free-Schwachstellen in Chrome wurden in freier Wildbahn ausgenutzt, einschließlich CVE-2022-0609, CVE-2022-1096 und CVE-2022-2294. Diese Fehler in verschiedenen Chrome-Komponenten ermöglichten Remote-Codeausführung durch bösartige Webseiten.
Windows Win32k UAF (Windows, mehrfach)
CVE-2021-1732 und zahlreiche andere Use-After-Free-Schwachstellen in der Windows win32k-Kernel-Komponente wurden für lokale Privilegieneskalation von APT-Gruppen und Ransomware-Betreibern ausgenutzt.
Tools zum Testen/Ausnutzen
-
AddressSanitizer — Laufzeit-UAF-Erkennung mit detaillierten Berichten.
-
Valgrind — erkennt Verwendung von freigegebenem Speicher.
-
UBSan — Undefined-Behavior-Sanitizer, der UAF-Muster erkennt.
CVE-Beispiele
-
CVE-2022-0609 — Chrome Animation UAF in freier Wildbahn ausgenutzt.
-
CVE-2021-1732 — Windows win32k UAF für Privilegieneskalation.
-
CVE-2021-21224 — Chrome V8 Type Confusion führt zu UAF.
Referenzen
-
MITRE. "CWE-416: Use After Free." https://cwe.mitre.org/data/definitions/416.html
-
Project Zero. "A very deep dive into iOS Exploit chains." https://googleprojectzero.blogspot.com/