Cyrus: Buffer Overflow in NNTP-Code

Eine kürzlich entdeckte Buffer-Overflow-Schwachstelle im NNTP-Code des IMAP-Servers Cyrus erlaubt es einem entfernten Angreifer unter Umständen, Befehle auf dem betroffenen System auszuführen.

Die Sicherheitslücke in Cyrus befindet sich in der Funktion “split_wildmats()” in der Datei “imap/nntpd.c” und tritt beim Verarbeiten von NNTP-WILDMAT-Daten auf. Das WILDMAT-Format ist ein Pattern-Matching-Format, das beispielsweise auch im Archivierungsprogramm GNU Tar zum Einsatz kommt und in RFC 3977 für NNTP definiert ist. Der Programmierfehler besteht darin, dass Cyrus die “strcpy()”-Funktion zum Behandeln der WILDMAT-Daten verwendet. Schon die Manpage zu “strcpy()” macht allerdings klar, warum das im Allgemeinen keine gute Idee ist:

char *strcpy(char *dest, const char *src);
The strcpy() function copies the string pointed to by src,
including the terminating null byte ('\0'), to the buffer
pointed to by dest.

Es wird also alles bis zum Terminierungszeichen von “src” nach “dest” kopiert. Ob diese Daten auch wirklich in den bei “dest” allozierten Speicher passen, wird dabei nicht geprüft. Diese Funktion ist bekanntlich für unzählige Buffer-Overflow-Schwachstellen in der Vergangenheit verantwortlich, und es ist schlechte Programmierpraxis, sie überhaupt zu verwenden. Overflows können beim Verwenden dieser Funktion sehr leicht auftreten sobald der durch “dest” referenzierte String länger ist als der bei “src” allozierte Speicher. Grundsätzlich sollte statt “strcpy()” die Funktion “strncpy()” zum Einsatz kommen, die als drittes Argument die Anzahl der zu kopierenden Zeichen annimmt. So lange dann sichergestellt ist, dass diese Zeichenzahl in “dest” passt, können Overflows vermieden werden.

Die Schwachstelle in der Funktion “split_wildmats()” sieht folgendermaßen aus:

do { if ((c = strrchr(str, ','))) *c++ = '\0'; else c = str; if (!(n % 10)) /* alloc some more */ wild = xrealloc(wild, (n + 11) * sizeof(struct wildmat)); if (*c == '!') wild[n].not = 1; /* not */ else if (*c == '@') wild[n].not = -1; /* absolute not (feeding) */ else wild[n].not = 0; strcpy(p, wild[n].not ? c + 1 : c); wild[n++].pat = xstrdup(pattern);
} while (c != str);

In dieser Schleife wird “strcpy()” zum Kopieren der Zeichenkette verwendet, was bei bestimmten Eingaben zum Überlauf führen kann. Zuvor wird nämlich in derselben Funktion folgendes gesetzt:

char pattern[MAX_MAILBOX_BUFFER] = "", *p, *c;
p = pattern + strlen(pattern);

“pattern” besitzt damit nur eine feste Größe von “MAX_MAILBOX_BUFFER”. Diese Schwachstelle lässt sich einfach korrigieren, indem man die “strcpy()”-Funktion durch folgende zwei Zeilen ersetzt:

strncpy(p, wild[n].not ? c + 1 : c, pattern+sizeof(pattern) - p);
pattern[sizeof(pattern)-1] = '\0';

Sollte die Option “allowanonymouslogin” in “imap.conf” gesetzt sein, kann diese Sicherheitslücke ohne Authentifikation ausgenutzt werden. Kurz nach Veröffentlichen des Fehlers wurde behauptet, dass Systeme die mit der “FORTIFY_SOURCE”-Option kompiliert wurden nicht betroffen seinen, also beispielsweise RHEL 5, 6 und Fedora. Diese Meldung war jedoch nicht korrekt, da dieses Problem von “FORTIFY_SOURCE” nicht abgefangen wird. Allerdings lässt sich ein Angriff detektieren, falls Cyrus mit einem Buffer-Overflow-Schutz wie Stack-Smashing-Protector (SSP) übersetzt wurde (Näheres im Bulletin vom 7.9.2011). Sollte der Code allerdings nicht entsprechend übersetzt sein, so kann der Angreifer Befehle mit den Rechten des Cyrus-Servers ausführen.

Betroffen sind die Cyrus-Versionen 2.3 vor 2.3.17 und 2.4 vor 2.4.11. Der Fehler wurde letzte Woche im Git-Repository korrigiert und ist in der kürzlich erschienen Version 2.4.11 nicht mehr enthalten.

Nach oben