Falsche Berechnung der Multi-Byte-String-Länge

Beschreibung

Falsche Berechnung der Multi-Byte-String-Länge tritt auf, wenn ein Programm die Länge von Strings, die Wide- oder Multi-Byte-Zeichen enthalten, falsch berechnet. In Zeichencodierungen wie UTF-8, UTF-16 oder verschiedenen asiatischen Zeichensätzen kann ein einzelnes Zeichen durch mehrere Bytes dargestellt werden. Funktionen, die davon ausgehen, dass ein Byte einem Zeichen entspricht (wie strlen() in C für ASCII), produzieren falsche Längen für Multi-Byte-Strings. Diese Fehlberechnung kann zu Buffer Overflows bei der Pufferallokation, Abschneiden von Daten oder Buffer-Over-Reads beim Durchlaufen von Strings führen.

Risiko

Multi-Byte-String-Längenfehlberechnungen sind besonders gefährlich in internationalisierten Anwendungen und Systemen, die Benutzereingaben in verschiedenen Sprachen verarbeiten. Wenn ASCII-zentrische Längenfunktionen auf Multi-Byte-Daten verwendet werden, können Puffer unterdimensioniert sein (was zu Overflow führt) oder Operationen können über beabsichtigte Grenzen hinaus lesen. Diese Schwachstellenklasse trug zu MS08-067 bei, einer der bedeutendsten Windows-Schwachstellen, die vom Conficker-Wurm ausgenutzt wurde. Anwendungen, die UTF-8, UTF-16 oder andere Multi-Byte-Codierungen ohne ordnungsgemäße Längenbehandlung verarbeiten, sind anfällig.

Lösung

Verwenden Sie codierungsbewusste String-Funktionen, die für den zu verarbeitenden Zeichensatz geeignet sind. Für UTF-8 verwenden Sie Funktionen wie mbstowcs(), mbrlen() oder plattformspezifische Alternativen. Unterscheiden Sie bei allen String-Operationen zwischen Byte-Länge und Zeichenanzahl. Bei der Allokation von Puffern für Multi-Byte-Strings berechnen Sie die erforderliche Byte-Größe korrekt. Verwenden Sie wchar_t und Wide-Character-Funktionen für Wide-Character-Strings. Erwägen Sie die Verwendung von Bibliotheken wie ICU (International Components for Unicode) für robuste Unicode-Behandlung. Validieren und normalisieren Sie die Zeichencodierung vor der Verarbeitung.

Häufige Auswirkungen

AuswirkungDetails
IntegritätBereich: Speicherbeschädigung

Unterdimensionierte Pufferallokationen basierend auf falscher Länge führen zu Buffer Overflows während String-Operationen.
VertraulichkeitBereich: Informationsoffenlegung

Over-Reads beim Iterieren über String-Grenzen hinaus legen angrenzende Speicherinhalte offen.
VerfügbarkeitBereich: Denial-of-Service

Speicherbeschädigung durch falsche String-Behandlung verursacht Abstürze und Systeminstabilität.

Beispielcode + Lösungscode

Anfälliger Code

#include <string.h>
#include <stdlib.h>
#include <wchar.h>

// ANFÄLLIG: Verwendet strlen auf potenziell Multi-Byte-String
char *copy_input(const char *input) {
    // strlen zählt Bytes, nicht Zeichen
    // Für UTF-8 kann dies länger als die Zeichenanzahl sein
    size_t len = strlen(input);

    // Allokiert genug Bytes ABER nachfolgende Zeichen-für-Zeichen-
    // Verarbeitung kann andere Größe annehmen
    char *copy = malloc(len + 1);
    strcpy(copy, input);
    return copy;
}

// ANFÄLLIG: Vermischt Byte-Länge und Zeichenanzahl
void truncate_string(wchar_t *dest, const wchar_t *src, size_t max_chars) {
    // Verwendet byte-basierte Funktion auf Wide-Character-String
    // sizeof(wchar_t) kann 2 oder 4 Bytes sein
    strncpy((char *)dest, (char *)src, max_chars);  // FALSCH!
}

// ANFÄLLIG: MS08-067-artiger Pfad-Kanonisierung
void canonicalize_path(char *path) {
    char *ptr = path + strlen(path);

    // Rückwärtsgehen ohne Multi-Byte-Grenzen zu berücksichtigen
    while (ptr > path && *ptr != '\\') {
        ptr--;  // Kann mitten in Multi-Byte-Zeichen landen
    }
    // Weitere Verarbeitung kann Speicher beschädigen
}

