-
-
[原创]Windows主机入侵检测与防御内核技术深入解析(11)
-
发表于: 2024-9-24 08:34 7661
-
本系列文章为看雪星星人为看雪安全爱好者创作的原创免费作品。
欢迎评论、交流、转载,转载请保留看雪星星人署名并勿用于商业盈利。
本人水平有限,错漏在所难免,欢迎批评指正。
前文内容请见Windows主机入侵检测与防御内核技术深入解析(1)-(10)。
漏洞分析提示的只是漏洞存在的理论可能,并不能确认漏洞真正存在。这种尚未被确认的漏洞只能称为潜在漏洞。只有编写出“利用”并实现攻击的漏洞,才能确认是真正存在的漏洞,可称为确实漏洞。
上文的利用是利用验证演示程序(即PoC)的简称,是名词而非动词,指一段演示代码,能演示利用漏洞进行的攻击。攻击必须是成功的。而渗透测试,实际上就是针对漏洞编写利用的过程。
安全系统的开发团队工作的方式和渗透测试团队是不一样的,但编写漏洞利用依然有很大的用处。
对潜在漏洞成功地编写漏洞利用可以确认漏洞存在。虽然未能成功地编写出漏洞利用并不彻底否认漏洞的存在,但能评估利用该漏洞进行攻击的难度。如果攻击难度非常高,那么修补该漏洞的优先级就可以相应地靠后。
漏洞利用也是在漏洞修补之后进行验证的必要工具。如果没有漏洞利用,那么漏洞即便得到了所谓“修补”,也是完全无法验证的。那么和没有进行修补的区别在哪呢?
如果开发团队不编写利用,那么利用就将由渗透测试人员甚至是恶意攻击者来实现,而项目付出的成本将会急剧飙升。
在5.2.1节的设计漏洞分析曾经提出了U盘插入漏洞。如果一个装满了可执行文件的U盘被插入到主机,由于这个过程并不涉及文件的写入,安全系统将无法发觉这些可执行文件的加入,从而默认它们都是原来就存在的可信的文件。
这个利用很容易实现,甚至不需要编写代码。测试中操作者将U盘插入,然后鼠标双击U盘中存在的可执行文件即可。如果可执行文件被成功执行,即绕过了安全系统的防护。
但和渗透测试人员不同,开发者编写利用的过程中需要不断思考“如果禁止这样做,那么是否还能绕过”的问题。这样才能逐步触及问题的本质。而开发人员是了解系统实现的原理的,因此比渗透人员做同样的工作成本要低得多。
就如上这个问题,开发者应继续追问:“如果禁止插入U盘,是否还能利用这个漏洞呢?”
除了插入U盘之外,还有其他操作能让文件不经过文件系统创建就“出现”在系统中。比如添加虚拟盘。如加载一个ISO文件,系统中将出现一个虚拟盘。但这些操作的共同特点是,系统中将出现新的盘符。
系统存在漏洞并不是一件糟糕的事。糟糕的是漏洞存在却无人知道,或者有人知道却不知如何利用。当利用明确,那么修补的方式也同时明确了。如果该漏洞的本质是出现新的盘符未被考虑,那么修补有如下的选项:
n 禁止任何新盘符出现。这适合那些禁止插入任何可移动存储设备的环境。
n 允许出现新盘符,但是任何新盘符上的可执行模块都一律禁止执行。这种策略适合大多数普通办公的环境。
n 允许出现新盘符。同时新盘插入时,自动扫描盘上所有可执行文件并加入可疑链表中。这种适应性最好,但是开发成本高、且容易带来更多潜在漏洞,不是经济且可靠的选择。
在考虑到“新增盘符”是一个漏洞的情况下,分析者也应同时考虑“新增路径”是否存在漏洞?因为新增盘符的本质是增加了新的路径的可能。但不一定需要增加盘符,也可能新增可执行文件的路径。比如说,通过文件重定向、创建软链接等形式,可以让一个可执行文件以不同的路径来执行。
看起来对原本存在的文件新增路径并不会带来任何问题,但是可疑文件也可能新增路径。
尝试编写这样的利用:一个文件被复制进入系统,从而它的路径进入了可疑库。但是,攻击者设法为它创建了一个链接,从而诞生了一个新的路径。然后不知情的用户点击了新的路径。安全系统拦截到了模块执行,但比对显示其路径并不在可疑库中,因此被放过,从而绕过了系统!
这其中的关键是,能否创建一个链接产生新的路径,让微过滤驱动获得的路径并非原始的,而是新的路径?如果要修补漏洞,那么在微过滤驱动中如何获得文件的原始路径?这正需要编写利用去证实或者证否,请读者自己完成。
5.2.2节的技术漏洞分析指出,文件映射读写将会绕过仅仅对非分页文件些写进行处理的微过滤驱动程序的拦截。这从理论上可行,利用编写也比较简单。网上很容易找到利用内存映射方式读写文件的例子。
内存映射读写带来的问题是:这种读写方式并不会直接触发文件读写操作。在这里请回顾图3-2。在用户态使用API函数WriteFile来写入文件的时候,微过滤驱动能拦截到非分页的普通请求(IRP),因而能得到处理机会。
但通过内存映射读写文件的时候,被写入的是内存而不是文件,因此不会发生这种请求。同时内存写入之后,图3-2中的文件缓存将被改写。程序读取文件的时候会从文件缓存中读取,因此文件的内容本质已经被改变。
文件缓存和硬盘上的真实文件可以不一致,这无关紧要。在需要同步的时候,Windows内核通过分页请求将最新的文件缓存内容写入磁盘。这时微过滤驱动是可以拦截到磁盘写入请求的。
但遗憾的是请回顾代码3-1中的1处,其中存在一个恰好跳过分页请求的标记FLTFL_OPERATION_REGISTRATION_SKIP_PAGING_IO。因此,本书示例的安全系统将拦截不到这种请求。
这个利用的编写应该比较简单,因此本书并没有给出实际的代码,建议读者自己尝试编写。但要注意的是,这个例子的编写成功并不意味着漏洞能真正被利用。这和5.4.1节中的盘符与路径漏洞不同。
对于盘符漏洞,用户只要捡起一个可疑的U盘插入系统,然后双击执行,就破坏了安全系统的防护。而在本节的内存映射读写文件的利用编写出来的可执行文件本身是新产生的可疑文件,会直接被模块防御阻止,因而无法攻击成功。开发者会以此种攻击无法实现作为理由而拒绝修复漏洞。
因此在提供利用时,我们有必要说明真正实现攻击的途径。虽然直接编写一个可执行文件来实现攻击是不可行,但我们完全可以设想现实场景中可能的真正攻击。
假定有某个合法的下载工具,比如浏览器,或者FTP客户端等等,它在保存文件到本地的时候用的是内存映射方式(这种可能性存在的概率是极大的)。
不知情的用户用该工具从网上下载一个恶意文件保存到本地时,模块防御因为拦截不到写入操作而无法将它加入可疑库。当用户再无意地执行它的时候,防御措施就被彻底绕过了。
经过这样的评估,开发者会意识到此处的漏洞是极为严重的。因为内存映射读写文件在各类工具软件中广泛存在,该漏洞足以让加强主机防御系统的一切努力都付之东流。如果不修复它,其他所有的工作都是白费。
理论上要修复这个漏洞就必须过滤内存读写。但是在系统中过滤内存操作是难度极大的工作。实际上我开发客户端内核安全组件十余年,大多数时间做的都是这件事。想要普适性、高性能、精准地过滤拦截内存读写几乎是不可能的。
假定无法过滤内存读写,似乎这个漏洞就永远是存在的。因为通过内存读写就能修改文件缓存,也就实质修改了文件内容。如果这个被修改后的文件可以不刷入磁盘就直接作为可执行文件执行,那就变成了无法捕获的幽灵。
好在天无绝人之路。由于Windows在执行文件之前会先将所有缓存刷入磁盘,因此一定有非分页写请求产生(图3-1中的分页IRP)。因此在去掉FLTFL_OPERATION_REGISTRATION_SKIP_PAGING_IO之后,过滤分页IRP即可捕获这种情况。
要注意的是捕获分页请求的回调处理更麻烦,因为中断级更加不确定,编码需要更加小心。请参考微软的文档和范例自行完成。
对于5.4.1节和5.4.2节中分别提到的两个利用,本书都没有提供实际的例子。这两个利用要么可以通过简单的操作实现,要么利用的编码比较简单。但本节的漏洞涉及到一种不同寻常的技术,因此我会提供相应的例子。
在安全系统中,越是不同寻常的技术反而最有可能带来风险。因为不同寻常,较少应用,因此不广泛为人所知,这使得在安全系统的开发中往往被遗漏或者忽视。但较少应用或者较少为人所知并不影响它的有效性。
NTFS的事务(TxF)是一种极少被提及的技术。它的本意是给NTFS加入类似数据库的事务的特性,让开发者可以实现一组原子化的操作。
比如一个文件可以被修改、被改名等等,但这一组操作被视为一个事务。如果该事务不提交或者提交失败,那么其中所有的操作都一并作废。相反地,如果提交成功,那么这一系列操作则同时生效。
这个想法非常好,但从推出之后,此技术很少被开发人员使用,以至于微软也不再愿意继续提供此技术。但微软也不能贸然将它删除,因为可能有些软件已经使用了它。所以微软在文档中强烈推荐开发者不要继续使用事务,如图5-2所示。
图5-2 微软在文档中强烈推荐开发者不要继续使用事务
很多情况下开发者可能会认为,既然微软已经强烈推荐不要再使用它,而且实际使用它的人也很少,那么我们正可以明正言顺地忽视它,更不用投入宝贵的人力在它上面。
但对安全系统的开发者来说刚好相反。微软表示将来可能弃用,正说明现在没有弃用它。使用它的人少,正说明这技术极有可能被开发者忽视,而被恶意攻击者注意到,并利用起来攻击现有的系统。
所以安全系统的开发者往往需要去关注很多小众、麻烦、成本过高不会有人那么去做的技术。因为这些东西都是攻击者甘之若饴的宝藏。
知道的人少或者应用不多丝毫不会提升攻击者使用它的难度。而成本过高很可能是对正常软件项目而言的。对恶意攻击者来说,写几千行代码只为实现一个小小的跳转丝毫也不显得成本高昂。
下面考虑一下如何利用事务来实现攻击。本例的模块防御的技术基础是使用微过滤驱动拦截文件系统操作。事务的特点是可以让操作产生、被拦截到,但最后轻而易举地消失(只要不提交就等于不生效)。
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课