- PVSM.RU - https://www.pvsm.ru -

Как изучение критической уязвимости DHCP в Windows 10 привело к обнаружению еще двух ошибок безопасности

Как изучение критической уязвимости DHCP в Windows 10 привело к обнаружению еще двух ошибок безопасности - 1 [1]

Изображение: Unsplash [2]

Как было описано в предыдущей статье [3] про CVE-2019-0726 [4], иногда поиск деталей об уже известной уязвимости приводит к обнаружению новой уязвимости. А в некоторых случаях таких новых уязвимостей оказывается больше одной.

В статье рассматривались две функции библиотеки dhcpcore.dll: вскользь упомянутая UpdateDomainSearchOption и более подробно разобранная вызываемая ею DecodeDomainSearchListData. Как всегда происходит при поиске уязвимостей, даже если важные выводы в конце сводятся к одной-двум функциям, в процессе разбора приходится просмотреть гораздо большее количество кода. И порой глаз цепляется за мелочи, которые не имеют отношения к текущей задаче, но могут иметь самостоятельное значение или пригодиться позже. Пусть в данный момент нет времени обращать на них внимание, но такие мелочи откладываются на подкорке и, если по истечении некоторого срока появляется возможность вернуться к ним и проверить свои догадки, вновь всплывают в сознании.

Так и произошло на этот раз. При изучении функции DhcpExtractFullOptions, отвечающей за обработку всех опций, заданных в DHCP-ответе от сервера, в частности вызывающей UpdateDomainSearchOption, внимание сразу привлекают два массива на стеке по 256 элементов каждый:

Как изучение критической уязвимости DHCP в Windows 10 привело к обнаружению еще двух ошибок безопасности - 2

При этом не заметно присутствия каких-либо проверок, ограничивающих значения итераторов данных массивов. Так как в тот момент мы разбирали другую уязвимость, эта информация к делу не относилась. Поэтому оставалось лишь запомнить это место в коде, чтобы возвратиться к нему позже.

Анализ

Проходит пара недель, и мы вновь вспоминаем про обратившую на себя внимание ранее функцию DhcpExtractFullOptions. Обращаемся к ней в дизассемблере, причесываем ранее не до конца разобранные куски кода и пытаемся понять, для чего используются два заинтриговавших нас статических массива.

В самом начале исполнения функции массивы и их итераторы обнуляются:

Как изучение критической уязвимости DHCP в Windows 10 привело к обнаружению еще двух ошибок безопасности - 3

Функция занимается разбором всех опций в полученном от DHCP-сервера пакете, сбором информации из них и ее последующей обработкой. Помимо этого, по результатам разбора она также записывает соответствующее событие в сервис ETW (Event Tracing for Windows). Именно в логировании события и принимают участие интересующие нас буферы. Вместе с большим количеством других данных они передаются в процедуру EtwEventWriteTransfer. Работа по подготовке всех данных для логирования довольно объемна и не имеет большого значения для рассматриваемой нами уязвимости, поэтому обойдемся без иллюстраций.

Важнее определить, как эти буферы заполняются. Происходит заполнение в цикле разбора опций. Сначала для текущей поступившей на обработку опции вызывается функция с говорящим названием ParseDhcpv4Option, которая либо заполняет поля объекта dhcp_pointers на основании поступивших данных, либо делает пометку о незнакомой опции, когда встречает идентификатор опции со значением, для которого отсутствует обработчик.

Как изучение критической уязвимости DHCP в Windows 10 привело к обнаружению еще двух ошибок безопасности - 4

По возвращении из ParseDhcpv4Option значение идентификатора текущей опции option_tag записывается в следующий элемент массива all_tags, первого из интересующих нас массивов. Если функция встретила незнакомую опцию и, соответственно, не выставила флаг is_known_option, то значение идентификатора записывается также и в следующий элемент второго массива — unknown_tags. Естественно, осмысленные названия переменные в этой статье получили уже по результатам разбора кода.

Таким образом, массив all_tags хранит теги всех опций из поступившего сообщения, а массив unknown_tags — теги только для незнакомых парсеру опций. При этом проверка значений индексов этих массивов отсутствует вовсе. Следовательно, значения таких индексов могут превышать 256 и приводить к записи за пределы отведенной на стеке под массивы памяти. Для переполнения первого массива достаточно отправить от DHCP-сервера пакет с количеством опций, превышающим 256. То же самое справедливо и для второго массива с той лишь разницей, что отправлять следует опции, которые клиент не умеет обрабатывать.

