恶意文件分析系统中的数字签名验证

恶意文件分析系统中的数字签名验证

安全研究部 李志昕

摘要:本文主要介绍了Linux环境下的PE文件数字签名验证的相关技术,着重介绍了从PE文件中解析数字签名,并应用Openssl库进行证书信任链的验证。最后,对在恶意文件分析系统中对数字签名的信任策略问题,提出一些讨论和思考。

关键词:恶意文件分析 数字签名 Openssl

前言

本文是基于一个真实项目中所涉及到的数字签名验证问题的相关实践所进行的总结,并不希望详细介绍数字签名技术的方方面面,而是仅就项目中遇到的问题和解决问题的思路方法进行介绍。

本文主要介绍的内容有:在Linux环境下如何验证PE文件的数字签名,如何从Windows系统中导出信任证书并在Linux应用,以及数字签名验证通过情况下的文件信任策略。这当中所涉及到的数字签名的概念和技术,为了保证文章的完整可读,也将作以简要的介绍。

PE文件数字签名格式

这里假定读者已经具备数字签名的基本理论知识,如果不了解可以先阅读一下What is a Digital Signature1这篇文章,其中用比较形象的手法解释了相关概念。

接下来,首先看一下我们遇到的问题。我们的恶意文件分析系统(以下简称分析系统)接收到用户提交的样本文件后,在进行动态分析之前会先做一些静态分析。而在对PE文件的静态分析中,如果PE文件有数字签名,则对签名进行验证。若数字签名验证通过,则不再对其进行后续分析。这样做主要考虑的是降低误报,以及减少服务器资源消耗。但是由于分析系统是运行在Linux平台上,所以无法直接利用Windows系统的工具来完成验证。当然,另外提供一个基于Windows的验证服务器也是一个很好的思路,那么在我们的项目中,采用的是在Linux环境下直接提取PE文件的数字签名并验证的方法。要做到这一点,就必须先了解PE文件数字签名的格式。

图 2.1 引自于微软的官方文档2,该图比较清晰的展现了PE文件数字证书的结构,下面作以简要的描述:

(1) PE文件头部的可选头部中,数据目录(Data Directories)的第五项,为安全目录(Security Directory),指定了证书表项(Certificate Table)在PE文件中的位置和大小。
(2) 证书表项,每项包含一个8字节的头部以及符合PKCS#73定义的签名数据。

头部定义如下:

14 56 78
表项长度 证书版本 证书类型
  • 表项长度:头部和签名数据的总长度
  • 证书版本:常见为0x0200 (WIN_CERT_REVISION_2)
  • 证书类型:常见为0x0002 (WIN_CERT_TYPE_PKCS_SIGNED_DATA)

image001

(3) 签名数据中主要包含了PE文件的Hash值,使用软件发布者私钥创建的签名,以及X.509 v3格式的证书。PE文件Hash的计算不包含图2.1中灰色背景的部分,目的是避免绑定证书文件影响到Hash值。

应用Openssl验证数字签名

从PE文件中提取得到数据签名数据后,接下来就需要对其进行验证。读者可能发现,在上一节中我们并没有对签名数据进行深入的解析。主要原因:一是PKCS#7、X.509等等这些标准并不是本文要着重介绍的,此外我们实际可以应用Openssl来完成解析和验证的工作,从而绕过对这些复杂细节的纠缠。

下面简要介绍一下所使用到的主要Openssl库函数和验证过程:

(1) PKCS7 *d2i_PKCS7(PKCS7 **a, unsigned char **pp, unsigned int length)

该函数的作用是加载PKCS7 SignedData结构数据。*a为结果写入的对象,可以传入NULL,函数将自动创建新对象;*pp为指向签名数据的指针;length为签名数据长度,这两个变量的值按上一节的方法解析PE文件即可获得。

(2) X509_STORE *X509_STORE_new(void)

该函数用于创建X509_STORE对象,结合下列函数使用。

(3) int X509_STORE_load_locations(X509_STORE *store,const char *file, const char *dir)

该函数的作用为加载可信证书,用来验证签名证书。store即X509_STORE_new函数创建的对象;file为加载的文件名;dir为加载的目录名。

(4) int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs,X509_STORE *store, BIO *indata, BIO *out,int flags)

这个函数就是验证签名的关键函数了,下面详细介绍一下相关参数:

  • p7即为使用d2i_PKCS7加载的数据结构;
  • certs为一套用来查找签名者证书的证书集,可传入p7->d.sign->cert;
  • store为可信证书仓库对象;
  • indata为已签名的数据;这里稍微有点复杂,需要计算一下buffer的偏移,实际Openssl已经解析了结构,只要用以下代码处理一下即可:

image002

  • out为输出内容写入的buffer;
  • flags是用来修改验证操作的可选标志。主要介绍两个flag:

