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
| Auswirkung | Details |
|---|---|
| Integrität | Bereich: Speicherbeschädigung Unterdimensionierte Pufferallokationen basierend auf falscher Länge führen zu Buffer Overflows während String-Operationen. |
| Vertraulichkeit | Bereich: Informationsoffenlegung Over-Reads beim Iterieren über String-Grenzen hinaus legen angrenzende Speicherinhalte offen. |
| Verfügbarkeit | Bereich: 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
-
MITRE. "CWE-135: Incorrect Calculation of Multi-Byte String Length." https://cwe.mitre.org/data/definitions/135.html
-
CERT. "STR38-C. Do not confuse narrow and wide character strings and functions." https://wiki.sei.cmu.edu/confluence/display/c/STR38-C