利用工具包与 Google Chrome

在2021年10月,我们发现Magnitude exploit kit 在野外测试一个基于Chromium的攻击链。这引起了我们的极大兴趣,因为近几年来,浏览器攻击工具主要集中在Internet Explorer的漏洞上,大家普遍认为像Google Chrome这样的浏览器对于攻击者来说过于庞大,无法轻易攻击。

#MagnitudeEK现在通过利用CVE202121224和CVE202131956来提升其攻击能力,攻击基于Chromium的浏览器。这一发展相当有趣,因为目前大多数攻击工具只针对Internet Explorer,而Chromium则未受到影响。

袋鼠加速器ios

Avast Threat Labs (@AvastThreatLabs) 2021年10月19日

大约一个月后,我们发现Underminer exploit kit也跟进,针对相同的Chromium漏洞开发了攻击工具。这意味著有两个攻击工具敢于攻击Google Chrome:Magnitude利用CVE202121224和CVE202131956,Underminer则利用CVE202121224、CVE20190808、CVE20201020和CVE20201054。

自从我们的发现以来,我们一直在密切监控攻击工具的情况,留意任何新的发展。我们期待其他攻击工具能随之而来,但据我们所知,并没有其他攻击工具加入。此外,Magnitude似乎已经放弃了基于Chromium的攻击链。尽管Underminer至今仍在使用这些漏洞,但它的传统IE攻击链的表现则更好。根据我们的监测数据,Underminer针对基于Chromium的浏览器的攻击尝试占其总次数的不到20。

这是一个非常好的消息,因为这表明基于Chromium的攻击链并不如攻击者希望的那样成功,对于攻击工具开发者来说,针对Chromium用户的攻击并不具有很高的利润潜力。在这篇博客中,我们想分享一些对于这种情况的看法,以及为何攻击者可能最初想要开发这些漏洞的原因。由于我们不会每天都在野外见到新的Chromium攻击链,我们还将剖析Magnitude的攻击工具并分享一些详细的技术信息。

攻击工具理论

要理解为什么攻击工具开发者会想测试Chromium漏洞,首先我们需要从他们的角度来看待问题。他们开发和维护攻击工具的最终目标是获利:他们只想最大化赚取的金额与花费的金额的差额。为了实现这个目标,大多数现代攻击工具遵循一个简单的公式。他们购买针对可能受到其漏洞影响的用户的广告例如Internet Explorer用户。这些广告包含JavaScript代码,该代码会自动执行,即使受害者并未与广告互动有时称为驾驶式攻击。然后,这些代码可以进一步分析受害者的浏览器环境,并为该环境选择合适的漏洞。如果攻击成功,恶意载荷如勒索病毒或虚拟货币挖掘器将部署到受害者那里。在这种情况下,所谓的赚取的金额可以是赎金或挖矿奖励。另一方面,花费的金额主要由广告成本、基础设施成本租用服务器、注册域名等和攻击者花在开发和维护攻击工具上的时间组成。

典型浏览器攻击工具的运作方式

攻击者希望随时准备多种不同的漏洞,因为这将使他们能够广泛吸引潜在受害者。但是,值得注意的是,随著时间的推移,个别漏洞通常会变得不那么有效。这是因为,随著一些人进行漏洞修补,其他人升级到新的设备希望这些设备不会存在与以前设备相同的漏洞,受到已知漏洞影响的人数将减少。这迫使攻击者始终寻找新的漏洞进行攻击。如果他们在数年内持续使用同一组漏洞,他们的利润最终将几乎降到零。

那么他们如何找到合适的漏洞进行攻击呢?毕竟,每年会报告数千个CVE,但其中只有少数几个可以被纳入攻击工具。武器化一个漏洞通常需要花费大量时间当然,除非有现成的PoC,或者可以从竞争对手那里窃取漏洞,因此攻击者可能首先需要仔细考虑每个漏洞的多个特征。如果某个漏洞在这些特征中得分很高,那么它就看起来是一个合适的攻击工具候选者。以下是一些重要特征:

漏洞的普遍性 影响的用户越多,对攻击者来说就越具吸引力。

漏洞的可靠性 许多漏洞依赖某些假设或基于比赛条件,这使得它们在某些时候失效。攻击者显然更偏好高可靠性的漏洞。

