jar第三方组件Dependency-check依赖检查工具

0x00: 工具介绍

dependency-check是一款根据项目依赖来检查漏洞的白盒审计工具。他根据项目中的依赖库,搜集依赖的版本,厂商等信息,然后匹配NVD漏洞库,对比其中的CPE来确定此版本的依赖包是否存在漏洞。他虽然最主要是用来检查java项目的依赖,但是对于js,c/c++,python,它也是具有一定的检查能力。

它支持多种使用方式,各有优缺点。无论是jar包,还是目录,或者压缩文件,他都能自动识别。

0x01: 安装与运行

2.1 相关链接

Dependency Check官网:

https://www.owasp.org/index.php/OWASP_Dependency_Check
Dependency Check官方文档:

https://jeremylong.github.io/DependencyCheck/index.html
Dependency Check有三种使用方式:
从命令行使用:此时Dependency Check作为一个单独的软件,与项目无关,使用时只需指定需要扫描的项目位置即可。在业务上线流程中推荐使用此方式
作为插件在项目中使用:此时需要在项目的配置文件中做相关内容添加,只对当前项目有效。别的项目需要使用时,需要重新修改配置文件
作为Ant Task使用:这种方式的使用介于以上两者之间,可以在多个项目中使用,但是需要安装,并且需要在项目的build.xml中添加相关配置。

2.2 从命令行使用

安装流程

从命令行使用时Dependency Check作为一个单独的软件,需要从官网下载。

官网右侧Quick Download目录下选择Command Line即可。

或者直接点击本链接:

http://dl.bintray.com/jeremy-long/owasp/dependency-check-2.1.0-release.zip

下载后解压即可使用。如果是windows平台,运行bin目录下dependency-check.bat;如果是linux,运行dependency-check.sh;如果是mac平台,使用brew install dependency-check即可安装。

注意:第一次扫描的时候会需要等待很长时间。因为Dependency Check需要将从NVD下载数据库,则可能需要花十分钟甚至二十分钟。在这之后,只要两次扫描的间隔时间不超过七天,就只需要维护一个很小的xml列表,它会在每次启动扫描的时候自动更新,大约只需要一分钟左右。

如何使用

windows使用dependency-check.bat –project “My App Name” –scan “c:\java\application\lib”

–project用于指定这个扫描项目的名字(不是要扫描的项目,而是扫描这个任务的项目名字,可以随便指定)

–scan指定要扫描的压缩文件或者目录。Linux平台类似,只是把.bat换成.sh。第一次使用会很慢,因为要下载相应的NVD库。

dependency-check支持多种格式的文件:Zip archive format (*.zip, *.ear, *.war, *.jar, *.sar, *.apk, .nupkg); Tape Archive Format (.tar); Gzip format (*.gz, .tgz); Bzip2 format (.bz2, *.tbz2)。
使用dependency-check –help获取帮助信息。

2.3 作为项目插件使用

作为maven插件

这种方式需要Maven版本在3.1或者之后。需要在maven的项目依赖你添加dependency-check的依赖如下:

<dependency>
<groupId>org.owasp</groupId>
<artifactId>dependency-check-maven</artifactId>
<version>2.1.0</version>
<dependency>

然后添加插件申明:

<project>
...
<build>
...
<plugins>
...
<plugin>
<groupId>org.owasp</groupId>
<artifactId>dependency-check-maven</artifactId>
<version>2.1.0</version>
</plugin>
...
</plugins>
...
</build>
...
</project>

此时在IDEA的右侧maven管理界面插件目录下会出现以下目录

《jar第三方组件Dependency-check依赖检查工具》

此时右键点击dependency-check:check运行,即可开始扫描。dependency-check:update-only用来更新NVD漏洞库而不开始扫描。此种方式扫描的配置可以使用<configuration>标签

<project>
...
<build>
...
<plugins>
...
<plugin>
<groupId>org.owasp</groupId>
<artifactId>dependency-check-maven</artifactId>
<version>2.1.0</version>
<configuration>
<suppressionFiles>
<suppressionFile>http://example.org/suppression.xml</suppressionFile>
<suppressionFile>project-suppression.xml</suppressionFile>
</suppressionFiles>
</configuration>
<executions>
<execution>
<goals>
<goal>check</goal>
</goals>
</execution>
</executions>
</plugin>
...
</plugins>
...
</build>
...
</project>

