
CVE-2017-14948 pour le firmware D-Link 880
Dans ce petit article, nous allons voir quelques bugs que j'ai trouvés sur des produits D-Link. D-Link propose une large gamme de produits, comprenant de nombreux modèles de routeurs, utilisant différentes versions de firmware. Dans ce document, je traiterai les versions de firmware suivantes : DIR-880L, DIR-868L, DIR-890L, DIR-885L et DIR-895L. Sans plus tarder, commençons.
Comme je ne possédais aucun des routeurs D-Link et qu'ils fournissent un accès gratuit à leur firmware, j'ai décidé de trouver des bugs en ne m'appuyant que sur l'analyse statique. Notez que, dans cette section, je ferai référence au firmware DIR-880L ; les autres firmwares ont des structures similaires.
Après avoir téléchargé et décompressé le firmware DIR-880L, j'ai constaté que son firmware contient un système de fichiers squashFS complet, contenant environ 2160 fichiers. Comme je ne voulais pas les considérer chacun indépendamment, j'ai commencé à chercher celui qui gérait les entrées utilisateur.
Après avoir analysé les fichiers de configuration et recherché les en-têtes HTTP connus, j'ai finalement restreint mon attention à trois binaires, et finalement à un seul : fileaccess.cgi.
Voici le désassemblage de la fonction vulnérable :
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;
}
Dans le code ci-dessus, le contenu de la variable 'CONTENT_TYPE' (pointée par la variable haystack) est contrôlé par un utilisateur (via l'en-tête de la requête HTTP). Son contenu, après le mot-clé 'boundary', est ensuite copié dans un tampon dest, sans vérifier la longueur de haystacka. Si l'on regarde la fonction appelante (adresse 0x1CE6C), on peut déduire que la taille de dest est de 256 octets. Comme un attaquant peut contrôler le contenu de CONTENT_TYPE, il pourrait envoyer la chaîne 'boundary=' suivie d'au moins 257 caractères pour déclencher un débordement de tampon.
Deux autres bugs similaires ont été trouvés dans le même échantillon de firmware, impliquant le cookie HTTP. L'un d'eux est présenté ci-dessous :
v10 = getenv("HTTP_COOKIE");
if ( v10 )
{
strcpy((char *)&v5, &v10[v11]);
v17 = strlen((const char *)&v5);
}
Ici, la variable v10 pointe vers le cookie utilisateur, qui peut être au maximum de 4k octets (selon la RFC2109). Cependant, la variable v5 est aussi grande que 1024 octets (comme on peut le déduire de la pile de la fonction). Cela peut déclencher un débordement de tampon.
Ces bugs ont été signalés et confirmés par D-Link.
Ces échantillons de firmware présentent une structure similaire à celle du DIR-880L et ont les mêmes bugs liés aux mêmes champs HTTP.