漏洞开发的难度 这决定了攻击者需要花费多少时间来开发漏洞如果他们甚至能够利用该漏洞。攻击者倾向于选择具有公共PoC漏洞的漏洞,这通常使他们可以在最小努力下将其整合到攻击工具中。

针对的精确性 攻击者关心辨识受害者和定向广告方面的难度。如果他们过于频繁地错误辨识受害者意味著他们将漏洞广告推送给无法被利用的受害者,那么他们只会在恶意广告上赔钱。

预期的漏洞寿命 如前所述,每个漏洞随著时间的推移变得不那么有效。然而,漏洞有效性的下降速度可能在不同的漏洞之间变化很大,这主要取决于受影响的软件的修补过程是否有效。

漏洞的可检测性 攻击者需要面对众多旨在保护用户免受漏洞攻击的安全解决方案。这些解决方案可能大大降低攻击工具的成功率,因此攻击者更偏好不易被防御者检测到的隐秘漏洞。

漏洞的潜在性 一些漏洞使攻击者获得System权限,而其他漏洞则可能使得攻击者仅限于在沙盒中执行。潜力较小的漏洞也较无用,因为它们要么需要与其他本地权限提升漏洞链接,要么对最终的恶意载荷的行为施加限制。

综合以上特征,导致基于Chromium的攻击链失败的最可能原因是预期的漏洞寿命。Google在迫使用户安装浏览器修补方面非常有效:Chrome在准备好时会推送更新给用户,并且每个月有时会进行多次更新这与例如Internet Explorer的更新不同,后者是锁定在每月一次的修补星期二的周期中,仅在出现特别严重的漏洞时会有所打破。当CVE202121224还是一个零日漏洞时,影响了数十亿用户。在几天内,几乎所有这些用户都收到了修补。唯一未获得修补的用户是那些手动禁用或破坏自动更新的用户、那些长时间未重新启动浏览器的用户以及那些使用良好修补习惯的Chromium分支。

失败的第二个原因可能归因于糟糕的针对精确性。广告网络通常允许攻击者根据用户浏览器环境的各种特征来定向广告,但特定版本的浏览器通常不是这些特征之一。对于Internet Explorer漏洞,这不那么重要:攻击者可以直接为Internet Explorer用户购买广告。只要一部分Internet Explorer用户对其漏洞有效,他们就会获利。但是,如果他们只是盲目针对Google Chrome用户,则可能有相当小的比例的受害者是脆弱的,这样会使得恶意广告的成本超过从少数脆弱用户那里获利的金额。Google还计划减少UserAgent 字符串中提供的信息。攻击工具通常高度依赖这个字符串来获取有关浏览器版本的准确信息。在UserAgent标头中的信息减少的情况下,他们可能需要设计自定义版本指纹识别,而这将大概率不如之前的版本准确,且管理起来成本较高。

现在我们对攻击工具和Chromium有了一些了解,我们就可以开始推测为什么攻击者决定开发基于Chromium的攻击链。首先,为攻击工具增加新漏洞看起来像是一种试验与错误的活动。虽然攻击者可能对某个漏洞表现如何有一些预期,但他们在实际测试之前,并不能确定它的实用性。因此,当他们试图整合一个漏洞时,结果不如预期并不应该令人惊讶。也许他们错估了漏洞的普遍性,或认为更容易精准到达脆弱受害者,或许他们过于专注于漏洞表现良好的特征:毕竟,他们对于用户数以十亿计的浏览器来说,都有可靠的高潜力漏洞。另外,这可能也只是一次实验,攻击者是希望能探索Chromium漏洞的领域。

还有一点重要的是,过去几年中Internet Explorer的使用率稳步下降目前对于维持攻击工具的存活至为关键。这可能迫使攻击者实验其他浏览器的可行漏洞,因为他们知道迟早要进行转变。但是从这些尝试来看,攻击者目前似乎并不完全能够进行这场转变。这是个好消息,因为这可能意味著如果没有重大变化,攻击工具很可能会被迫在Internet Explorer的使用率降到某个临界值以下时淘汰。

CVE202121224

现在让我们更仔细地看看我们在野外发现的Magnitude攻击链。攻击首先是针对CVE202121224的JavaScript漏洞。这是一个存在于V8的类型混淆漏洞,允许攻击者在沙盒化的Chromium渲染进程中执行任意代码。针对该漏洞的零日攻击或称为issue 1195777,因为当时尚未被分配CVE Id在2021年4月14日被公开在Github上。该攻击对最新的Chrome版本有效,不过Google在大约一周后就赶紧推出了修补。

