
CVE-2017-14948 для прошивки D-Link 880
В этой небольшой статье мы рассмотрим некоторые ошибки, которые я нашел в продуктах D-Link. D-Link предлагает широкий ассортимент продукции, включающий множество различных моделей маршрутизаторов с разными версиями прошивки. В этом документе я рассмотрю следующие версии прошивок: DIR-880L, DIR-868L, DIR-890L, DIR-885L и DIR-895L. Без лишних слов, приступим.
Поскольку у меня не было ни одного маршрутизатора D-Link, а они предоставляют свободный доступ к своим прошивкам, я решил искать ошибки, полагаясь только на статический анализ. Обратите внимание, что в этом разделе я буду ссылаться на прошивку DIR-880L; остальные прошивки имеют схожую структуру.
После загрузки и распаковки прошивки DIR-880L я обнаружил, что её прошивка содержит целую файловую систему squashFS, содержащую около 2160 файлов. Поскольку я не хотел рассматривать каждый из них по отдельности, я начал искать тот, который обрабатывает пользовательские входные данные.
После анализа конфигурационных файлов и поиска известных HTTP-заголовков я в итоге сосредоточил внимание на трех бинарных файлах, и в конечном итоге на одном: fileaccess.cgi.
Вот дизассемблирование уязвимой функции:
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;
}
В приведенном выше коде содержимое переменной 'CONTENT_TYPE' (на которую указывает переменная haystack) контролируется пользователем (через заголовок HTTP-запроса). Его содержимое после ключевого слова 'boundary' затем копируется в буфер dest без проверки длины haystacka. Если взглянуть на вызывающую функцию (адрес 0x1CE6C), можно сделать вывод, что размер dest составляет 256 байт. Поскольку злоумышленник может контролировать содержимое CONTENT_TYPE, он может отправить строку 'boundary=', за которой следует как минимум 257 символов, чтобы вызвать переполнение буфера.
В том же образце прошивки были найдены еще две подобные ошибки, связанные с HTTP-куки. Одна из них показана ниже:
v10 = getenv("HTTP_COOKIE");
if ( v10 )
{
strcpy((char *)&v5, &v10[v11]);
v17 = strlen((const char *)&v5);
}
Здесь переменная v10 указывает на пользовательский cookie, который может быть размером не более 4 КБ (согласно RFC2109). Однако переменная v5 имеет размер 1024 байта (как можно понять из стекового кадра функции). Это может вызвать переполнение буфера.
Эти ошибки были сообщены и подтверждены компанией D-Link.
Эти образцы прошивок имеют структуру, аналогичную DIR-880L, и содержат те же ошибки, связанные с теми же HTTP-полями.