一文看懂漏洞管理中的CPE

img

大概是中文领域中讲解的最详细的一篇

0x00 什么是CPE

CPE(Common Platform Enumeration),中文译为通用枚举平台,是采用了一种结构化命名的方式,基于URI(Uniform Resource Identifiers)一种通用语法规则,通俗的讲:CPE是用来描述漏洞影响了哪些产品/组件的哪些版本。

在2011年8月,NIST发布CPE的最新版本2.3版,同时CPE 2.3版也包含在SCAP的1.2版本中。CPE 2.3版和过去的版本有着很大的改变,在新版本中设计了成为了一种堆栈式的结构,从栈低依次是Naming、Name Matching、Applicability Language、Dictionary。

img

1. Naming

我们大部分时间讨论的CPE,一般指的就是在Naming层中表示的CPE规则的描述,在新版规则中,定义了三种方式来描述CPE:

  • WFN(well-formed CPE name):被称为格式良好的CPE名称,WFN是在一种面向人读的描述方式,CPE的命名规范定义了将WFN绑定到URI、FS和解绑的规则。(官方称这种规则转换为绑定,可以理解为转换)
  • URI:URI是兼容旧版的一种机读描述方式
  • FS(Formatted String):FS是新版增加具有格式化的机读描述方式

这三种描述方式可以相互转换,而在NVD看到漏洞详情页面展示的都是FS形式的。

1.1 WFN

WFN是一组无序的属性值对,用来描述软件、操作系统、硬件的逻辑结构。

我们先看一个例子:用WFN形式来描述Microsoft Internet Explorer 8.0.6001 Beta:

1
wfn:[part="a",vendor="microsoft",product="internet_explorer",version="8\.0\.6001",update="beta"]

在WFN中有下列这些属性:

  • part:可以理解为分类,有三种分类:
    • a:应用程序
    • o:操作系统
    • h:硬件设备
  • vendor:创建产品个人或者组织/厂商
  • product:产品标题或者名称
  • version:由厂商提供用来表示产品的特定的发行版本
  • update:同样是厂商提供表示产品的更新版本,比version范围更小
  • edition:这个属性同样表示版本,属于被弃用的属性,一般是为了兼容更早CPE版本,默认值为ANY
  • language:表示产品在操作界面所支持的语言
  • sw_edition:表示产品是针对某些特定市场或类别的目标用户
  • target_sw:产品运行需要的软件环境
  • target_hw:产品运行需要的硬件环境
  • other:表示无法归类上上述其他属性的值

如果在WFN未使用某个属性,则称为未指明的属性,默认值未ANY。sw_edition target_sw target_hw other 是新引入的属性,被称作扩展属性。

WFN有两种逻辑属性值:

  • ANY:任意值,当属性没有可接受值
  • NA:不适用,该属性没有合法或者有意义的值

另外WFN对于值的规则,也有具体的描述:

  • 首先WFN属性值应该是可以输出的UTF-8格式的非空连续字符串,十六进制编码位于x00-x7f之间,这意味着CPE中的字符限制为英文、数字和常见的一些符号,即时中文产品也需要用拼音或者有对应的英文名字的形式来表示
  • 属性值用””包裹起来
  • 可以使用大小写字符和数字
  • 下划线可以使用,用来代替空白字符
  • 可以使用反斜杠表示转义字符
  • *号和?号有特殊含义,如果要使用请使用转义字符,*号和?的具体含义由其他CPE规定解释,可以加在字符串的开头和结尾
  • 其他可以输出的非字母数字符号,在使用时需要放在引号内

下面是一些在WFN中可以使用值的例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
"foo\-bar" (hyphen is quoted)
"Acrobat_Reader"
"\"oh_my\!\"" (quotation marks and exclamation point are quoted)
"g\+\+" (plus signs are quoted)
"9\.?" (period is quoted, question mark is unquoted)
"sr*" (asterisk is unquoted)
"big\$money" (dollar sign is quoted)
"foo\:bar" (colon is quoted)
"back\\slash_software" (backslash is quoted)
"with_quoted\~tilde" (tilde is quoted)
"*SOFT*" (single unquoted asterisk at beginning and end)
"8\.??" (two unquoted question marks at end)
"*8\.??" (one unquoted asterisk at beginning, two unquoted question marks at end)

1.2 URI

接下来我们在看看URI,同样的先看一个例子:用URI方式来描述 Microsoft Internet Explorer 8.0.6001 Beta

