现在,越来越多的人谈论静态分析来搜索漏洞是发展的必要阶段。 但是,许多人都在谈论静态分析的问题。 在过去的“
积极黑客日”上 ,我们进行了很多讨论,基于这些讨论的结果,
我们已经撰写了有关静态分析器
如何工作的文章。 如果您尝试使用任何严肃的工具,可能会因为冗长的报告,令人困惑的建议,设置工具的困难和误报而被吓到。 那么仍然需要静态分析吗?
我们的经验表明需要什么。 而且,当您初次使用该工具时会遇到许多问题,因此很可能可以解决。 我将尝试告诉您用户可以做什么以及分析仪的外观如何,以便其使用很有用,并且不会引入“安全人员需要的另一种不必要的工具”。
关于静态分析
因此,我们已经讨论了静态分析的理论局限性。 例如,深度静态分析试图解决复杂度呈指数级的问题。 因此,每种工具都在时间,资源消耗,发现的漏洞数量以及误报数量之间寻求折中方案。
为什么我们需要深入分析? 任何IDE都会很快发现错误,有时甚至会发现与安全相关的错误-通常是什么指数问题? 一个经典的示例是SQL注入(以及任何其他注入,例如XSS,RCE等),它通过多个功能(即,从用户读取数据并执行查询发生在不同的功能中)。 它的搜索需要对数据流进行过程间分析,这是指数复杂的任务。 同意,如果不搜索此类漏洞,就不能认为分析深入。 出于同样的原因,您需要对代码进行整体分析,而不是部分分析-否则可能会遗漏过程间漏洞。
近年来,我在与各种静态分析仪的(潜在)客户进行交流方面获得了很多经验。 特别是,我们将根据首次使用(试验)的结果来讨论对工具的主张。 大多数主张都以某种方式源自该技术的理论限制。 另外,工具可能根本不具备用户所需的功能。 但是,在我看来,分析仪可以解决下面指出的问题,并朝着用户移动。 但是,您还需要能够使用分析仪,以平衡相同问题的后果-事实证明,这并不那么困难。 让我们去吧。
您可以想象一个模型情况:您决定尝试运行该技术或选择一个静态分析器-进行试验。 当然,您不信任供应商的测试用例,而是想尝试分析您的代码(同时您可以找到真正的漏洞并加以修复)。 在短时间内为您提供了安装程序或带有系统的成品虚拟机。
运行分析
首先,您需要运行分析。 您进入界面,一切似乎都很清楚:将包含源代码的存档上传到表单中,然后单击“分析”。 但是没有:您会得到几种具有不同字段的表格,需要以某种方式填写。 必须指定编程语言,一些分析器设置,选择漏洞软件包(您如何知道其中包含的内容?)等等。 您通过了此测试,分析便开始了。 啊,不-扫描错误。 “格式不符合要求”,“该语言需要代码汇编”,“未找到扫描文件” ...如果您自己未编写此代码,则仍然必须向开发人员寻求帮助。
开发人员移交源代码进行测试特别注意建筑规范的要求。 用于多种语言的大多数分析器都要求在分析过程中收集代码(JVM语言-Java,Scala,Kotlin等,C / C ++,Objective-C,C#)。 您了解这是多么痛苦:复制大型项目的环境以在新机器上进行组装。 另一方面,这些要求是合理的;它们是根据分析技术和这些语言的细节而来的。
分析仪如何解决这些问题? 首先,他们使分析的启动尽可能自动化。 理想情况下,下载任何格式的文件就足够了,分析器本身必须了解其中存在哪些语言,如何尝试构建以及如何默认情况下设置其余设置,以使结果尽可能完整。 显然,不可能预见所有事情-但是,您可以尝试处理大多数情况。
需要使组装要求尽可能软。 例如,对于JVM语言,您不需要在分析过程中进行汇编-只需请求加载工件即可,即,将汇编代码与源代码一起加载(这要简单得多)。 对于Xcode,在Objective-C的情况下,大多数情况下都可以使程序集自动化。 如果无法收集代码,则分析器可能会尝试进行部分分析。 它的结果不会那么完整,但是总比没有结果要好。 如果可以将分析模块放在已经配置了代码组件的开发人员的机器上,那么该结构也应该很方便,而该体系结构应允许将其他模块和接口部分转移到另一台机器上。
最后,分析器应提出最软的格式要求,并处理输入文件本身。 具有源代码的归档文件,嵌套的归档文件,来自存储库的归档文件,到存储库的链接,产品的归档文件,产品的可执行文件-如果分析仪支持所有这些功能,则很好。
但是,请不要忘记分析仪没有人工智能并且无法预见一切。 因此,如果发生错误,您应该熟悉手册-在准备分析代码时有很多有用的东西。 好了,在分析器实现期间启动扫描的所有这些工作对于每个代码库都只完成了一次。 通常,分析仪通常集成到CI周期中,也就是说,组装不会有问题。
分析过程
好的,扫描已经开始。 一个小时过去了-没有结果。 进度条挂在中间的某个位置,尚不清楚完成什么百分比和完成什么预测。 第二个小时过去了-进度已经移动了99%,并且已经暂停了半个小时。 第三个小时过去了,分析仪崩溃了,报告内存不足。 或再挂一个小时并结束。 您可以期望分析以与您的检查样式相同的速度通过,并且期望在这里将与现实大相径庭。
是的,一个好的静态分析器会消耗很多资源,我指出了上述原因之一:发现复杂的漏洞是一项艰巨的任务。 因此,拥有的资源越多,时间越长,效果就会更好(当然,使用好的引擎)。 预测分析时间和所需的资源确实非常困难-静态分析算法的运行时间在很大程度上取决于语言结构,代码的复杂性,调用的深度-难以预先计算的特征。
资源问题是必然的弊端。 您需要小心分配必要的资源,耐心等待扫描完成,并且还要了解,即使使用给定的代码库,也没有人能准确预测分析仪所需的资源,因此必须准备更改这些参数。 此外,由于分析仪的更新,即使不更新代码库也可以更改所需的参数。
不过,分析仪可以帮助解决这个问题。 它能够将资源密集型部分(引擎)和接口分离到不同的机器中。 这样一来,您就不会在计算机上加载不必要的程序,从而减慢了它们的工作速度,同时有可能使用系统界面来处理扫描中的任何工作负载(例如,查看和编辑结果)。 这样还可以轻松扩展,而无需重新安装整个系统(我们将分析仪放在新的虚拟机上,指定主机的IP-瞧)。
此外,分析器可以允许您选择分析深度,禁用大量检查,使用增量分析(在此情况下,不是所有代码都被检查,而是仅被更改)。 这些东西必须非常小心地使用,因为它们会极大地影响扫描结果。 如果使用这种功能,建议您每隔一段时间进行一次完整的分析。
分析结果
让我们继续扫描结果(很长一段时间我们去过它们)。 您在等待分析器窗口中的漏洞数量时感到不安,感到非常惊讶。 156重击,1260重击和3210重击 您转到结果页面并淹没在发现的问题中。 您下载pdf报告,然后看到数千页的文本。 猜猜代码开发人员在看到这样的画布时会说些什么?
保安人员正在向开发人员报告漏洞但是,让我们仍然尝试查看结果,给他机会。 在仔细检查了数十个事件之后,您开始理解为什么存在这么多漏洞。 您知道有几个漏洞确实很严重,您需要修复它们。 但是,立即发现大约十二个错误。 而且-库代码中的大量漏洞。 您将不会更正库! 然后,您将了解将花费多少时间来分析结果。 并且必须每天,每周,至少每一次发行都重复此过程。 (实际上不是)。
首先,可以用非常不同的方式来理解误报。 有人不会只将目前可以利用的关键漏洞视为虚假。 有人会认为错误仅是分析仪的显式错误。 在很大程度上取决于您对工具的需求。 我们建议您考虑几乎所有情况,因为即使现在无法利用的低级漏洞也可能在明天变成严重问题,例如,由于代码和外部条件的更改。
好的,您需要查看所有条目,但这仍然是大量的工作。 在这里,分析仪可以提供很好的帮助。 分析器最重要的功能是能够跟踪一个项目的两次扫描之间的漏洞,同时保持对它的跟踪能力可以抵抗代码开发标准的小改动。 这就消除了需要重复对漏洞进行长时间分析的问题:您第一次花更多的时间,消除误报并更改事件的严重性,但是随后您只需要查看新的漏洞,该漏洞会小很多倍。
很好,但是是否有必要第一次审查所有漏洞? 我们建议您这样做,但是一般而言,这是没有必要的。 首先,分析器允许您按目录和文件过滤结果:例如,当您开始扫描时,您可以立即从分析中排除任何组件,库,测试代码。 这将影响分析速度。 其次,分析器允许您按漏洞过滤结果,即,当您开始扫描时,可以限制漏洞的集合。 最后,除了严重性之外,分析器还可以产生类似虚假漏洞的可能性(即,它对该漏洞的信心)。 使用此指标,您可以过滤结果。
另外,值得注意的是软件组成分析技术(现在开始受到越来越多不同级别仪器的支持)。 该技术使您可以检测代码中库的使用,确定名称和版本,显示已知漏洞以及许可证。 该技术可以将库代码与您自己的库代码分开,这也可以过滤结果。
事实证明,您可以处理分析结果丰富的问题,这并不是很难。 而且,尽管第一次查看结果确实需要花费一些时间,但是当您对其进行扫描时,将花费越来越少的时间。 但是,我再次指出,对结果进行任何过滤时都应该小心-您可以跳过此漏洞。 即使该库是已知的,也不意味着该库中没有漏洞。 如果现在检测不到此漏洞(也就是说,该工具对该漏洞显示很多误报),并且将其禁用,则在更新分析器时,可以跳过真正的漏洞。
检查分析仪
了解大报告和误报。 但是,您想走得更远-确保分析器找到那些您肯定知道的漏洞(您可以故意放置它们,或找到其他工具)。
首先,重要的是要了解分析仪由于各种原因找不到该漏洞。 最简单的事情是扫描配置不正确(您需要注意错误消息)。 但是从分析技术的角度来看,原因可能有所不同。 静态分析器包含两个重要组件:引擎(它包含所有算法的复杂性和数学原理)和漏洞搜索规则的基础。 一种情况是引擎允许您找到此类的漏洞,但规则库中没有漏洞。 在这种情况下,添加规则通常并不困难。 如果引擎原则上不支持此类漏洞,则情况完全不同-在此修订可能非常重要。 我在本文开头给出了一个示例:没有数据流分析算法就永远找不到SQL注入。
静态分析器应在引擎中实现一组算法,这些算法涵盖给定编程语言(控制流,数据流,间隔分析等)的可用漏洞类别。 重要的一点是能够向工具添加您自己的漏洞搜索规则-这将消除丢失漏洞的第一个原因。
因此,如果您没有在扫描结果中找到现有漏洞,则首先需要找出跳过的原因-通常,供应商可以提供帮助。 如果原因是在规则库中或在扫描配置中,则可以很容易地消除这种情况。 最重要的是评估分析的深度,也就是说,原则上您可以搜索引擎。
胜任力
在这里阅读完本文之后,我们可以假定要使用该工具,需要开发人员的深厚专业知识,因为您需要了解哪些回答是错误的,哪些是正确的。 我认为,这完全取决于仪器的操作友好程度。 如果它提供方便且易于理解的功能,易理解的漏洞描述以及不同语言的示例,链接和建议,并且该工具显示了与数据流分析相关的漏洞的踪迹,则您无需具备开发人员的专业知识即可了解编程语言的所有精妙之处以及框架。 但是,为了阅读代码,开发背景应该最少。
开发过程中的整合
在本文的结尾,我们简要介绍了使用该工具的最重要问题之一,我们将在以下文章中对其进行详细考虑。 假设您决定使用静态分析器。 但是,您已经建立了既有技术又有组织的开发流程,并且不想更改它(没有人会提供)。
该工具应具有完整的非图形界面(例如CLI或REST API),您可以使用该界面将分析仪集成到任何流程中。 分析仪可以与各种组件进行现成的集成是很好的:IDE或构建系统的插件,与版本控制系统的集成,CI / CD服务器(Jenkins,TeamCity)的插件,与项目管理系统(JIRA)的集成或与用户的合作(活动目录)。
如果静态分析已经很好地建立并且所有参与者都同意并且知道为什么这样做,那么将静态分析集成到开发过程中(所谓的SDLC)是使用它的最有效方法。 在对分析器进行更改或更新之后,对代码进行不断的分析将使您能够尽早发现漏洞。 信息安全开发人员和专家的角色分离,信息安全要求的明确指示以及与当前流程的软集成(例如,起初是系统的咨询性质),将使您轻松而有用地使用该工具。 但是,如果您的开发模型并不意味着类似的过程,则没有人会取消手动使用该工具。
总结
本文包含有关开始使用静态分析器的基本建议。 一个好的分析器比任何轻量级的检查器都好一个数量级;它可以找到根本不同的复杂性问题。 因此,有必要将静态分析的功能视为一项技术,但同时选择一种特定的工具,以使其功能最大程度地消除所有这些功能。