(1) PKCS7_NOVERIFY,表示签名者证书将不进行信任链验证。在无可信证书仓库的情况下,可以设置这个标志。
(2) PKCS7_NOCHAIN,表示除了签名者证书,其他所包含的证书将不被作为untrusted CAs使用,也就意味着整个信任链必须包含在可信证书仓库中。在实际项目中应用了该标志,原因是某些PE文件中所带的其他证书可能不作为验证目的,如果不设置此标志,则会导致验证异常。我们在IE自带的某些PE文件上观察到了这种现象。按理说,不作为验证目的的其他证书不应该出现在信任链检查过程中,可能是openssl的BUG,也可能是我们哪里用法不对。理论上,设置该标志,对数字签名的验证是强验证,很多二级或多级签发的证书不能通过验证。总之,设置该标志,纯粹是为了临时解决问题。

创建可信证书仓库

从上一节的内容可知,如果没有可信任证书仓库,也就无法进行信任链的验证。当然,还有使用CA服务器等其它方式,但如果考虑在本地验证的情况下,是必须要有可信任证书仓库的。接下来我们要做的就是”乾坤大挪移”,将Windows系统中的可信证书导出到Linux系统中来,需要以下几个步骤:

(1) 导出Windows系统中的可信证书

“Win + R”调出Run对话框,输入”certmgr.msc”运行。在证书管理窗口(见图 4.1 )的左侧栏中选中”Trusted Root Certification Authorities”–”Certificates”,然后在右侧栏中”Ctrl + A”全选,单击右键选择”All Tasks”–”Export…”。

image003

在向导(见图 4.2 )中选择”Personnal Information Exchange – PKCS#12″,完成向导完成导出后得到后缀为”.pfx”的文件,假定为CAs.pfx。

image004

(2) 转换格式

Windows导出的证书无法直接应用,需要转换成pem格式,使用如下命令:

$> openssl pkcs12 –in CAs.pfx –out CAs.pem

此时CAs.pem中包含了所有导出的证书,还需要将它们拆分成单独的pem文件。这里可以用一个简单的python脚本来实现:

image005

可能有现成的openssl命令行参数实现这种拆分,没有细究。

(3) 创建hash link

最后,需要对证书文件创建hash link,不同Linux发行版下用的命令可能会有所不同,例如:Ubuntu 14.04使用c_rehash,而Fedora 20使用cacertdir_rehash。

$> c_rehash

使用上一节介绍的X509_STORE_load_locations函数导入该目录的可信证书就可以支持信任链的验证了。

签名验证通过文件的信任策略

签名验证的技术问题解决之后,是否就大功告成了呢?是不是只要签名验证通过,就可以认为这个PE文件一定是正常程序,换言之是一个非恶意程序?

起初我们的分析系统的确是这样设计的,完全信任数字签名。因为实际样本中具有数字签名的只是极少数,而签名验证通过的就更少了,所以并没有仔细思考这个问题。然而,后来我们注意到在某个较短时间内,比如某一天,会出现比平时多很多的签名验证通过的样本,直觉上有一点不太正常。

为了避免是签名验证程序实现上的bug所致,转到Windows系统再来查看这些文件的证书(如图 5.1 所示),发现数字签名确实是有效的(见处),只是证书的有效期通常只有一年(见处)。把样本上传virustotal检查,结果发现确是恶意程序(见图 5.2 )。

image006

image007

如此便说明了一个事实,并非能够通过数字签名验证的文件都是正常文件,很有可能是恶意软件的开发者申请合法证书并签名。所以对于数字签名,不应该直接信任,而是建立软件发布者的黑白名单。当样本的签名验证通过,但软件发布者是分析系统未知的时,则强制进行完整的样本分析过程。经过几轮相同软件发布者的样本分析后,根据分析结果将软件发布者加入分析系统的黑白名单,为后续样本数字签名的验证提供依据。

这样数字签名就成为样本分析的一个维度,通过大量样本数据的积累后,则可以以此维度进行统计分析,作为安全态势可视化的数据源。

结束语

本文中介绍的方法并不是唯一的,更不可能是最好的,只是在我们项目当中的一个技术选择。或在资源受限,或在网络受限,或考虑性能因素等情况下,可以作为一个可行方案备用。此外对于可信证书的更新,证书吊销等问题,也还需要进一步完善解决方案。

最后提出的以数字签名作为一个维度进行安全态势可视化,已经见到有安全公司做类似的在线应用,应该是值得进一步研究的。

参考文献

  1. What is a Digital Signature?

http://www.youdzone.com/signature.html

  1. Windows Authenticode Portable Executable

http://download.microsoft.com/download/9/c/5/9c5b2167-8017-4bae-9fde-d599bac8184a/Authenticode_PE.docx

  1. http://en.wikipedia.org/wiki/PKCS
  2. OpenSSL-based signcode utility

http://sourceforge.net/projects/osslsigncode/

《恶意文件分析系统中的数字签名验证》的文章下载
恶意文件分析系统中的数字签名验证

更多相关文章请参看 http://www.nsfocus.com.cn/research/qyjs.html

发表评论