Korrigierter Code

#include <string.h>
#include <stdlib.h>
#include <wchar.h>
#include <locale.h>

// SICHER: Ordnungsgemäße Multi-Byte-String-Behandlung
char *copy_input_safe(const char *input) {
    // mbstowcs verwenden, um tatsächliche Zeichen zu zählen wenn nötig
    // Aber strlen ist korrekt für Byte-Allokation
    size_t byte_len = strlen(input);

    char *copy = malloc(byte_len + 1);
    if (copy) {
        memcpy(copy, input, byte_len + 1);
    }
    return copy;
}

// SICHER: Ordnungsgemäße Wide-Character-String-Behandlung
void truncate_wstring_safe(wchar_t *dest, size_t dest_size,
                           const wchar_t *src, size_t max_chars) {
    // Wide-Character-Funktionen verwenden
    size_t src_len = wcslen(src);
    size_t copy_len = src_len < max_chars ? src_len : max_chars;

    // Sicherstellen, dass Ziel nicht überläuft
    if (copy_len >= dest_size) {
        copy_len = dest_size - 1;
    }

    wcsncpy(dest, src, copy_len);
    dest[copy_len] = L'\0';
}

// SICHER: Multi-Byte-bewusste String-Iteration
size_t safe_char_count(const char *str) {
    setlocale(LC_ALL, "");  // Locale für mblen setzen

    size_t count = 0;
    const char *ptr = str;

    while (*ptr) {
        int char_len = mblen(ptr, MB_CUR_MAX);
        if (char_len <= 0) {
            char_len = 1;  // Ungültige Sequenzen behandeln
        }
        ptr += char_len;
        count++;
    }

    return count;
}

// SICHER: UTF-8-bewusste String-Verarbeitung
size_t utf8_char_length(unsigned char c) {
    if ((c & 0x80) == 0) return 1;      // ASCII
    if ((c & 0xE0) == 0xC0) return 2;   // 2-Byte-Sequenz
    if ((c & 0xF0) == 0xE0) return 3;   // 3-Byte-Sequenz
    if ((c & 0xF8) == 0xF0) return 4;   // 4-Byte-Sequenz
    return 1;  // Ungültig, als einzelnes Byte behandeln
}

Ausgenutzt in der Praxis

MS08-067 Conficker-Wurm (Microsoft Windows, 2008)

CVE-2008-4250 war ein Buffer Overflow in der Windows Server Service-Funktion NetPathCanonicalize. Die Schwachstelle beinhaltete falsche Grenzenberechnung während der Pfad-Kanonisierung mit Multi-Byte-Zeichen, was Angreifern ermöglichte, Stack-Schutz zu umgehen und Code-Ausführung zu erreichen. Der Conficker-Wurm nutzte diese Schwachstelle aus, um Millionen von Windows-Systemen zu infizieren.

Unicode-Normalisierungsangriffe (Verschiedene, fortlaufend)

Mehrere Schwachstellen in Webanwendungen und Frameworks entstehen durch inkonsistente Behandlung von Unicode-Normalisierung und Multi-Byte-Zeichenlängen, die WAF-Umgehungen und Injection-Angriffe ermöglichen.


Tools zum Testen/Ausnutzen

  • AddressSanitizer — erkennt Buffer Overflows durch String-Längenfehlberechnungen.

  • AFL++ — Fuzzer mit Unicode-bewussten Mutatoren zum Testen der Multi-Byte-Behandlung.

  • ICU — International Components for Unicode-Bibliothek für sichere Unicode-Behandlung.


CVE-Beispiele

  • CVE-2008-4250 — MS08-067 Windows Server Service RCE über Pfad-Kanonisierung.

  • CVE-2022-24785 — Moment.js Path-Traversal über Locale-Dateibehandlung.

  • CVE-2021-42574 — Unicode bidirektionale Textbehandlung (Trojan Source).


Referenzen

  1. MITRE. "CWE-135: Incorrect Calculation of Multi-Byte String Length." https://cwe.mitre.org/data/definitions/135.html

  2. CERT. "STR38-C. Do not confuse narrow and wide character strings and functions." https://wiki.sei.cmu.edu/confluence/display/c/STR38-C