Zum Inhalt springen

Services, Wiki-Artikel, Blog-Beiträge und Glossar-Einträge durchsuchen

↑↓NavigierenEnterÖffnenESCSchließen
Schwachstellenklassen Glossar

Memory Safety - Speichersicherheits-Schwachstellen

Memory-Safety-Schwachstellen entstehen in Sprachen ohne automatisches Speichermanagement (C/C++) durch fehlerhafte manuelle Speicherverwaltung. Hauptklassen: Buffer Overflow (Stack/Heap), Use-After-Free, Double-Free, Integer Overflow, Format String. Diese Klasse verantwortet historisch ~70% aller schwerwiegenden CVEs in grossen Softwareprojekten (Microsoft, Google). Schutz: Memory-Safe-Languages (Rust, Go), AddressSanitizer, Stack Canaries, ASLR, DEP/NX.

Memory-Safety-Schwachstellen sind eine Klasse von Bugs in systemnaher Software (C, C++, Assembly) die entstehen wenn ein Programm auf Speicher zugreift der nicht für es bestimmt ist. Microsoft berichtete dass ~70% aller CVEs in Windows-Produkten auf Memory-Safety-Fehler zurückgehen. Google Chrome: ähnliche Zahlen. Diese Schwachstellen sind besonders gefährlich weil sie oft zu Remote Code Execution (RCE) führen.

Schwachstellen-Klassen

Buffer Overflow (Stack-basiert)

// Klassisches Beispiel:
void unsafe_copy(char* user_input) {
  char buffer[64];
  strcpy(buffer, user_input);  // KEINE Längenprüfung!
}
// Bei Input > 64 Bytes: überschreibt Return-Adresse!
// Angreifer kontrolliert wohin Funktion zurückspringt → Code-Execution!

Exploitierung:

  1. Buffer mit Angreifer-Payload füllen: Shellcode oder ROP-Chain
  2. Return-Adresse auf Shellcode zeigen
  3. Funktion kehrt zurück → springt in Angreifer-Code → RCE

Moderne Gegenmaßnahmen:

  • Stack Canaries: zufälliger Wert zwischen Buffer und Return-Adresse - wenn überschrieben, bricht das Programm ab
  • ASLR: Adressen werden zufällig vergeben, Angreifer kennt Shellcode-Adresse nicht
  • NX/DEP: Stack ist nicht ausführbar, Shellcode kann nicht ausgeführt werden → ROP erforderlich

Heap Buffer Overflow

// Speicher auf dem Heap überschreiben:
char* buf = malloc(64);
memcpy(buf, user_data, user_len);  // user_len > 64 → Overflow!
// → Überschreibt Heap-Metadaten → Allocator kompromittiert → Exploit

Use-After-Free (UAF)

// Speicher freigeben, dann noch nutzen:
char* ptr = malloc(100);
free(ptr);
ptr[0] = 'A';   // UNDEFINED BEHAVIOR! ptr ist dangling pointer!

Exploitierung:

  1. Objekt A wird allokiert (ptr_a) → Free von A
  2. Angreifer sorgt dafür dass Objekt B den ptr_a-Speicher erhält
  3. Alt-Code nutzt ptr_a noch → liest/schreibt in B
  4. Type Confusion → Angreifer kontrolliert B’s Inhalt → Exploit

UAF ist eine der häufigsten Browser-Exploit-Klassen. In Chrome sind ~70% der High-Severity CVEs UAF-basiert.

Double-Free

// Speicher zweimal freigeben:
char* ptr = malloc(100);
free(ptr);
// ... code ...
free(ptr);   // Double-Free! Heap-Korruption!
// → Modifiziert Heap-Allocator-Strukturen
// → Kann zu UAF oder Arbitrary Write führen

Integer Overflow

// Überlauf bei Integer-Arithmetik:
int size = user_provided_size * 2;  // Wenn size = MAX_INT/2: Overflow → 0!
char* buf = malloc(size);
memcpy(buf, user_data, user_provided_size * 2);  // zu wenig Buffer!
// → Buffer-Overflow trotz malloc!

// Reales Beispiel: libpng Längen-Berechnungen
uint16_t width, height;  // 16-Bit
int total = width * height * 4;  // Overflow wenn > 65535x65535!

Format String Schwachstelle

printf(user_input);  // NIEMALS! Nur printf("%s", user_input)!
// → Bei user_input = "%x %x %x %x": Stack-Werte ausgegeben!
// → Bei user_input = "%n": schreibt in Speicher!
// → Beliebiger Speicher-Lese- und Schreibzugriff!