Magnitude的攻击工具显然受到Github上的PoC的强烈启发。然而,尽管Magnitude的漏洞和PoC遵循非常相似的攻击路径,但并没有相匹配的代码片段,这表明攻击者并没有太多依赖拷贝/粘贴的漏洞开发技术。事实上,Magnitude的漏洞看起来比PoC更清晰和可靠。由于没有使用混淆攻击者可能计划稍后添加,该漏洞非常容易阅读和调试。其中有一些非常易于理解的函数名,如confusiontooob、addrof和arbwrite,以及变量名,如oobarray、arbwritebuffer和oobarraymapandproperties。对我们这些研究者来说,唯一更好的情况就是如果作者留下几条有益的注释

有趣的是,该漏洞的一些部分似乎也受到CTF writeup的启发,该CTF挑战源于CTF 2019,参赛者需要利用引入到V8分支中的虚构漏洞。虽然CVE202121224显然是不同的且实际存在的漏洞,但那篇写作中描述的许多技术对于V8漏洞利用来说仍然适用,因此也被用于Magnitude攻击链的后期阶段,有时甚至使用与写作中相同的变量名称。

攻击的核心,触发漏洞以破坏vulnarray的长度

漏洞的根本原因是V8中的不正确整数转换在SimplifiedLowering阶段。这一错误转换在攻击中由Mathmax呼叫触发,如上面的代码片段所示。如可见,攻击首先以循环方式调用foofunc 0x10000次。这是为了使V8编译该函数,因为该bug只有在JIT编译后才会显现。接下来,调用helper[gcfunc]。该函数的目的是触发垃圾回收。我们测试发现该漏洞即使没有这个调用仍然可行,但作者可能是为了提高攻击的可靠性而将其放在了那里。然后,再次调用一次foofunc,这时flagvar=true,使得xvar=0xFFFFFFFF。如果没有这个bug,lenvar现在应该计算为0xFFFFFFFF,下句语句应该抛出RangeError,因为不能创建负长度的数组。然而,由于该漏洞,lenvar计算的出乎意料的值为1。这是因为漏洞代码在将无符号32位整数0xFFFFFFFF转换为带符号32位整数1的过程中出现了错误。构建vulnarray后,攻击在它上面调用Arrayprototypeshift。在正常情况下,该方法应该移除数组中的第一个元素,因此vulnarray的长度应该为零。然而,由于lenvar的实际值和预测值之间的差异,V8在这里进行了一个错误的优化,将32位常量0xFFFFFFFF放入Arraylength中这是以01计算出来的,其中0是预测的长度,1代表Arrayprototypeshift减少Arraylength。

展示了如何利用vulnarray的覆盖来损坏oobarray的长度

现在,攻击者成功地构建了一个带有损坏Arraylength的JSArray,这使他们能够执行越界的内存读取和写入。可以在confusiontooob函数的最后一个语句中看到第一次越界内存写入。该攻击在vulnarray[0x10]写入0xc00c。这利用了V8中两个当前局部数组的确定性内存布局。由于vulnarray首先被创建,因此oobarray位于内存中的已知偏移量,因此通过对vulnarray进行越界内存访问,可以访问oobarray的元数据以及实际数据。在这种情况下,索引0x10的元素对应于0x40的偏移量,也就是存储oobarray的Arraylength的地方。因此,越界写操作损坏了oobarray的长度,使得能够读取和写入到其结尾以外的内存位置。

addrof和fakeobj攻击原语

接下来,攻击构建了addrof和fakeobj攻击原语。这些是在JavaScript引擎攻击中著名且非常强大的原语。简单来说,addrof泄露一个JavaScript对象的地址,而fakeobj则在给定地址上创建一个新的虚假对象。构建了这两个原语后,攻击者通常可以重新使用现有技术达成最终目标:任意代码执行。

逐步分析addrof原语。注意,仅泄露地址的低32位,而DebugPrint返回整个64位地址。在实践中,这并不重要,因为V8会通过保持所有堆指针的高32位不变来压缩指针。

