
CVE-2017-14948 for D-Link 880 Firmware
In diesem kleinen Artikel werden wir einige Fehler betrachten, die ich in D-Link-Produkten gefunden habe. D-Link bietet eine breite Produktpalette an, darunter viele verschiedene Router-Modelle mit unterschiedlichen Firmware-Versionen. In diesem Dokument werde ich die folgenden Firmware-Versionen behandeln: DIR-880L, DIR-868L, DIR-890L, DIR-885L und DIR-895L. Ohne weitere Umschweife, lasst uns beginnen.
Da ich keinen der D-Link-Router besaß und sie freien Zugriff auf ihre Firmware bieten, entschied ich mich, Fehler nur durch statische Analyse zu finden. Beachten Sie, dass ich mich in diesem Abschnitt auf die Firmware DIR-880L beziehe; die anderen Firmwares haben ähnliche Strukturen.
Nach dem Herunterladen und Entpacken der DIR-880L-Firmware stellte ich fest, dass die Firmware ein vollständiges squashFS-Dateisystem enthält, das etwa 2160 Dateien umfasst. Da ich nicht jede einzelne davon unabhängig betrachten wollte, begann ich nach derjenigen zu suchen, die Benutzereingaben verarbeitet.
Nach der Analyse der Konfigurationsdateien und der Suche nach bekannten HTTP-Headern beschränkte ich meinen Fokus schließlich auf drei Binärdateien und dann auf eine: fileaccess.cgi.
Hier ist die Disassemblierung der verwundbaren Funktion:
signed int __fastcall content_type(char *a1)
{
char *dest; // [sp+4h] [bp-10h]@1
const char *haystack; // [sp+Ch] [bp-8h]@1
char *haystacka; // [sp+Ch] [bp-8h]@3
dest = a1;
haystack = getenv("CONTENT_TYPE");
if ( !haystack )
return -22;
haystacka = strstr(haystack, "boundary=");
if ( !haystacka )
return -22;
strcpy(dest, haystacka + 9);
return 0;
}
Im obigen Code wird der Inhalt der Variablen 'CONTENT_TYPE' (auf den die Variable haystack zeigt) durch einen Benutzer kontrolliert (über den HTTP-Request-Header). Dessen Inhalt wird nach dem Schlüsselwort 'boundary' in einen Puffer dest kopiert, ohne die Länge von haystacka zu überprüfen. Wenn man sich die aufrufende Funktion (Adresse 0x1CE6C) ansieht, kann man ableiten, dass die Größe von dest 256 Bytes beträgt. Da ein Angreifer den Inhalt von CONTENT_TYPE kontrollieren kann, könnte er die Zeichenfolge 'boundary=' gefolgt von mindestens 257 Zeichen senden, um einen Pufferüberlauf auszulösen.
Zwei weitere ähnliche Fehler wurden in derselben Firmware-Probe gefunden, die das HTTP-Cookie betreffen. Einer davon ist unten dargestellt:
v10 = getenv("HTTP_COOKIE");
if ( v10 )
{
strcpy((char *)&v5, &v10[v11]);
v17 = strlen((const char *)&v5);
}
Hier zeigt die Variable v10 auf das Benutzer-Cookie, das maximal 4k Bytes groß sein kann (gemäß RFC2109). Die Variable v5 ist jedoch 1024 Bytes groß (wie wir aus dem Stack-Frame der Funktion ableiten können). Dies kann einen Pufferüberlauf auslösen.
Diese Fehler wurden von D-Link gemeldet und bestätigt.
Diese Firmware-Beispiele weisen eine ähnliche Struktur wie die DIR-880L auf und haben die gleichen Fehler in Bezug auf dieselben HTTP-Felder.