Эксплуатация

Попробуем теперь на практическом примере убедиться в том, что сделанные нами выводы верны. Для начала обратим внимание на то, что теги опций занимают один байт, в то время как элементы массивов имеют тип int, то есть являются четырехбайтовыми. Таким образом, мы имеем переполнение, в котором мы контролируем каждый четвертый байт, а остальные при перезаписи обнуляются.

Как изучение критической уязвимости DHCP в Windows 10 привело к обнаружению еще двух ошибок безопасности - 5

Для проверки нашего предположения проще всего будет перезаписать хранящуюся на стеке security cookie рассматриваемой функции, что вызовет исключение, связанное с проверкой безопасности. Смоделируем ситуацию, в которой DHCP-сервер отправляет достаточное для перезаписи количество опций. Пускай это будут 0x1a0 (416) опций с идентификатором 0xaa и нулевым размером. Таким образом, каждая опция занимает два байта, и полный размер пакета со всеми заголовками составит 1100—1200 байт. Это значение находится в пределах MTU [5] для Ethernet, следовательно, имеются основания полагать, что сообщение не будет фрагментировано, что позволит нам избежать возможных неблагоприятных эффектов.

Отправляем сформированный описанным способом пакет в ответ на запрос от DHCP-клиента и перехватываем на клиентской машине исключение в соответствующем процессе svchost.exe:

Как изучение критической уязвимости DHCP в Windows 10 привело к обнаружению еще двух ошибок безопасности - 6

Как видно из трассировки стека, идентификаторами опций из нашего пакета были переписаны и stack cookie, и адрес возврата из функции.

Конечно, создание рабочего эксплойта под данную ошибку потребует от злоумышленника достаточно больших усилий. На современных системах переполнение буфера на стеке является довольно сложной и трудоемкой в эксплуатации уязвимостью благодаря всем существующим нынче защитным механизмам. С другой стороны, не следует забывать, что все эти механизмы либо защищают от перезаписи адреса возврата и обработчиков исключений, либо запрещают исполнение кода в непредназначенных для этого регионах памяти, либо мешают предсказывать адреса. Они, например, никак не могут помочь против перезаписи хранящихся на стеке между переполняемым буфером и адресом возврата локальных переменных. И рассматриваемая функция DhcpExtractFullOptions содержит в этом интервале несколько потенциально опасных переменных.

Вновь пишем в Microsoft об обнаруженной ошибке. После непродолжительной переписки и занявшего примерно неделю анализа заявки получаем ответ, что для описанной уязвимости готовится CVE-идентификатор, исправление планируется к выпуску в марте, а информация об уязвимости уже имеется в Microsoft, была сообщена кем-то ранее. Факт, вообще говоря, неудивительный, ведь ошибка лежит буквально на поверхности, а буферы, не содержащие граничных проверок индексов, всегда обращают на себя внимание первыми и часто могут быть обнаружены автоматическими средствами анализа.

В марте, как и было заявлено, выходит обновление, исправляющее описанную ошибку, получившую идентификатор CVE-2019-0697 [6]. Исследователем, сообщившим информацию ранее, оказался Mitch Adair, тот самый сотрудник Microsoft, что обнаружил и исправленную в январе DHCP-уязвимость CVE-2019-0547 [7].

Автор: Михаил Цветков, специалист отдела анализа приложений Positive Technologies.

Автор: ptsecurity

Источник [8]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/informatsionnaya-bezopasnost/315025

Ссылки в тексте:

[1] Image: https://habr.com/ru/company/pt/blog/448600/

[2] Unsplash: https://unsplash.com/photos/T01GZhBSyMQ

[3] предыдущей статье: https://habr.com/ru/company/pt/blog/448378/

[4] CVE-2019-0726: https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2019-0726

[5] MTU: https://ru.wikipedia.org/wiki/Maximum_transmission_unit

[6] CVE-2019-0697: https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2019-0697

[7] CVE-2019-0547: https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2019-0547

[8] Источник: https://habr.com/ru/post/448600/?utm_source=habrahabr&utm_medium=rss&utm_campaign=448600