这两个原语以类似的方式构建,利用了vulnarray[0x7]和oobarray[0]指向相同内存位置的事实。在这里值得注意的是,vulnarray在V8内部被表示为HOLEYELEMENTS,而oobarray则是PACKEDDOUBLEELEMENTS有关V8中内部数组表示的更多信息,请参见V8开发者的这篇博客。这使得可以将一个对象写入vulnarray,并从oobarray的另一端读取更准确地说,读取指向该对象的指针作为双倍数。这正是addrof的实现方式,如上所示。一旦读取到地址,它会使用helper[f2ifunc]从双倍表示转换为整数表示,因为双倍占用了64位,而V8中的指针则压缩到仅仅32位。fakeobj也以相同的方式实现,只是反向操作。首先将指针转换为双倍,通过helper[i2ffunc]。接著,作为双倍写入oobarray[0],然后通过vulnarray[0x7]读取,这欺骗V8将其视为实际的对象。请注意,在fakeobj中无需掩码,因为写入到oobarray中的双倍占用的位数高于从vulnarray读取的指针。

任意读/写的攻击原语

随著addrof和fakeobj的建立,攻击遵循相当标准的攻击路径,这似乎受到上述CTF 2019写作的强烈启发。攻击构建的下一个原语是任意读/写。为了实现这些原语,攻击伪造一个JSArray在上面的代码片段中也被称为fake,使其完全控制元数据。然后,它可以覆盖虚假JSArray的elements指针,该指针指向实际元素存储的地址。损坏elements指针使攻击者能够将虚假数组指向任意地址,然后可以通过对虚假数组的读取/写入来读取/写入该地址。

让我们更详细地看看任意读/写原语的实现。攻击首先调用getarw函数以设置虚假JSArray。该函数首先通过对oobarray[3]的过度读取,以泄露oobarray的map和properties记住oobarray的原始长度为3,而其长度早前已经损坏。map和properties指向描述V8内部对象类型的结构。然后,创建一个名为pointarray的新数组,其第一个元素为oobarraymapandproperties。最后,fake JSArray在pointarray前的0x20偏移量构建。此偏移量经过仔细选择,因此fake对应的JSArray结构与pointarray的elements重叠。因此,通过修改pointarray的元素可以控制fake的内部成员。要注意的是,pointarray中的元素占用64位,而JSArray结构的成员通常仅占32位,因此修改pointarray的一个元素可能同时覆盖fake的两个成员。现在应该明白为什么pointarray的第一个元素被设置为oobarraymapandproperties。第一个元素位于V8查找fake的map和properties的地址相同。因此,通过将其初始化为这样,可以创建一个PACKEDDOUBLEELEMENTS的JSArray,使fake基本上继承自oobarray的类型。

pointarray的第二个元素与fake的elements指针和Arraylength重叠。攻击利用这一点来实现任意读取和写入,首先损坏elements指针,使其指向所需的地址,然后通过fake[0]对该地址进行读取/写入。然而,如上面的攻击代码所示,还采取了一些其他操作,值得解释。首先,攻击始终确保addrvar是一个奇数。这是因为V8期望指针被标记,且最低有效位设置。然后,将2ltlt32添加到addrvar。如之前所述,pointarray[1]中的第二个元素在内存中占用64位,而elements指针和Arraylength都仅占用32位。这意味著对pointarray[1]的写入同时覆盖两个成员,而2ltlt32只是设置了Arraylength,这由最高有效位控制。最后,从addrvar中减去8。因为elements指针不直接指向第一个元素,而是指向一个FixedDoubleArray结构,该结构占用八个字节并位于实际元素数据之前。

一个假设的WebAssembly程序将被Magnitude的shell码替换

攻击的最后一步是将任意读/写原语转换为任意代码执行。为此,它使用了一个众所周知的技巧,利用WebAssembly。当V8 JIT编译WebAssembly函数时,它会将编译代码放置在可写且可执行的内存页中目前似乎有一些新的缓解措施旨在阻止这一技巧,但对于受到CVE202121224影响的V8版本,它仍然是有效的。因此,攻击可以定位JIT编译的WebAssembly函数的代码,将其覆盖为自己的shell码,然后从JavaScript调用原始的WebAssembly函数,这样就可以执行所植入的shell码。

利用工具包与 Google Chrome

