• XSS.stack #1 – первый литературный журнал от юзеров форума

Статья SIGRed – Эксплуатация 17-летней ошибки в DNS-серверах Windows

yashechka

Генератор контента.Фанат Ильфака и Рикардо Нарвахи
Эксперт
Регистрация
24.11.2012
Сообщения
2 344
Реакции
3 563
Введение

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

"Windows DNS Server" является реализацией Microsoft и является неотъемлемой частью и требованием для среды домена Windows.

SIGRed (CVE-2020-1350) - это критическая уязвимость (базовая оценка CVSS 10.0) в DNS-сервере Windows, которая затрагивает версии Windows Server 2003–2019 и может быть вызвана злонамеренным ответом DNS. Поскольку служба работает с повышенными привилегиями (SYSTEM), при успешном ее использовании злоумышленнику предоставляются права администратора домена, что эффективно компрометирует всю корпоративную инфраструктуру.


Мотивация

Нашей главной целью было найти уязвимость, которая позволила бы злоумышленнику поставить под угрозу среду домена Windows, предпочтительно не прошедшую проверку подлинности. Существует множество связанных исследований различных независимых исследователей в области безопасности, а также исследований, спонсируемых национальными государствами. Большинство опубликованных и общедоступных материалов и эксплоИтов посвящены реализации Microsoft протоколов SMB (EternalBlue (https://en.wikipedia.org/wiki/EternalBlue)) и RDP (BlueKeep (https://en.wikipedia.org/wiki/BlueKeep)), поскольку эти цели влияют как на серверы, так и на конечные точки. Чтобы получить права администратора домена, простой подход заключается в непосредственном использовании контроллера домена. Поэтому мы решили сосредоточить наше исследование на менее публично изученной поверхности атаки, которая существует в основном на Windows Server и контроллерах домена.

Обзор DNS Windows

"Система доменных имен (DNS) - это один из стандартных наборов протоколов, которые включают в себя TCP/IP, и вместе DNS-клиент и DNS-сервер предоставляют компьютерам и пользователям услуги разрешения имен с помощью сопоставления имен компьютеров и IP-адресов". - Microsoft (https://docs.microsoft.com/en-us/windows-server/networking/dns/dns-top).

DNS главным образом использует Протокол Пользовательских Дейтаграмм (UDP) на порту 53 для обслуживания запросов. DNS-запросы состоят из одного UDP-запроса от клиента, за которым следует один UDP-ответ от сервера.

Помимо перевода имен в IP-адреса, DNS служит и другим целям. Например, агенты передачи почты используют DNS, чтобы найти лучший почтовый сервер для доставки электронной почты: запись MX обеспечивает сопоставление между доменом и почтовым обменником, что может обеспечить дополнительный уровень отказоустойчивости и распределения нагрузки. Список доступных типов записей DNS и их соответствующие цели можно найти в Википедии (https://en.wikipedia.org/wiki/List_of_DNS_record_types ).

Но смысл этого поста в блоге не в том, чтобы представить длинную беседу о функциях и истории DNS, поэтому мы рекомендуем вам прочитать больше о DNS здесь (https://www.cloudflare.com/learning/dns/what-is-dns/).

Что нужно знать:

- DNS работает через порт UDP/TCP 53.
- Одно сообщение DNS (ответ/запрос) ограничено 512 байтами в UDP и 65 535 байтами в TCP.
- DNS является иерархическим и децентрализованным по своей природе. Это означает, что когда DNS-сервер не знает ответа на запрос, который он получает, запрос перенаправляется на DNS-сервер над ним в иерархии. На вершине иерархии есть 13 корневых DNS-серверов по всему миру.

В Windows DNS-клиент и DNS-сервер реализованы в двух разных модулях:

- DNS-клиент - dnsapi.dll отвечает за разрешение DNS.
- DNS-сервер - dns.exe отвечает за ответы на DNS-запросы на Windows Server, в котором установлена роль DNS.

Наше исследование сосредоточено вокруг модуля dns.exe.

Подготовка окружающей среды

Для нашей поверхности атаки есть два основных сценария:
- Ошибка в том, как DNS-сервер анализирует входящий запрос.
- Ошибка в способе, которым DNS-сервер анализирует ответ для перенаправленного запроса.

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

Как упоминалось ранее, перенаправленный запрос - это использование архитектуры DNS для возможности пересылки запросов, на которые он не знает ответа, - на DNS-сервер над ним в иерархии.

Однако в большинстве сред их серверы пересылки настраиваются на хорошо известные респектабельные DNS-серверы, такие как 8.8.8.8 (Google) или 1.1.1.1 (Cloudflare), или, по крайней мере, на сервер, который не находится под контролем злоумышленника.

Это означает, что даже если мы обнаружим проблему при разборе ответов DNS, нам нужно будет создать "человека посередине" для его использования. Очевидно, этого недостаточно.

Запись NS спешит на помощь

NS означает "сервер имен", и эта запись указывает, какой DNS-сервер является полномочным для этого домена (какой сервер содержит фактические записи DNS). Запись NS обычно отвечает за разрешение поддоменов данного домена. Домен часто имеет несколько записей NS, которые могут указывать основной и резервный серверы имен для этого домена.

Чтобы целевой DNS-сервер Windows анализировал ответы от нашего вредоносного DNS-сервера имен, мы делаем следующее:

1. Настраиваем записи NS нашего домена (deadbeef.fun), чтобы они указывали на наш вредоносный DNS-сервер (ns1.41414141.club).
2 - ЗАпрашиваем у жертвы DNS-сервер Windows на наличие NS-записей deadbeef.fun.
3 - DNS жертвы, еще не зная ответа на этот запрос, перенаправляет запрос на DNS-сервер над ним (8.8.8.8).
4 - Авторитетный сервер (8.8.8.8) знает ответ и отвечает, что NameServer deadbeef.fun - ns1.41414141.club.
5 - DNS-сервер Windows жертвы обрабатывает и кэширует этот ответ.
6 - В следующий раз, когда мы запросим субдомен deadbeef.fun, целевой DNS-сервер Windows также запросит у ns1.41414141.club свой ответ, так как это NameServer для этого домена.

1.png


Уязвимость — CVE-2020-1350

Функция: dns.exe!SigWireRead
Тип уязвимости: целочисленное переполнение, приводящее к переполнению буфера на основе кучи

dns.exe реализует функцию синтаксического анализа для каждого поддерживаемого типа ответа.

2.png


3.png


Один из поддерживаемых типов ответов предназначен для запроса SIG. Согласно Википедии, запрос SIG - это "запись подписи, используемая в SIG (0) (RFC 2931) и TKEY (RFC 2930). RFC 3755 назначил RRSIG заменой SIG для использования в DNSSEC ".

Давайте рассмотрим список дизассемблера, созданный Cutter для dns.exe!SigWireRead - функция-обработчик для типа ответа SIG:

4.png


Первый параметр, который передается в RR_AllocateEx (функция, ответственная за выделение памяти для записи ресурса), вычисляется по следующей формуле:

[Name_PacketNameToCountNameEx result] + [0x14] + [Длина поля подписи (rdi – rax)]

Размер поля подписи может варьироваться, поскольку он является основной полезной нагрузкой ответа SIG.

5.png


Как вы можете видеть на рисунке ниже, RR_AllocateEx ожидает, что его параметры будут переданы в 16-битных регистрах, так как он использует dx как часть rdx и cx как часть rcx.

Это означает, что, если мы можем сделать так, чтобы вышеприведенная формула вывела результат, превышающий 65 535 байт (максимальное значение для 16-битного целого числа), мы получили переполнение целочисленного значения, которое приводит к гораздо меньшему выделению, чем ожидалось, что, как мы надеемся, это приведет к перезаписи буфера на основе кучи.

6.png


Достаточно удобно, что этот выделенный адрес памяти затем передается как буфер назначения для memcpy, что приводит к переполнению буфера на основе кучи.

7.png


Подводя итог, отправив ответ DNS, содержащий большую (более 64 КБ) запись SIG, мы можем вызвать управляемое переполнение буфера на основе кучи примерно 64 КБ в небольшом выделенном буфере.

Запуск уязвимости

Теперь, когда мы можем заставить пострадавший DNS-сервер запрашивать у нашего DNS-сервера различные вопросы, мы фактически превратили его в клиента. Мы можем заставить пострадавший DNS-сервер задавать нашему вредоносному DNS-серверу определенные типы запросов и, соответственно, отвечать соответствующими вредоносными ответами.

Мы подумали, что все, что нам нужно, чтобы вызвать эту уязвимость, - это заставить DNS-сервер жертвы запросить у нас запись SIG и ответить на него ответом SIG с длинной подписью (длина> = 64 КБ). Мы были разочарованы, обнаружив, что DNS по UDP имеет ограничение размера в 512 байт (или 4096 байт, если сервер поддерживает EDNS0). В любом случае этого недостаточно, чтобы вызвать уязвимость.

Но что произойдет, если у сервера есть веская причина для отправки ответа размером более 4096 байт? Например, длинный ответ TXT или имя хоста, которое может быть разрешено для нескольких IP-адресов.

Усечение DNS - но подождите, это еще не все!

Согласно DNS RFC 5966:

"В отсутствие EDNS0 (Механизмы расширения для DNS 0) нормальное поведение любого DNS-сервера, которому необходимо отправить ответ UDP, который превысил бы ограничение в 512 байт, состоит в том, что сервер усекает ответ так, чтобы он соответствовал этому пределу и затем установите флаг TC в заголовке ответа. Когда клиент получает такой ответ, он принимает флаг TC в качестве указания на то, что ему следует вместо этого повторить попытку через TCP".

Круто! Таким образом, мы можем установить флаг TC (усечение) в нашем ответе, который заставляет целевой DNS-сервер Windows инициировать новое TCP-подключение к нашему вредоносному серверу NameServer, и мы можем передать сообщение размером более 4096 байт. Но насколько больше?

Согласно DNS RFC 7766:
"DNS-клиентам и серверам СЛЕДУЕТ передавать поле длиной в два октета и сообщение, описываемое этим полем длины, на уровень TCP одновременно (например, в одном системном вызове "запись"), чтобы повысить вероятность того, что все данные будут передаваться в одном сегменте TCP ".

Поскольку первые два байта сообщения представляют его длину, максимальный размер сообщения в DNS через TCP представляется как 16 битов и поэтому ограничен 64 КБ.

8.png


Но даже сообщение длиной 65 535 недостаточно велико, чтобы вызвать уязвимость, поскольку длина сообщения включает заголовки и исходный запрос. Эти издержки не учитываются при расчете размера, который передается в RR_AllocateEx.

Сжатие указателей DNS - меньше значит больше

Давайте еще раз посмотрим на законный ответ DNS (для удобства мы выбрали ответ типа A).

9.png


Вы можете видеть, что Wireshark оценил байты 0xc00c в поле имени ответа для research.checkpoint.com. Вопрос в том, почему?

Вот ответ - https://powerdns.org/hello-dns/basic.md.html

"Чтобы вставить как можно больше информации в 512 байтов, DNS-имена могут (и часто ДОЛЖНЫ) быть сжаты… В этом случае DNS-имя ответа кодируется как 0xc0 0x0c. У части c0 установлены два старших значащих бита, указывающих, что следующие 6+8 битов являются указателем где-то ранее в сообщении. В этом случае это указывает на позицию 12 (=0x0c) внутри пакета, которая находится сразу после заголовка DNS ".

Что находится по смещению 0x0c (12) от начала пакета? Это research.checkpoint.com!

В этой форме сжатия указатель указывает на начало закодированной строки. В DNS строки кодируются в виде цепочки (<size> <value>).

10.png


Таким образом, мы можем использовать «магический» байт 0xc0 для ссылки на строки внутри пакета. Давайте еще раз рассмотрим формулу, которая вычисляет размер, который передается в RR_AllocateEx:

[Name_PacketNameToCountNameEx result] + [0x14] + [Длина поля подписи (rdi – rax)]

Реверсинг Name_PacketNameToCountNameEx подтверждает поведение, которое мы описали выше. Цель Name_PacketNameToCountNameEx - вычислить размер поля имени с учетом сжатия указателя. Наличие примитива, который позволяет нам увеличивать размер выделения на большую величину, когда мы представляем его только двумя байтами, это именно то, что нам нужно.

Следовательно, мы можем использовать сжатие указателей в поле SIG Signer's Name. Однако простое указание 0xc00c в качестве имени подписавшего не приведет к переполнению, поскольку запрашиваемое доменное имя уже присутствует в запросе, а размер служебных данных вычитается из выделенного значения. Но как насчет 0xc00d? Единственное ограничение, которое мы должны соблюдать, - это то, что наша закодированная строка действительна (оканчивается на 0x0000), и мы можем сделать это легко, потому что у нас есть поле без каких-либо символьных ограничений - значение подписи. Для домена 41414141.fun 0xc00d указывает на первый символ домена ("4"). Порядковый номер этого символа затем используется в качестве размера несжатой строки ("4" представляет значение 0x34 (52)). Агрегирование размера этой несжатой строки с максимальным объемом данных, который мы можем разместить в поле Подпись (до 65 535, в зависимости от исходного запроса), приводит к значению, превышающему 65 535 байт, что приводит к переполнению!

Давайте проверим это с WinDBG, подключенным к dns.exe:

11.png


Приложение упало!

Хотя кажется, что приложение потерпели крах, потому что мы пытались записать значения в не отображенную память, куча может быть сформирована таким образом, что позволяет нам перезаписывать некоторые значимые значения.

Предыдущие попытки использования dns.exe доступны онлайн. Например: более глубокий взгляд на ms11-058 (https://blog.skullsecurity.org/2011/a-deeper-look-at-ms11-058).

Запуск из браузера

Мы знаем, что эта ошибка может быть вызвана злоумышленником, присутствующим в среде локальной сети. Однако мы подумали, что было бы интересно посмотреть, может ли эта ошибка быть запущена удаленно без доступа к локальной сети.

Контрабанда DNS внутри HTTP

К настоящему времени вы должны знать, что DNS можно передавать по TCP и что DNS-сервер Windows поддерживает этот тип подключения. Вы также должны быть знакомы со структурой DNS поверх TCP, но на всякий случай вот краткий обзор:

12.png


Рассмотрим следующую стандартную полезную нагрузку HTTP:

0000 50 4f 53 54 20 2f 70 77 6e 20 48 54 54 50 2f 31 POST /pwn HTTP/1
0010 2e 31 0d 0a 41 63 63 65 70 74 3a 20 2a 2f 2a 0d .1..Accept: */*.
0020 0a 52 65 66 65 72 65 72 3a 20 68 74 74 70 3a 2f .Referer: http:/

Несмотря на то, что это полезная нагрузка HTTP, отправка ее на наш целевой DNS-сервер через порт 53 заставляет DNS-сервер Windows интерпретировать эту полезную нагрузку, как если бы это был запрос DNS. Это делается с использованием следующей структуры:

0000 50 4f 53 54 20 2f 70 77 6e 20 48 54 54 50 2f 31 POST /pwn HTTP/1
0010 2e 31 0d 0a 41 63 63 65 70 74 3a 20 2a 2f 2a 0d .1..Accept: */*.
0020 0a 52 65 66 65 72 65 72 3a 20 68 74 74 70 3a 2f .Referer: http:/

Message Length: 20559 (0x504f)
Transaction ID: 0x5354
Flags: 0x202f
Questions: 28791 (0x7077)
Answer RRs: 28192 (0x6e20)
Authority RRs: 18516 (0x4854)
Additional RRs: 21584 (0x5450)
Queries: [...]

К счастью, DNS-сервер Windows поддерживает как "Повторное Использование Соединения", так и "Конвейеризацию" RFC 7766, что означает, что мы можем выдавать несколько запросов за один сеанс TCP, и мы можем делать это, не ожидая ответов.

Почему это важно?

Мы можем использовать базовый JavaScript для отправки запроса POST на DNS-сервер из браузера, когда жертва заходит на веб-сайт, который мы контролируем. Но, как показано выше, запрос POST интерпретируется так, как мы на самом деле не контролируем.

Однако мы можем злоупотреблять функциями "Повторного Использования Подключения" и "Конвейерной Передачи", отправляя HTTP-запрос POST на целевой DNS-сервер (https://target-dns:53 /) с двоичными данными, содержащими другой "контрабандный" DNS-запрос в данные POST, запрашиваемые отдельно.

Наша полезная нагрузка HTTP состоит из следующего:

- Заголовки HTTP-запросов, которые мы не контролируем (User-Agent, Referer и так далее).
- "Заполнение", чтобы первый DNS-запрос имел правильную длину (0x504f) внутри данных POST.
- Наш "контрабандный" DNS-запрос внутри данных POST.

13.png



На практике большинство популярных браузеров (таких как Google Chrome и Mozilla Firefox) не допускают HTTP-запросы на порт 53, поэтому эту ошибку можно эксплуатировать только в ограниченном наборе веб-браузеров - включая Internet Explorer и Microsoft Edge (не на основе Chromium).

Анализ вариантов

Основная причина этой ошибки заключается в том, что API RR_AllocateEx ожидает параметр размера 16 бит. Обычно можно предположить, что размер одного сообщения DNS не превышает 64 КБ, и, следовательно, такое поведение не должно вызывать проблем. Однако, как мы только что видели, это предположение неверно, когда учитывается результат Name_PacketNameToCountNameEx при расчете размера буфера. Это происходит потому, что функция Name_PacketNameToCountNameEx вычисляет эффективный размер несжатого имени, а не количество байтов, которое потребовалось для его представления в пакете.

Чтобы найти другие варианты этой ошибки, нам нужно найти функцию, которая удовлетворяет следующим условиям:

- RR_AllocateEx вызывается с переменным размером (а не с постоянным значением).
- Существует вызов Name_PacketNameToCountNameEx, и его результат используется для вычисления размера, переданного в RR_AllocateEx.
- Значение, которое передается в RR_AllocateEx, рассчитывается с использованием значений в диапазоне 16 бит или более.

Единственной другой функцией в dns.exe, которая удовлетворяет этим трем условиям, является NsecWireRead. Давайте рассмотрим следующий упрощенный фрагмент кода, который мы вывели из декомпиляции функции:

C:
RESOURCE_RECORD* NsecWireRead(PARSED_WIRE_RECORD *pParsedWireRecord, DNS_PACKET *pPacket, BYTE *pRecordData, WORD wRecordDataLength)
{
DNS_RESOURCE_RECORD *pResourceRecord;
unsigned BYTE *pCurrentPos;
unsigned int dwRemainingDataLength;
unsigned int dwBytesRead;
unsigned int dwAllocationSize;
DNS_COUNT_NAME countName;
pResourceRecord = NULL;
pCurrentPos = Name_PacketNameToCountNameEx(&countName, pPacket, pRecordData, pRecordData + wRecordDataLength, 0);
if (pCurrentPos)
{
   if
    (pCurrentPos >= pRecordData                                         // <-- Check #1 - Bounds check
     && pCurrentPos - pRecordData <= 0xFFFFFFFF                         // <-- Check #2 - Same bounds check (?)
     && wRecordDataLength >= (unsigned int)(pCurrentPos - pRecordData)) // <-- Check #3 - Bounds check
    {
      dwRemainingDataLength = wRecordDataLength - (pCurrentPos - pRecordData);
      dwBytesRead = countName.bNameLength + 2;
      // size := len(countName) + 2 + len(payload)
      dwAllocationSize = dwBytesRead + dwRemainingDataLength;
      if (dwBytesRead + dwRemainingDataLength >= dwBytesRead            // <-- Check #4 - Integer Overflow check (32 bits)
          && dwAllocationSize <= 0xFFFF)                                // <-- Check #5 - Integer Overflow check (16 bits)
      {
       pResourceRecord = RR_AllocateEx(dwAllocationSize, 0, 0);
       if (pResourceRecord)
       {
         Name_CopyCountName(&pResourceRecord->data, &countName);
         memcpy(&pResourceRecord->data + pResourceRecord->data->bOffset + 2, pCurrentPos, dwRemainingDataLength);
       }
     }
   }
}
return pResourceRecord;
}

Как видите, эта функция содержит много проверок безопасности. Одна из них (Проверка № 5) - это проверка 16-битного переполнения, которая предотвращает вариант нашей уязвимости в этой функции. Мы также хотели бы отметить, что эта функция имеет гораздо больше проверок безопасности, чем средняя функция в dns.exe, что заставляет нас задуматься о том, была ли эта ошибка уже замечена и исправлена, но только в этой конкретной функции.

Как мы упоминали ранее, Microsoft реализовала DNS-клиент и DNS-сервер в двух разных модулях. Хотя наша уязвимость определенно существует на DNS-сервере, мы хотели посмотреть, существует ли она и на DNS-клиенте.

14.png



Похоже, что в отличие от dns.exe!SigWireRead, dnsapi.dll!Sig_RecordRead проверяет в Sig_RecordRead + D0, что значение, которое передается в dnsapi.dll!Dns_AllocateRecordEx, меньше 0xFFFF байт, таким образом предотвращая переполнение.

Тот факт, что эта уязвимость отсутствует в dnsapi.dll, а также имеет разные соглашения об именах между двумя модулями, заставляет нас думать, что Microsoft управляет двумя совершенно разными базами кода для DNS-сервера и DNS-клиента и не синхронизирует исправления ошибок между ними.

План эксплуатации

По запросу Microsoft мы решили скрыть информацию о примитивах эксплуатации, чтобы предоставить пользователям достаточно времени для установки исправлений на своих DNS-серверах. Вместо этого мы обсуждаем наш план эксплуатации, поскольку он применяется к Windows Server 2012R2. Однако мы считаем, что этот план должен распространяться и на другие версии Windows Server.

Бинарный файл dns.exe был скомпилирован с помощью Control Flow Guard (CFG), что означает, что традиционного подхода перезаписи указателя функции в памяти недостаточно для использования этой ошибки. Если бы этот двоичный файл не был скомпилирован с CFG, то использовать эту ошибку было бы довольно просто, так как довольно рано мы столкнулись со следующим сбоем:


15.png


Как видите, мы потерпели крах в функции ntdll!LdrpValidateUserCallTarget. Эта функция отвечает за проверку целевых указателей на функции как часть CFG. Мы видим, что проверяемый указатель (rcx) полностью управляем, что означает, что мы успешно переписали указатель на функцию где-то по пути. Причина, по которой мы увидели сбой, заключается в том, что указатель функции используется в качестве индекса глобальной таблицы растровых изображений с битом “allowed”/“disallowed” для каждого адреса, а наш произвольный адрес привел к чтению с не отображенной страницы в самой таблице.

Чтобы использовать эту ошибку при полном удаленном выполнении кода при победе над CFG, нам нужно найти примитивы, которые дают нам следующие возможности: write-what-where (для точной перезаписи адреса возврата в стеке) и утечка информации (для утечки адресов памяти такие как стек).

Infoleak

Чтобы создать примитив Infoleak, мы испортили метаданные записи ресурса DNS, пока они еще находится в кэше, используя наше переполнение. Затем при повторном запросе из кеша мы смогли сделать утечку в смежной куче памяти.

Менеджер кучи WinDNS

WinDNS использует функцию Mem_Alloc для динамического выделения памяти. Эта функция управляет своими собственными пулами памяти, которые будут использоваться в качестве эффективного кэша. Существует 4 сегмента пула памяти для разных размеров выделения (до 0x50, 0x68, 0x88, 0xA0). Если запрошенный размер выделения превышает 0xA0 байт, по умолчанию используется HeapAlloc, который использует собственную кучу Windows. Менеджер кучи выделяет дополнительные 0x10 байтов для заголовка пула памяти, который содержит метаданные, включая тип буфера (выделенный/свободный), указатель на следующий доступный кусок памяти, файл cookie для проверок отладки и многое другое. Менеджер кучи реализовал свои списки размещения в виде односвязных списков, что означает, что чанки размещаются в обратном порядке, в котором они были освобождены (LIFO).

Write-What-Where

Чтобы создать примитив write-what-where, мы атаковали диспетчер кучи WinDNS, повредив заголовок (метаданные) блока, де-факто испортив freelist.

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

Чтобы обойти CFG, мы хотим, чтобы эта область памяти находилась в стеке (расположение которой мы надеемся узнать благодаря утечке информации).
Когда у нас есть возможность записи в стек, мы можем перезаписать адрес возврата на адрес, который мы хотим выполнить, эффективно перехватывая поток выполнения.

Важно отметить, что по умолчанию служба DNS перезапускается при первых трех сбоях, что увеличивает шансы на успешную эксплуатацию.

Заключение

Эта уязвимость высокой степени опасности была признана Microsoft и ей был назначен код CVE-2020-1350.

Мы считаем, что вероятность использования этой уязвимости высока, так как мы внутренне обнаружили все примитивы, необходимые для использования этой ошибки. Из-за нехватки времени мы не продолжили использование ошибки (которая включает в себя объединение всех примитивов эксплуатации), но мы верим, что решительный злоумышленник сможет ее эксплуатировать. Успешное эксплуатирование этой уязвимости может иметь серьезные последствия, так как вы часто можете найти непропатченные среды доменов Windows, особенно контроллеры домена. Кроме того, некоторые интернет-провайдеры (ISP) могут даже настроить свои общедоступные DNS-серверы как WinDNS.

Мы настоятельно рекомендуем пользователям устанавливать исправления на своих уязвимых DNS-серверах Windows, чтобы предотвратить использование этой уязвимости.

В качестве временного решения, пока не будет применено исправление, мы предлагаем установить максимальную длину сообщения DNS (через TCP) равной 0xFF00, что должно устранить уязвимость. Вы можете сделать это, выполнив следующие команды:

reg add "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\DNS\Parameters" /v "TcpReceivePacketSize" /t REG_DWORD /d 0xFF00 /f
net stop DNS && net start DNS


Хронология раскрытия

- 19 мая 2020 года - первоначальный отчет в Microsoft.
- 18 июня 2020 г. - Microsoft выпустила CVE-2020-1350 для этой уязвимости.
- 09 июля 2020 г. - Microsoft признала эту проблему критической уязвимостью с оценкой CVSS 10,0.
- 14 июля 2020 г. - Microsoft выпустила исправление

Источник: https://research.checkpoint.com/202...ing-a-17-year-old-bug-in-windows-dns-servers/
Автор перевода: yashechka
Переведено специально для портала xss.pro (c)
 


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх