This repository has been archived by the owner on Aug 26, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 13
/
Copy pathcheck_sig.cs
137 lines (119 loc) · 4.89 KB
/
check_sig.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
// To Compile:
// C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe /t:exe /out:check_sig.exe check_sig.cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
internal class CheckSign
{
public static void PrintUsage()
{
Console.WriteLine(@"Checks whether an EXE/DLL is signed and, if so, validates the signature.
USAGE:
check_sig [/online] <path_to_exe/dll> [...] [/?]");
}
private static void Main(string[] args)
{
try
{
List<string> filepaths = new List<string>();
bool onlineCheck = false;
// Parse arguments
for (int i = 0; i < args.Length; i++)
{
string arg = args[i];
switch (arg.ToUpper())
{
case "-ONLINE":
case "/ONLINE":
// Peform an online revocation list check
onlineCheck = true;
break;
case "/?":
// Print usage and exit
PrintUsage();
return;
default:
filepaths.Add(arg);
break;
}
}
// Check whether filepath(s) specified
if (filepaths.Count == 0)
{
Console.Error.WriteLine("[!] [CheckSign] ERROR: No file(s) specified");
return;
}
// List the number of filepaths parsed
Console.WriteLine("[*] [CheckSign] Checking {0} file{1}{2}", filepaths.Count, (filepaths.Count > 1) ? "s" : "", Environment.NewLine);
// Process each file
int fileNum = 0;
foreach (string filepath in filepaths)
{
Console.WriteLine("[*] [CheckSign] File {0}: {1}", ++fileNum, filepath);
if (!File.Exists(filepath))
{
Console.WriteLine(" [-] [CheckSign] ERROR: File not found ({0})", filepath);
continue;
}
// Check for Signature
X509Certificate2 cert;
try
{
X509Certificate theSigner = X509Certificate.CreateFromSignedFile(filepath);
cert = new X509Certificate2(theSigner);
}
catch (CryptographicException)
{
Console.WriteLine(" [-] [CheckSign] No digital signature found!\n");
continue;
}
catch (Exception e)
{
Console.Error.WriteLine(" [-] [CheckSign] ERROR: {0}\n", e.Message.Trim());
continue;
}
Console.WriteLine(" [*] Digital signature found");
// Signature was Found, Gathering Chain information (if available).
// This will not reach out to the internet to verify validity, instead will check the local system.
bool chainIsValid = false;
var certChain = new X509Chain();
certChain.ChainPolicy.RevocationFlag = X509RevocationFlag.ExcludeRoot;
certChain.ChainPolicy.RevocationMode = (onlineCheck) ? X509RevocationMode.Online : X509RevocationMode.Offline;
certChain.ChainPolicy.UrlRetrievalTimeout = new TimeSpan(0, 1, 0);
certChain.ChainPolicy.VerificationFlags = X509VerificationFlags.NoFlag;
chainIsValid = certChain.Build(cert);
Console.WriteLine(" Publisher : " + cert.SubjectName.Name);
Console.WriteLine(" Valid From : " + cert.GetEffectiveDateString());
Console.WriteLine(" Valid To : " + cert.GetExpirationDateString());
Console.WriteLine(" Issued By : " + cert.Issuer);
if (chainIsValid)
{
Console.WriteLine(" [+] Signature valid!");
}
else
{
DateTime expirationDate = DateTime.Parse(cert.GetExpirationDateString());
if (DateTime.Today > expirationDate)
{
Console.WriteLine(" [-] Signature expired");
}
else
{
Console.WriteLine(" [-] Chain invalid or unable to verify chain; certificate may be self-signed");
}
}
Console.WriteLine();
}
}
catch (Exception e)
{
Console.Error.WriteLine("[-] [CheckSign] ERROR: {0}", e.Message.Trim());
}
finally
{
Console.WriteLine("\nDONE");
}
}
}