Magnitude的攻击首先创建一个虚假的WebAssembly模块,该模块包含一个名为main的单一函数,该函数仅返回数字42此函数的原始代码并不重要,因为它最终将被shell码覆盖。通过addrof和arbread的组合,攻击获得了V8 JIT编译的main的地址。有趣的是,随后它使用具有损坏的后备存储指针的ArrayBuffer构建了一个全新的任意写原语,并使用这刚构建出的原语向main的地址写入shell码。虽然理论上可以利用第一个任意写原语将shell码放入其中,但它选择了第二个方法,这很可能是因为其可靠性更高。似乎第一种方法在某些罕见情况下可能会导致V8崩溃,这使得它不适合重复使用,比如需要多次调用将大shell码缓冲区写入内存的情况。

攻击中嵌入了两个shell码。第一个是针对CVE202131956的攻击。这个攻击将首先执行,目的是窃取SYSTEM权限来提升当前进程的权限。在第一个shell码返回后,第二个shell码被植入到某个正在运行的进程中并执行,从而让Magniber勒索病毒加密受害者的驱动器。

CVE202131956

现在让我们将注意力转向第二个攻击链,Magnitude用来逃避Chromium沙盒的攻击。这是针对CVE202131956的攻击,这是Windows内核中的一个页面池缓冲区溢出漏洞。该漏洞于2021年6月被Kaspersky的Boris Larin 发现,他发现它作为零日漏洞在野外使用,成为PuzzleMaker攻击的一部分。Kaspersky关于PuzzleMaker的博文简要描述了该漏洞以及攻击者选择如何利用它的方式。然而,有关该漏洞的更多信息可以在NCC Group的两篇部分系列博文中找到,作者为NCC Group的Alex Plaskett。这篇博客系列详细介绍了如何利用该漏洞,几乎提供了逐步指南。我们发现Magnitude背后的攻击者非常接近地遵循这篇指南,尽管他们无疑还可以选择许多其他的利用方法。这再次显示,发布漏洞研究结果是一把双刃剑。虽然这篇博文确实帮助了许多人防范该漏洞,但也使得攻击者更容易将其武器化。

该漏洞位于ntfssys中的NtfsQueryEaUserEaList函数内,直接由系统调用NtQueryEaFile可达。此系统调用在页面池中分配一个临时缓冲区其大小由系统调用参数控制,并在此处放置与给定文件相关的NTFS扩展属性。各个扩展属性之间由最多四字节的填充分隔。由于填充直接开始于分配的池区块末尾,因此可以触发整数下溢,导致NtfsQueryEaUserEaList在池区块结束后写入后续扩展属性。利用这一漏洞的想法是喷洒池,以使包含某些Windows Notification FacilityWNF结构的区块能够被溢出破坏。随后使用一些WNF魔法,将解释稍后说明,该攻击获得了一种任意读/写的原语,用以窃取SYSTEM令牌。

该攻击首先检查受害者的Windows版本号。仅支持构建18362、18363、19041和1904219H1 20H2,如果发现运行于其他版本,攻击将退出。然后根据版本号确定进入EPROCESS结构的偏移量以及正确的系统调用编号,因为系统调用由攻击直接调用,绕过了ntdll中的普通系统调用存根。

检查受害者的Windows版本号

接下来,该攻击暴力破解文件句柄,直到找到可以使用NtSetEAFile系统调用来设置其NTFS扩展属性的一个。对此文件设置两个属性,旨在触发在稍后调用NtQueryEaFile时将溢出0x10字节写入下一个池区块。

专门构建的NTFS扩展属性,旨在引发页面池缓冲区溢出

当专门构建的NTFS扩展属性被设置后,攻击就开始喷洒页面池,喷洒WNFNAMEINSTANCE 和WNFSTATEDATA结构。这些结构分别使用系统调用NtCreateWnfStateName和NtUpdateWnfStateData喷洒。然后,该攻击连续创建10000个附加的WNFSTATEDATA结构,并通过NtDeleteWnfStateData释放每第二个结构。这在WNFSTATEDATA区块之间创造了空洞,这些空洞在将来类似大小的池分配中可能被重新利用。