此时如果配置正确,当使用gradle build项目的时候,Dependency-check将会自动开始扫描并生成报告。你也可以手动直接开始扫描使用:

gradle dependencyCheckAnalyze –info

扫描报告将会生成在build/reports目录下。

作为Ant Task使用

在这种使用模式下,需要首先下载dependencyCheck-ant二进制包从这里:

http://dl.bintray.com/jeremy-long/owasp/dependency-check-ant-2.1.0-release.zip

解压后在build.xml中配置如下:


然后就可以执行Ant Taskle了。使用dependency-check命令开始扫描,使用dependency-check-purge删除本地NVD库。使用dependency-check-update更新NVD库而不开启扫描。
当使用其他项目的时候,只需要复制build.xml配置过去,而不用重新下载NVD数据库。

0x02: 安装与运行

3.1 工作原理

Dependency-Check工具依赖于它的多个分析器。Archive分析器可以将zip,jar,war等压缩格式的文件解压,Assembly分析器可以解析dll与exe格式的文件,而jar分析器用于扫描polm.xml以及jar的包名来搜集依赖信息。这些收集的信息被称为证据,它们有三种属性:供应商,产品,版本。这些漏洞列表形如下面:

<entry id="CVE-2012-5055">
...
<vuln:vulnerable-software-list>
<vuln:product>cpe:/a:vmware:springsource_spring_security:3.1.2</vuln:product>
<vuln:product>cpe:/a:vmware:springsource_spring_security:2.0.4</vuln:product>
<vuln:product>cpe:/a:vmware:springsource_spring_security:3.0.1</vuln:product>
</vuln:vulnerable-software-list>
...
</entry>

这些信息还具有启发意义。例如,一个mysql5.1的jdbc驱动依赖包会被认为Mysql数据库的版本很可能也是5.1

在NVD CVE数据库中,每个CVE条目都有一个易受攻击的软件列表。这些CPE条目记录了“CPE:/入口类型:供应商:产品:版本:修订:…”这些属性。这些数据被收集并存储在Lucene索引中。然后使用所收集的证据,并尝试匹配Lucene CPE索引中的条目。如果找到,CPEAnalyzer分析器将向依赖项添加标识符,并随后添加到报告中。一旦确定了CPE,就将关联的CVE条目添加到报告中。
这些证据在写入报告的时候会被分级使用不同的信心级别——低、中、高和最高。它等于在识别过程中使用的证据的最低水平的信心水平。如果用于识别某个CPE的一系列证据中信心等级最低的证据是高级,那么,那么CPE将拥有高级的信心水平。
由于Dependency-Check的工作方式,误报和漏报都有可能,这些可以在后面使用某些配置策略来减少。
Dependency-Check不使用hash来识别依赖包。因为这些依赖包有可能是源码在本地自己编译的,这样的话依赖包的hash将与官方发布的版本依赖包hash不匹配,分析器将不能识别。

3.2 漏报与误报策略

误报策略

由于Dependency-Check的工作方式,可能会存在识别错误的问题,导致某个没有漏洞的CPE被识别为有问题的。
如果是使用html形式生成的报告,
在每个被识别的CPE(以及CVE条目)旁边的报告中,有一个抑制按钮。单击镇压按钮将创建一个对话框,您可以简单地复制并将其放入到一个抑制XML文件中的XML。如果这是您第一次创建压缩文件,那么应该单击对话框顶部的“完整的XML Doc”按钮,以添加必要的模式元素。
一个示例压缩文件看起来是这样的:

<?xml version="1.0" encoding="UTF-8"?>

<suppressions xmlns="https://jeremylong.github.io/DependencyCheck/dependency-suppression.1.1.xsd">

   <suppress>

      <notes><![CDATA[

      file name: some.jar

      ]]></notes>

      <sha1>66734244CE86857018B023A8C56AE0635C56B6A1</sha1>

      <cpe>cpe:/a:apache:struts:2.0.0</cpe>

   </suppress>

<suppress>

        <notes><![CDATA[

        This suppresses cpe:/a:csv:csv:1.0 for some.jar in the "c:\path\to" directory.

        ]]></notes>

        <filePath>c:\path\to\some.jar</filePath>

        <cpe>cpe:/a:csv:csv:1.0</cpe>

    </suppress>