// RICHTIG:
printf("%s", user_input);  // %s als Formatstring, Input als Argument

Schutzmaßnahmen auf Compiler/OS-Ebene

Stack Canaries (GCC/Clang)

gcc -fstack-protector-strong app.c

Zufälliger Wert zwischen lokalen Variablen und Return-Adresse. Beim Funktionsrückgabe wird der Canary geprüft - wenn überschrieben, bricht das Programm ab (Stack-Smashing-Protection).

ASLR (Address Space Layout Randomization)

Das OS randomisiert Stack, Heap, Libraries und PIE-Binary-Base. Angreifer kennt Adressen nicht, Sprünge scheitern.

# Linux:
sysctl kernel.randomize_va_space=2  # volle Randomisierung
# Windows: ASLR im Security Center aktiviert (Standard)

ASLR-Bypass erfordert: Information Leak + ROP-Chain.

NX/DEP (No-Execute / Data Execution Prevention)

Speicherbereiche werden als nicht-ausführbar markiert. Stack und Heap sind Data-Bereiche - Shellcode kann nicht ausgeführt werden.

gcc -Wl,-z,noexecstack

Umgehung: ROP (Return-Oriented Programming).

PIE (Position Independent Executable)

gcc -fPIE -pie app.c

Die Binary-Base wird ebenfalls randomisiert (nicht nur Libraries). Vollständiges ASLR ist erst mit PIE möglich.

RELRO (RELocation Read-Only)

gcc -Wl,-z,relro,-z,now app.c

Die GOT (Global Offset Table) wird nach dem Laden read-only gesetzt. GOT-Overwrite-Angriffe werden dadurch verhindert.

AddressSanitizer (Entwicklungs-/Testphase)

gcc -fsanitize=address,undefined app.c

Instrumentiert alle Speicher-Zugriffe. Buffer Overflow, UAF, Double-Free führen zu sofortigem Absturz mit Fehlermeldung. Performance-Overhead: ~2x - nur für Testing/Fuzzing, nicht für Produktion.

# MemorySanitizer (für uninitialisierte Reads):
clang -fsanitize=memory app.c

Control Flow Integrity (CFI)

clang -fsanitize=cfi app.c

Stellt sicher dass indirekte Sprünge nur zu gültigen Zielen führen. Erschwert ROP-Angriffe erheblich. Aktiviert in Chrome, Windows (Microsoft CET).

Memory-Safe-Languages

Rust - Memory-Safety ohne Garbage Collector

Das Ownership-System des Compilers verhindert UAF, Double-Free und Buffer-Overflow. Zero-Cost-Abstractions liefern die gleiche Performance wie C/C++. NSA, CISA und das Weiße Haus empfehlen Memory-Safe-Languages (2023/2024).

fn safe_access(v: &Vec<i32>, idx: usize) -> Option<&i32> {
    v.get(idx)  // Bounds-Check! Gibt None zurück wenn out-of-bounds
}
// KEIN Buffer-Overflow möglich durch safe Rust-Code!
// unsafe{}-Block: nötig für FFI/System-Code, explizit markiert

Adoption von Rust:

  • Linux-Kernel: Rust als zweite Sprache seit Kernel 6.1
  • Android: Rust für neue Kernel-Komponenten (UAF drastisch reduziert)
  • Windows: Rust für neue sicherheitskritische Komponenten
  • Google: 70% weniger Memory-Safety-Bugs bei Android-Rust-Code

Go - Sicher, aber mit Garbage Collector

  • Garbage Collector verhindert UAF und Double-Free
  • Bounds-Checks automatisch
  • Performance geringer als C, aber deutlich höher als Python
  • Trade-off: GC-Pausen, aber sichere Speicherverwaltung

Python / Java / JavaScript - vollständig GC-verwaltet

  • Speicherverwaltung vom Runtime übernommen
  • Native Extensions (C-Erweiterungen) können unsicher sein
  • Python-C-Extensions (numpy, scipy) sind potenziell memory-unsafe

Empfehlung

  • Neuprojekte mit Performance-Anforderungen: Rust bevorzugen
  • Bestehende C/C++-Codebasis: schrittweiser Rust-Rewrite für kritische Teile
  • Alle C/C++-Projekte: ASAN/Fuzzing in CI/CD ist Pflicht

Cookielose Analyse via Matomo (selbst gehostet, kein Tracking-Cookie). Datenschutzerklärung