1
cpe:/a:microsoft:internet_explorer:8.0.6001:beta

每个URI形式的名称都是以 cpe: 开始的,下图中采用来 ABNF 表示法,解释了 WFN 与 URI 的绑定关系:

img

1.3 FS

FS 是 CPE2.3 的新功能,它看起来和 URI 类似,前缀字符串为 cpe:2.3 ,FS以固定的顺序绑定WFN,用冒号作为分隔:

1
cpe:2.3:part:vendor:product:version:update:edition:language:sw_edition:target_sw: target_hw:other

下图用 ABFN 解释了 FS 和 WFN 的绑定关系:

img

2. Name Matching

在上一节中描述了最基础的CPE名称的定义规则,在这一节将要说明CPE的匹配规则。

CPE名称匹配定义是将一种源CPE与目标CPE进行1对1比较的方法,简单来说,就是通过匹配规则来发现目标系统是上是否安装了目标产品,假设一个安全团队需要确定哪些主机上安装了Microsoft Internet Explorer 8,以及包括的各种小版本,这个时候可以使用WFN来表示:

1
wfn:[part="a",vendor="microsoft",product="internet_explorer",version="8\.*",update=ANY,edition=ANY,language=ANY]

使用符合 CPE 规则的资产管理工具收集信息,并搜索结果和上述WFN进行比较,假设报告为:

1
wfn:[part="a",vendor="microsoft",product="internet_explorer",version="8\.0\.6001",update=NA,edition=NA,language="en\-us"]

可以明确这个两个WFN(第一个为源WFN,第二个为目标WFN)的集合关系(相等,超集)。

在Name MAtching中定义了四种关系:

  • ⊃:源是目标的超集
  • ⊂:源是目标的字集
  • =:源和目标相等
  • ≠:源和目标不相交

3. Dictionary

Dictionary是CPE名称和与名称相关联的元数据存储库,Dictionary的中的每个CPE名称都标识了世界上的一类IT产品。举个例子:假如我有一台电脑,型号是MacBook Pro 2021,那么字典标识的类是MacBook Pro 2021这一类,而不是我手上这一台的实例。

Dictionary的数据表现方式和Naming一致,也是用三种不同的格式标识,常用的则是FS格式的表现方式。

Dictionary的数据模型通过标准的xml语法构建,它有三种不同前缀:

  • cpe_dict:CPE Dictionary 2.3 XML模式
  • cpe_dict_ext:CPE Dictionary 2.3 XML模式扩展类型
  • cpe-name:CPE Naming类型的XML模式

采用cpe_dict前缀通过一个树状结构来描述各个元素的关系:

  • <cpe_dict:cpe-list>:根节点
    • <cpe_dict:generator>:文档的信息,包括Dictionary模式,时间,生成它应用程序的名称和版本
      • <cpe_dict:product_name>:生成Dictionary程序的名称
      • <cpe_dict:prodyct_version>:生成Dictionary程序的版本
      • <cpe_dict:scheme_version>:写入文档验证的架构版本
      • <cpe_dict:timestamp>:文件生成时间
      • <cpe_dict:cpe-item name="" deprecated_by="" >:单个字典条目的容器以及其元数据
      • <cpe_dict:title>
      • <cpe_dict:notes>
      • <cpe_dict:references>
      • <cpe_dict:check>
      • <cpe_dict:cpe23-item>

在这个结构中我们只需要关注<cpe_dict:cpe23-item>中的CPE数据即可。

4. Applicability Language

Applicability Language被称作适用性语言,通俗的讲,Applicability Language也是通过标准的xml语法构建来一种CPE逻辑组合方式,来描述一个组合型产品。

举个例子:Photoshop 2021版这个软件出现了一个提权漏洞,但是只在windows7和windows10上实现,此时如果直接用CPE方式描述,无法描述出有平台依赖关系的CPE,这个时候就需要进行组合来描述,这也就是Applicability Language的简单的实例。

下面来说用XML如何描述这个“组合”:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<cpe:platform-specification>
<cpe:platform id="789">
<cpe:title>
Microsoft Windows XP with Internet Explorer 7.x or 8.x
</cpe:title>
<cpe:logical-test operator="AND" negate="FALSE">
<cpe:fact-ref name="cpe:2.3:o:microsoft:windows_xp:*:*:*:*:*:*:*:*"/>
<cpe:logical-test operator="OR" negate="FALSE">
<cpe:fact-ref name="cpe:2.3:a:microsoft:internet_explorer:7.*:*:*:*:*:*:*:*"/>
<cpe:fact-ref name="cpe:2.3:a:microsoft:internet_explorer:8.*:*:*:*:*:*:*:*"/>
</cpe:logical-test>
</cpe:logical-test>
</cpe:platform>
<cpe:platform-specification>

