本系列文章为看雪星星人为看雪安全爱好者创作的原创免费作品。
欢迎评论、交流、转载,转载请保留看雪星星人署名并勿用于商业盈利。
本人水平有限,错漏在所难免,欢迎批评指正。
要对一个设计进行漏洞分析,首先必须用完整的逻辑描述出整个设计。很明显,这是在设计阶段就应该开始做的事。本书将这部分内容放在这里,仅仅是由于行文的顺序,而不意味着项目真正实施的顺序。
设计来源于需求。在5.1.1节中,我们明确了需求的预期。这里再重复如下:
“Windows11用户态包括管理员权限的任何权限环境下任何PE文件的加载执行都能被拦截,并可根据用户的判断选择放过执行或阻止执行。”
一个完整的软件产品设计往往由一组功能点的设计组成。本书的执行模块防御模块的设计出现在本书第二章的2.3.1节中,整个系统的设计由如下的5条规则组成。其中每个规则可以看出一个功能点。
规则2.1:在安全系统初次安装之后,系统中的可疑库为空,不存在任何可疑路径。
规则2.2:新的可执行文件创建时,将其路径加入可疑库中。
规则2.3:原有的可执行文件的内容被覆盖或被修改时,若修改后的内容是一个可执行文件,将其路径加入可疑库中。
规则2.4:当某可疑文件被改名,那么对应可疑库中的可疑路径应该随之更新。但非可疑文件被改名并不会有任何影响。
规则2.5:当某可疑文件被执行时,对文件内容计算散列值,如果散列值在散列值白库中,则执行并从可疑库中删除,否则禁止执行并将该散列值上报到后台。有必要的话,同时上报完整样本。
当然以上只是本书举出的小规模的范例。真正的产品设计规模会远比这个大,可能需要很多篇幅才能列出。但无论如何,完整的需求和设计都必须明确地列出来。需求和设计明确了之后才有可能进行漏洞分析。那么如何进行漏洞分析呢?
首先要明确的是,造成设计漏洞的原因永远都在于用户需求和技术实现之间的巨大鸿沟。
一般而言产品由产品经理设计。产品经理会比较了解用户需求,然而对技术不甚清楚。改为由精通技术的开发人员来设计也会面临类似的问题:开发人员精通技术然而不懂甚至不关心用户的需求。
用户需求和技术一样,都是五花八门博大精深的。试图去寻找一个“全能”的人材来同时兼顾需求和技术是不可能的。因此,在设计的漏洞分析中,最关键的是弥合针对需求的设计与技术实现之间的距离。
因此,对每个功能点进行漏洞分析的步骤为:
(1)与开发人员沟通,该功能点在技术上是否可行。如果不可行,则将功能点修改直至可行为止。
(2)对于技术可行的功能点,判断其逻辑上是否完备符合需求。如果不符合则存在漏洞。对于漏洞,要么修改逻辑直至漏洞消失,要么接受漏洞的存在,并将风险转移到产品之外或者接受风险。
(3)如果(2)中为了解决漏洞已经修改了功能点,那么必须回到(1),循环至(2)的结果为不再修改为止。
举例来说,功能点规则2.1表示,在安全系统安装之初,可疑库为空,也就是说任何文件都不是可疑文件。这在技术实现上没什么问题,但逻辑上显而易见存在一个漏洞:如果在安全系统安装之前,恶意文件已经存在了怎么办?
对于这个漏洞,我们选择接受。因为在安全系统安装之前,可以使用全盘扫描,或是标准化的环境安装(全面格式化并统一安装全公司标准化的初始环境)来解决这个问题。那么漏洞即便还存在,也属于全盘扫描或者是标准化安装流程了,和主机防御不再有任何关系。因此,风险被成功转移。
再看功能点规则2.2:“新的可执行文件创建时,将其路径加入可疑库中。”这其实潜在意味着,系统中只要有新的可执行文件创建,就必须被安全系统捕获到。这是一个技术问题,必须与开发人员进行沟通。
最初开发人员断然拒绝了这一要求。他们认为在一个系统中捕获所有的可执行文件的创建是不可能的。因为在系统中创建文件有太多的方法,不可能被完全捕获。
但是当他们注意到需求规定的环境:“Windows11用户态包括管理员权限的任何权限环境下”,这已经明确了是用户态程序发起的文件创建操作。考虑到用户态创建文件必须通过Windows内核,利用内核驱动来完全捕获所有的用户态的文件创建是可能的,开发人员最终接受了这一设计。
当然,上述论断的前提是Windows内核没有相关漏洞,导致用户态程序能在创建文件时能绕过文件系统的过滤而创建出一个文件。这个前提大概率是不正确的。但对于无法从内部弥补的外部漏洞,我们选择不承担责任。
规则2.3、2.4和2.5与规则2.2是类似的,其逻辑不存在什么问题,关键是技术能否实现。当开发人员确认可以实现,那么这个设计的功能点就通过了漏洞分析,可以继续下一步操作了。
当每个功能点分析完毕,接下来我们必须综合所有功能点,来看总体而言它们是否满足了需求。
实际的安全项目中常见的问题是,各个功能点已是技术可行且逻辑完备的,它们综合起来似乎也符合需求,但最终使用才发现实际效果和需求并不真正吻合。
原因在于设计者认为设计已符合需求,往往是建立在一系列看似显而易见的前提上(正如论文中常见的“显而易见”“众所周知”等)。然而这些假设没有经过专业技术人员的认真审视,又或者刚好超出了所有评审人员的所知范围,导致留下巨大的漏洞。
在审视设计的时候,一定要将所有这些显而易见的前提列出,逐个审核这些前提,再综合考虑最终的结果。因此设计的综合漏洞分析步骤如下:
(1)如前文完成每个功能点的漏洞分析。
(2)综合所有功能点的效果,查看效果与最终需求是否等同。如果不等同,要么接受漏洞,要么修改功能点并回到(1)。如果接受漏洞后等同了,必须找出它们“等同”所必须的所有前提。
(3)与技术人员充分沟通,并集思广益地评审(2)中发现的所有前提的技术可行性。如果存在问题,往往能发现漏洞。要么接受漏洞,要么修改功能点并回到(1)。
最终的效果是所有的漏洞都已明确解决(修复或接受了),所有前提都是技术可行的。除了已接受的风险外,功能点综合效果和最终需求等同。
请注意我用了“等同”,而不是“吻合”或者“符合”,原因就是后两者很容易让人掉以轻心。当我们认为设计A的效果“符合”需求B的时,其中往往暗含着大量的坑。如果我们的追求是设计A的效果“等同”需求B,结局会稍微好上一点点。
回到本书的例子。规则2.1至规则2.5总体而言,其意义是对原有的文件置之不理,而对任何新建的PE文件、被修改过的PE文件均根据路径标记可疑,然后再在执行时对可疑文件进行检查。而需求则是去除接受的原有文件的风险之外,是“除了机器上原有的文件之外,任何PE文件的加载执行都能被拦截,并可根据用户的判断选择放过执行或阻止执行”。
这设计效果符合需求吗?乍一看非常符合。新建的、新被修改的PE文件,不正符合“除了机器上原有文件之外任何PE文件”的需求吗?
所以我才强调我们的追求一定必须是效果“等同”需求。“新建的、被修改的PE文件”等同“除了机器上原有的文件之外任何PE”文件吗?至少字面上它们是不等同的。要等同就暗含了一个前提:
“机器上除了原有文件之外,如果出现任何新的PE文件,要么是创建出来的,要么是修改了原有文件形成的。”
这在一般人看来再合理不过了。一个机器上除了原来就存在过的文件之外,那不就是新建的、或者老文件修改内容变成的新文件吗?这有什么可疑?
但我们也可以反问一下:“不新建文件、也不修改任何文件,能不能让机器上出现一个前所未有的新文件?”
实际上,安全系统的漏洞分析的过程,就是不断找出安全系统的真实限制条件,并反问在这些限制条件下,能否实现绕过安全系统的阻碍的过程。
有些情况技术人员也可能一时想不到,但对另一些人(不一定需要是技术人员)来说,这可能是常识。因此在评审这些看似显而易见的前提时一定要集思广益,充分沟通。
文件并不一定要通过“新建”才能出现。磁盘的挂载也会导致大量新文件的出现。装满了PE文件的U盘插到电脑上,电脑上并未新建任何文件,也没有任何老文件被修改,然而大量的新的PE文件就这样凭空出现了。
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)
最后于 2024-8-1 08:58
被星星人编辑
,原因: