企业博客
最近公司在进行NAC网卡驱动的研发,而Windows驱动要想跑起来就必须得进行驱动签名。这中间过程坎坷,我们也在驱动签名上也踩过不少坑,特此记录,希望能帮到有需要的友商。
在开始讲驱动签名之前,我们先简单的科普一下什么是代码签名。
什么是代码签名
代码签名(Code signing)是利用代码签名证书对可执行文件或脚本进行数字签名,以确认软件作者及保证软件在签名后未被修改或损坏的措施,此措施使用加密散列来验证真实性和完整性。简单来说就是进行代码签名后,可以增加程序的可信度。
代码签名证书分类
代码签名证书主要分为两类:
标准代码签名证书
标准代码签名(OV)只需要验证申请企业的基本信息、税务信息,验证成功后通过邮件等形式通常针对32/64位应用程序进行签名,以防止各类杀毒软件的误报。仅需较短的处理时间及较低的成本,但无法用于 LSA 和 UEFI 文件签名、无法用于内核模式驱动程序。
EV扩展型代码签名证书
EV扩展型代码签名证书除了验证企业的基本信息、税务信息外,还会对企业的经营地址、申请人身份进行审查,区别于标准代码签名的重要特点是支持Windows 10内核驱动文件签名和消除SmartScreen筛选器安全提醒,此外EV代码签名针对内核模式的驱动文件需要进行微软的交叉签名。
这里需要注意,驱动文件要用EV证书进行签名才可以用。
了解了代码签名之后,再来了解一点关于Windows驱动程序的基础知识:
微软提供的驱动签名有两种方式:
前置条件
开始之前进行驱动签名的准备工作,首先需要购买EV证书(我司在ssl.com进行购买),然后登录到managecertificates,以开发者身份将提前准备好的EV证书提交到微软开发者进行认证。
具体步骤如下:在微软开发者账户设置中选择管理证书
提交完即可根据自身需求,自由选择签名方式。
PS: 证明签名(attestation-signing) 在Win 7上没法使用,已经尝试的签名组合:
- Ev sha1+ Ev sha256(交叉签名) + 微软签名
- Ev sha1+ 微软签名
- Ev sha256 + 微软签名
根据微软文档 get-drivers-signed-by-microsoft-for-multiple-windows-versions,需提交Hardware Lab Kit (HLK) 微软硬件测试结果到微软测试上。也就是说如果想在Win7上使用,请用HLK,此处已踩坑。
此处不包含驱动开发部分,假设已经编译出驱动release,此时需要的打包文件有:
;*** nacndislwf.ddf example
;
.OPTION EXPLICIT ; Generate errors
.Set CabinetFileCountThreshold=0
.Set FolderFileCountThreshold=0
.Set FolderSizeThreshold=0
.Set MaxCabinetSize=0
.Set MaxDiskFileCount=0
.Set MaxDiskSize=0
.Set CompressionType=MSZIP
.Set Cabinet=on
.Set Compress=on
;Specify file name for new cab file
.Set CabinetNameTemplate=NacNdisLwf.cab
; Specify the subdirectory for the files.
; Your cab file should not have files at the root level,
; and each driver package must be in a separate subfolder.
.Set DestinationDir=NacNdisLwf
;Specify files to be included in cab file
C:\tmp\Driver\none\NacNdisLwf.Inf
C:\tmp\Driver\none\NacNdisLwf.Sys
C:\tmp\Driver\none\nacndislwf.cat
signtool sign /as /fd sha256 /sha1 a32e4ea1143e9748389b2f3eb85e496d481ffbeb /tr http://ts.ssl.com "C:\tmp\Driver\double\NacNdisLwf.sys"
signtool sign /as /fd sha256 /sha1 a32e4ea1143e9748389b2f3eb85e496d481ffbeb /tr http://ts.ssl.com "C:\tmp\Driver\double\nacndislwf.cat"
MakeCab /f "C:\tmp\Driver\DDF\NacNdisLwfWin10.ddf"
signtool sign /fd sha256 /sha1 a32e4ea1143e9748389b2f3eb85e496d481ffbeb /tr http://ts.ssl.com "C:\tmp\Driver\DDF\disk1\NacNdisLwf.cab"
选择Submit new hardware 提交签名过后的CAB文件,等待微软验证,相关错误会反馈回来;若签名无问题,即可下载已签名完成的文件
具体步骤,请参考官方文档微软签名:attestation-signing-a-kernel-driver-for-public-release
搭建HLK测试环境
PS:具体请参考微软文档: windows-hardware
大致逻辑是,需要搭建HLK server与HLK client,将需要测试的驱动程序部署在HLK client上,在HLK server进行控制,HLKserver会对Client执行各种自动化操作,并在server上生成测试结果。
\\\HLKInstall\Client\Setup.cmd
另外还有个坑:Client系统语言请使用英语,不然会出现各种奇奇怪怪的报错
研究了很久,在创建HLKX时只能在这里选择签名,因为HLK不支持signtools,因此想出了以下两种解决方案:
在相关社区找到资料,看起来是HLK studio只支持sha256签名,不支持新的sha384签名,文件指路:for-a-windows-10-submission-the-input-package-and-the-included-files-must-be-signed-with-sha256-sig#latest
通过SSL.com签发的OV证书进行签名 由于之前SSl.com的OV代码证书没有人在使用,所以需要重新创建CSR提交到SSL上重新生成证书(SSL.com的验证流程很慢,正常要3-5天)
1.获取SSL.com带私钥的OV证书
2.查看OV证书是不是带sha256 RSA类型
3.与EV证书采用相同的操作(下载SignableFile.bin本地使用SignTool签名,上传到微软开发者验证)
4.在Use the certificate store中选择导入本机OV证书
5.签名成功
6.提交微软认证
签名问题小结:签名会失败的原因由于EV证书的签名算法为Sha384ECDSA,HLK Studio不支持认证该算法,只能使用SHA256RSA来解决;只使用HLK认证的签名依然会失败,这是由于Win10以下的驱动使用HCK认证(与HLK一样 HLK是其升级版本),可以在创建HLK提交后在Package页面选择merge package将HCK数据包合并到HLK中才可以认证Win7。
可参考文档: windows-hardware-certification-kit大致安装流程与HLK认证基本相同,这里分享一下过程中踩过的坑:
安装后,操作流程与HLK一致,最后package需注意:
最后再补充一点关于代码签名安全方面的东西,那就是在已签名PE文件里注入shellcode,不会影响签名的有效性,也就是白加黑的手法。虽然这是个老技术,但很多机器都没打这个补丁(KB2893294)。
为了不把本文弄得又臭又长,这里只做个简单的演示。具体原理可见末尾引用:
这里用到的工具(需自行编译)
https://github.com/med0x2e/SigFlip
shellcode国际惯例用的calc
https://github.com/peterferrie/win-exec-calc-shellcode/tree/master/build/bin
白应用,我这边就用火绒,刚好有安装包,从下图可以看到程序的签名:
开始把shellcode注入到hr.exe,指定加密key为test,需要注意的是文件的hash会变的,但是数字签名仍有效
再看看注入后(hrxx.exe)的签名,还是有效的
用loader配合白应用(hrxx.exe)执行shellcode,可以看到calc顺利弹出
更多用法,请大家自行发挥想象。
本文作者@云山雾隐研发安全团队,文章若有不妥之处请联系指正,欢迎大家通过公众号「云山雾隐」或知乎账号@云山雾隐与我们讨论。