先通过一个树状结构来描述各个元素的关系:

  • <cpe:platform-specification>
    • <cpe:platform>
      • <cpe:title>
      • <cpe:remark>
      • <cpe:logical-test>
        • <cpe:logical-test>
          • <cpe:logical-test>
          • <cpe:fact-reft>
          • <cpe:check-fact-ref>
        • <cpe:fact-reft>
        • <cpe:check-fact-ref>

<cpe:platform-specification>作为XML文件最外层的根节点,也可以称为一个容器,在一个文件中只存在一个,并且是在最外层。在<cpe:platform-specification>的下一层就是<cpe:platform> <cpe:platform>表示多个CPE组成的平台,并且有一个属性是id,在同一个容器中,id要保持唯,同时在一个容器中可以有多个平台。

<cpe:platform>的下一层包含三个元素<cpe:title><cpe:remark><cpe:logical-test><cpe:title>表示这个平台的名称,可以支持多个<cpe:title>,用来区分不同语言。<cpe:remark>表示是对这个平台的评论或者描述,也支持多条描述,但在大多数时候都是空的。<cpe:logical-test>表示这个平台的下的第一层逻辑关系,在与<cpe:platform>直接接触这一层,只存在一个<cpe:logical-test>,而在它之下可以无限嵌套或平行<cpe:logical-test>来构建组合。

<cpe:logical-test>有两个属性值:operator表示下一层各个元素之间但关系,它有两个值,AND和OR。另外一个是negate,表示对operator计算结果是否进行取反操作。

另外在每一个<cpe:logical-test>之下还有另外两个元素,<cpe:fact-reft>就是CPE一条规则。<cpe:check-fact-reft>则是对<cpe:fact-reft>的检查描述信息,大多数时间也是空的。

0x01 NVD网站上的CPE怎么看

NVD漏洞详情页面上提供了三种类型的CPE匹配信息:BasicRunning on/withAdvanced,不管哪一种信息,都提供了一个Configuration,这个可以理解为一个容器,并且是安装顺序序号排列下来的。

1. Basic

在Basic中也存在不同的情况:

1.1 第一种

第一种是最简单的,NVD提供了一个匹配的语法,只要点击Show Matching CPE(s)即可看到最终从Dictionary匹配出的结果

img

1.2 第二种

第二种告诉了匹配这条CPE时候,update字段的上限

img

1.3 第三种

第三种,则提供匹配的下限和上限

img

2. Running on/with

在Running on/with种则是一种特定组合关系,它的意思Running on/with上面的CPE信息需要依赖下面的环境,才能触发该漏洞。

img

3. Advanced

Advanced则提供了在Applicability Language种完整组合关系的这种。产生更复杂依赖关系。

img

在实际情况种Basic和Running on/with基本涵盖了几乎全部数据,只有少量会出现Advanced的这种情况。

0x02 总结

上述内容详细描述了各个模块的定义与说明。简单来说,在Naming中,定义了基本的CPE的写法;在Dictionary中,是所有细化的产品的枚举字典,而在Name Matching定义了怎么通过cpe匹配模式,匹配出最终的目标产品。而在Applicability Language中,则定义了一种基于逻辑结构的cpe高级用法,可以进行多个CPE的组合形式,来描述IT平台。

在NVD的漏洞详情页面,有三种形式的展示方式:

  • Basic:最基本匹配方式,直接可以通过给出cpe匹配范围,直接进行匹配,然后得出cpe字典列表
  • Running On/With:一种组合的匹配方式,
  • Advanced:一种组合的匹配方式

0x03 官方文档

https://csrc.nist.gov/projects/security-content-automation-protocol/specifications/cpe

0x04 一个处理CPE的Py包

https://cpe.readthedocs.io/

备注:这个包在处理CPE2.3版本时候到匹配有BUG,需要使用2.2版本来进行匹配,然后用2.3版本输出,算是一个曲线救国的方式。

0x05 参考链接

https://nvd.nist.gov/vuln/vulnerability-detail-pages
https://www.fooying.com/common_vulnerability_management_and_scap/