考虑到这一点,该攻击现在使用NtQueryEaFile来触发漏洞,从而有很高的可能性使前面的随机WNFSTATEDATA结构被溢出。如果真的发生这种情况,WNFSTATEDATA结构将如下面所示被破坏。然而,攻击不知道哪个WNFSTATEDATA结构被损坏,这样做的话必须遍历所有结构,使用NtQueryWnfStateData查询其ChangeStamp。如果ChangeStamp包含魔法数字0xcafe,则该攻击就找到了损坏的区块。如果溢出并没有击中任何WNFSTATEDATA区块,攻击会重复尝试触发漏洞,最多32次。注意,在溢出时如果未击中WNFSTATEDATA区块,它也可能会损坏页面池中的随机区块,这可能导致蓝屏死机。不过,在我们测试该攻击时,发现没有在正常攻击中遭遇蓝屏死机,这表明攻击者使用的池喷洒技术相对 robust。

已损坏的WNFSTATEDATA实例。AllocatedSize和DataSize都被人为提高,而ChangeStamp被设置为一个易于识别的值

在成功损坏WNFSTATEDATA后,将更多的WNFNAMEINSTANCE结构喷洒在池中,目的是希望这些结构会重新获取由NtDeleteWnfStateData释放的其他区块。这样做,攻击者试图让一个WNFNAMEINSTANCE区块在损坏的WNFSTATEDATA之后的位置。要解释为什么他们会想要这样做,首先讨论一下通过损坏WNFSTATEDATA所获得的成就。

WNFSTATEDATA结构可以被视为位于内存中实际的WnfStateData缓冲区的前置标头。可以使用系统调用NtQueryWnfStateData读取WnfStateData缓冲区,并使用NtUpdateWnfStateData进行写入。WNFSTATEDATAAllocatedSize决定了可写入WnfStateData的字节数,而WNFSTATEDATADataSize则决定了可读取的字节数。通过损坏这两个字段并设置为高值,攻击者获得了一种相对的内存读写原语,取得在原始WnfStateData缓冲区之后读写内存的能力。现在应该清楚为什么攻击者想要在损坏的WNFSTATEDATA区块后们会有一个WNFNAMEINSTANCE区块了:他们可以利用过度读/写来完全控制该WNFNAMEINSTANCE结构。攻击者只需进行过度读取,扫描过度读的内存以寻找字节03 09 A8,这些字节表示其WNFNAMEINSTANCE结构的开始。如果他们想改变该结构中的某些内容,他们只需修改一些过度读取的位元组,然后使用NtUpdateWnfStateData将其覆写回去。

攻击扫描过度读取的内存,寻找WNFNAMEINSTANCE标头。此处的0x0903代表NodeTypeCode,而0xA8即预选的NodeByteSize。

攻击者想要完全控制WNFNAMEINSTANCE结构的原因是什么?首先,在偏移量0x98处,有WNFNAMEINSTANCECreatorProcess,这使他们获得指向当前进程的EPROCESS的指针。Kaspersky报告说,PuzzleMaker使用了一个单独的资讯泄露漏洞CVE202131955,泄露了EPROCESS基地址。然而,Magnitude的攻击者无需使用第二个漏洞,因为EPROCESS的地址就在眼前。

另一个重要的偏移是0x58,对应于WNFNAMEINSTANCEStateData。顾名思义,这是指向WNFSTATEDATA结构的指针。通过修改这一指针,攻击者不仅可以扩大WnfStateData缓冲区,还可以将其重定向到任意地址,从而获得任意读/写原语。然而,这里有一些约束,因为StateData指针必须指向要读写的地址的0x10字节之前,并且该处必须有某些能被理解为WNFSTATEDATA结构的数据。

StateData指针首次设置为EPROCESS0x28,这使得攻击可以读取KPROCESSThreadListHead有趣的是,这个值使用的是ChangeStamp和DataSize进行泄露,而不是通过WnfStateData。ThreadListHead指向第一个线程的KTHREADThreadListEntry,该线程在Chromium攻击的上下文中正是当前线程。通过减去ThreadListEntry的偏移,该攻击获得了当前线程的KTHREAD基地址。

获得KTHREAD的基地址后,攻击将StateData指向KTHREAD0x220,这使得它可以从KTHREAD0x230读取写入多达三个字节。攻击利用这一点将位于KTHREAD0x232的字节设置为零。在目标Windows版本中,偏移0x232对应于KTHREADPreviousMode。将其值设置为SystemMode=0会欺骗内核,让其信服某些线程的系统调用实际上来自内核。具体来说,这使得该线程可以使用NtReadVirtualMemory和NtWriteVirtualMemory系统调用在内核地址空间中进行读写。

攻击损坏KTHREADPreviousMode

与Chromium