FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。
FreeBuf+小程序把安全装进口袋
在开始讲驱动签名之前,我们先简单的科普一下什么是代码签名。
代码签名(Codesigning)是利用代码签名证书对可执行文件或脚本进行数字签名,以确认软件作者及保证软件在签名后未被修改或损坏的措施,此措施使用加密散列来验证真实性和完整性。简单来说就是进行代码签名后,可以增加程序的可信度。
代码签名证书主要分为两类:
标准代码签名证书
EV扩展型代码签名证书
EV扩展型代码签名证书除了验证企业的基本信息、税务信息外,还会对企业的经营地址、申请人身份进行审查,区别于标准代码签名的重要特点是支持Windows10内核驱动文件签名和消除SmartScreen筛选器安全提醒,此外EV代码签名针对内核模式的驱动文件需要进行微软的交叉签名。
这里需要注意,驱动文件要用EV证书进行签名才可以用。
了解了代码签名之后,再来了解一点关于Windows驱动程序的基础知识:
微软提供的驱动签名有两种方式:
具体步骤如下:
在微软开发者账户设置中选择管理证书。
提交完即可根据自身需求,自由选择签名方式。
PS:证明签名(attestation-signing)在Win7上没法使用,已经尝试的签名组合:
此处不包含驱动开发部分,假设已经编译出驱动release,此时需要的打包文件有:
nacndislwf.cat
NacNdisLwf.inf
NacNdisLwf.sys
创建DDF文件(相当于打CAB包的配置文件),下面是一个打包NacNdisLwf驱动的示例:
;***nacndislwf.ddfexample;.OPTIONEXPLICIT;Generateerrors.SetCabinetFileCountThreshold=0.SetFolderFileCountThreshold=0.SetFolderSizeThreshold=0.SetMaxCabinetSize=0.SetMaxDiskFileCount=0.SetMaxDiskSize=0.SetCompressionType=MSZIP.SetCabinet=on.SetCompress=on;Specifyfilenamefornewcabfile.SetCabinetNameTemplate=NacNdisLwf.cab;Specifythesubdirectoryforthefiles.;Yourcabfileshouldnothavefilesattherootlevel,;andeachdriverpackagemustbeinaseparatesubfolder..SetDestinationDir=NacNdisLwf;SpecifyfilestobeincludedincabfileC:\tmp\Driver\none\NacNdisLwf.InfC:\tmp\Driver\none\NacNdisLwf.SysC:\tmp\Driver\none\nacndislwf.cat打包前可以先对.cat.sys进行签名,这样签名下来可以有两个证书:一个我们的EV证书、一个微软的证明签名。
MakeCab/f"C:\tmp\Driver\DDF\NacNdisLwfWin10.ddf"提交微软的全部文件必须进行EV/sha256签名。
大致逻辑是,需要搭建HLKserver与HLKclient,将需要测试的驱动程序部署在HLKclient上,在HLKserver进行控制,HLKserver会对Client执行各种自动化操作,并在server上生成测试结果。
在Client上安装HLK客户端确保与server处于同一个局域网域下,ControllerName为server端的设备名注意此处不要使用Ip,已踩过坑。
\\
创建机器池:客户端安装完成后会打开HLKStudio,点击Configuration可以看到刚刚安装客户端的设备机器需新建一个机器池,并将这个设备从默认的机器池中拖出去,然后右键更改状态为ready。
之后便可以新建项目,选择测试目标Client上已经安装的驱动进行测试了,这块没啥坑,直接看微软文档即可。
选择Client上的驱动(先在Client上安装自己的驱动,studio这边刷新之后就会显示)。
在Tests上勾选需要运行的自动测试,点击Runselected进行自动测试。
查看测试结果:遇到失败可以查看原因解决。
创建提交包:驱动通过验证后需创建提交包进行提交。
点击CreatPackage进行创建包
签名:微软是推荐使用Usethecertificatestore里面的证书,但我们在插入yubikey打算使用usb密钥的证书对他进行签名时,发现可以选择在yubikey中的证书。但签名时会失败,报错为Unabletousetheselectedcertificatetosignthepackage,进入到Eventviewer中查看详情为:Unabletousetheselectedcertificatetosignthepackage。
研究了很久,在创建HLKX时只能在这里选择签名,因为HLK不支持signtools。
解决方案1:使用C#的CSP对HLkx进行签名,<失败:CSP无法识别sha384签名>,
通过SSL.com签发的OV证书进行签名由于之前SSl.com的OV代码证书没有人在使用,所以需要重新创建CSR提交到SSL上重新生成证书(SSL.com的验证流程很慢,正常要3-5天)。
获取SSL.com带私钥的OV证书
查看OV证书是不是带sha256RSA类型,与EV证书采用相同的操作(下载SignableFile.bin本地使用SignTool签名,上传到微软开发者验证)。在Usethecertificatestore中选择导入本机OV证书,签名成功。
提交微软认证
签名问题小结:签名会失败的原因由于EV证书的签名算法为Sha384ECDSA,HLKStudio不支持认证该算法,只能使用SHA256RSA来解决;只使用HLK认证的签名依然会失败,这是由于Win10以下的驱动使用HCK认证(与HLK一样HLK是其升级版本),可以在创建HLK提交后在Package页面选择mergepackage将HCK数据包合并到HLK中才可以认证Win7。
HCKserver版本可以使用server2012及server2008,建议使用2008英文版。
原因:server2012默认开启domincontrller会导致安装失败,且这个domincontrller不是很好关闭,
需要关闭IEESC配置。
不关闭IEESC安装,.net4.5会失败(点击servicemanager关闭IEESC),
server与client请都使用英文版,避免不必要的问题。
安装后,操作流程与HLK一致,最后package需注意:
不需要签名,直接生成不签名的HCKX文件;
生成后发送hckx文件到HLKserver上进行mergepackage操作。
建议使用微软的VHLK虚拟机,在本地装hyper-v直接使用虚拟机运行server可以省很多事情。
使用英文版!使用英文版!使用英文版!重要的事情说三遍。
最后再补充一点关于代码签名安全方面的东西,那就是在已签名PE文件里注入shellcode,不会影响签名的有效性,也就是白加黑的手法。虽然这是个老技术,但很多机器都没打这个补丁(KB2893294)。
为了不把本文弄得又臭又长,这里只做个简单的演示。具体原理可见末尾引用:
这里用到的工具(需自行编译)。
开始把shellcode注入到hr.exe,指定加密key为test,需要注意的是文件的hash会变的,但是数字签名仍有效。
再看看注入后(hrxx.exe)的签名,还是有效的。
用loader配合白应用(hrxx.exe)执行shellcode,可以看到calc顺利弹出。