</suppressions>

suppression文件有两种匹配方式,通过hash散列值来匹配或者通过包路径来匹配,包路径可以是正则表达式。以上第一个示例是将抑制cpe::apache:struts:2.0.0从任何文件匹配的SHA1哈希。
如果是使用命令行模式运行扫描,在启动扫描的时候加上参数–suppression后面指定suppression文件的路径即可使这个配置生效。

如果是通过maven插件的方式运行,则在插件的configuration标签里增加suppressionFiles元素,内容为suppression文件的路径即可使次文件生效。其他插件形式的类似在配置文件中修改。

漏报策略

由于Dependency-check是根据依赖度来识别CPE,因此,如果某项CPE证据信心不足,则会被忽略掉。
在html形式的报告中,点击Display: Showing Vulnerable Dependencies (click to show all)即可显示所有脆弱的依赖,这样可以查看没有CPE匹配的依赖项。错误可能的原因是随着时间的推移重新命名供应商或库名称,或者是工件缺少信息(manifest没有供应商)。
Dependency-check有一个内置的hints文件,在每次Check中都将使用它来修正错误。如果确定某个依赖没有被识别,可以通过修改Hints文件来修正错误。以下是hints文件样例:

<?xml version="1.0" encoding="UTF-8"?>

<hints xmlns="https://jeremylong.github.io/DependencyCheck/dependency-hint.1.1.xsd">

    <hint>

        <given>

            <evidence type="product" source="Manifest" name="Implementation-Title" value="Spring Framework" confidence="HIGH"/>

            <evidence type="product" source="Manifest" name="Implementation-Title" value="org.springframework.core" confidence="HIGH"/>

            <evidence type="product" source="Manifest" name="Implementation-Title" value="spring-core" confidence="HIGH"/>

        </given>

        <add>

            <evidence type="product" source="hint analyzer" name="product" value="springsource_spring_framework" confidence="HIGH"/>

            <evidence type="vendor" source="hint analyzer" name="vendor" value="SpringSource" confidence="HIGH"/>

            <evidence type="vendor" source="hint analyzer" name="vendor" value="vmware" confidence="HIGH"/>

            <evidence type="vendor" source="hint analyzer" name="vendor" value="pivotal" confidence="HIGH"/>

        </add>

    </hint>

</hints>

这个xml文件将把add中的四个证据添加到任何一个given中的产品中去。
每一个hint中有且只有一个add与given。add为将要被修改的属性,而given是需要修改的目标列表。Dependency会被所有add里的属性修改到given的每一个目标中。
type可以是product,vendor,或者verion等属性,对应之前提到的CPE数据库中证据的属性
source可以使hint analyzer,Manifest,pom,jar,表示目标属性的来源,这个值在add中一直是hint analyzer
name是想要修改的属性名,这个属性通常与type相同,只有当source为pom时,它才会变化为pom.xml中的标签名。
value在add中表示要修改的属性值,在given中表示要匹配的目标值。
confidence表示信心等级。

3.3 报告输出

Dependency-check支持多种输出格式,默认是HTML格式。在命令式方式使用时,指定参数–format来选定格式,可以有XML, HTML, CSV, JSON, VULN, ALL这些选项(必须是大写)。
HTML格式将会生成一个报告文档,有关于各项的统计总结,每个依赖对应的CVE,以及简单说明,是最通俗易读的方式。
而CSV这些格式的报告将会生成一个列表,结构如下:

《jar第三方组件Dependency-check依赖检查工具》

结构很清晰,但是信息比较精简,关于证据的来源,可信度等信息都被忽略了,只保留了最重要的漏洞编号及简单描述,没有树形结构信息。
XML与JSON生成的报告很类似,只是语法结构不一样,内部的字段以及信息结构都是一样的。以下是JSON报告片段截取:


如果是人工审阅,html格式是最好的选择,如果是需要自动化处理,json与xml都差不多,而CSV格式信息比较少,并且可能出现编码问题,不做推荐。

本文转载自滴滴安全应急响应中心:  https://mp.weixin.qq.com/s/j37Y1rpQphFFSoAtbzSnMQ

点赞