public static void TriageCertFile(string certFilePath, Dictionary <string, string> MasterKeys) { // triage a certificate file try { var certDictionary = new Dictionary <string, Tuple <string, string> >(); var fileName = Path.GetFileName(certFilePath); Console.WriteLine(" Certificate file : {0}\r\n", fileName); var certificateArray = File.ReadAllBytes(certFilePath); try { certDictionary.Add(fileName, Dpapi.DescribeCertificate(certificateArray, MasterKeys)); } catch (Exception e) { Console.WriteLine("[X] Error triaging {0} : {1}", fileName, e.Message); } Console.WriteLine(); } catch (Exception e) { Console.WriteLine("[X] Error triaging {0} : {1}", certFilePath, e.Message); } Console.WriteLine(); }
public static void TriageCertFolder(string folder, Dictionary <string, string> MasterKeys, bool machine = false) { // triage a specific certificate folder var certDictionary = new Dictionary <string, Tuple <string, string> >(); if (!Directory.Exists(folder)) { return; } var systemFiles = Directory.GetFiles(folder); if ((systemFiles.Length != 0)) { Console.WriteLine("\r\nFolder : {0}\r\n", folder); foreach (var file in systemFiles) { if (Regex.IsMatch(file, @"[0-9A-Fa-f]{32}[_][0-9A-Fa-f]{8}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{12}") ) { var fileName = Path.GetFileName(file); Console.WriteLine("\r\nCertificate file : {0}\r\n", fileName); var certificateArray = File.ReadAllBytes(file); try { certDictionary.Add(fileName, Dpapi.DescribeCertificate(certificateArray, MasterKeys, machine)); } catch (Exception e) { Console.WriteLine("[X] Error triaging {0} : {1}", fileName, e.Message); } } } } else { Console.WriteLine("\r\n[X] Folder '{0}' doesn't contain files!", folder); } Console.WriteLine(); foreach (var key in certDictionary.Keys) { if (certDictionary[key].First != "") { Console.WriteLine("[*] Private key file {0} was recovered\r\n", key); Console.WriteLine("[*] PKCS1 Private key\r\n"); Console.WriteLine(certDictionary[key].First); Console.WriteLine("\r\n[*] Certificate\r\n"); Console.WriteLine(certDictionary[key].Second); Console.WriteLine(); } } }
public static void TriageCertFile(string certFilePath, Dictionary <string, string> MasterKeys, bool machine = false) { // triage a certificate file var fileName = Path.GetFileName(certFilePath); Console.WriteLine("\r\n Certificate file : {0}\r\n", fileName); var certificateArray = File.ReadAllBytes(certFilePath); try { ExportedCertificate cert = Dpapi.DescribeCertificate(certificateArray, MasterKeys, machine); if (cert.Thumbprint != "") { Console.WriteLine(" Thumbprint: {0}", cert.Thumbprint); Console.WriteLine(" Issuer: {0}", cert.Issuer); Console.WriteLine(" Subject: {0}", cert.Subject); Console.WriteLine(" Valid Date: {0}", cert.ValidDate); Console.WriteLine(" Expiry Date: {0}", cert.ExpiryDate); } if (cert.EKUs.Count > 0) { Console.WriteLine(" Enhanced Key Usages:"); foreach (var eku in cert.EKUs) { Console.WriteLine(" {0} ({1})", eku.First, eku.Second); if (eku.Second == "1.3.6.1.5.5.7.3.2") { Console.WriteLine(" [!] Certificate is used for client auth!"); } } } if (cert.PrivateKey != "") { Console.WriteLine(" [*] Private key file {0} was recovered:\r\n", fileName); Console.WriteLine(cert.PrivateKey); Console.WriteLine(cert.PublicCertificate); Console.WriteLine(); } } catch (Exception e) { Console.WriteLine("[X] Error triaging {0} : {1}", fileName, e.Message); } Console.WriteLine(); }
public static void TriageUserCerts(Dictionary <string, string> MasterKeys, string computerName = "") { string[] userDirs; if (!String.IsNullOrEmpty(computerName)) { // if we're triaging a remote computer, check connectivity first var canAccess = Helpers.TestRemote(computerName); if (!canAccess) { return; } } //TODO have not verified with multiple users if (Helpers.IsHighIntegrity() || (!String.IsNullOrEmpty(computerName) && Helpers.TestRemote(computerName))) { var userFolder = !String.IsNullOrEmpty(computerName) ? $"\\\\{computerName}\\C$\\Users\\" : $"{Environment.GetEnvironmentVariable("SystemDrive")}\\Users\\"; userDirs = Directory.GetDirectories(userFolder); } else { // otherwise we're only triaging the current user's path userDirs = new string[] { Environment.GetEnvironmentVariable("USERPROFILE") }; } foreach (var dir in userDirs) { var parts = dir.Split('\\'); var userName = parts[parts.Length - 1]; if (dir.EndsWith("Public") || dir.EndsWith("Default") || dir.EndsWith("Default User") || dir.EndsWith("All Users")) { continue; } var userCertkeysBasePath = $"{dir}\\AppData\\Roaming\\Microsoft\\Crypto\\RSA\\"; if (!Directory.Exists(userCertkeysBasePath)) { continue; } var certDictionary = new Dictionary <string, Tuple <string, string> >(); var directories = Directory.GetDirectories(userCertkeysBasePath); foreach (var directory in directories) { var files = Directory.GetFiles(directory); foreach (var file in files) { if (!Regex.IsMatch(file, @"[0-9A-Fa-f]{32}[_][0-9A-Fa-f]{8}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{12}")) { continue; } var fileName = Path.GetFileName(file); Console.WriteLine("\r\nCertificate file : {0}\r\n", fileName); var certificateArray = File.ReadAllBytes(file); try { certDictionary.Add(fileName, Dpapi.DescribeCertificate(certificateArray, MasterKeys)); } catch (Exception e) { Console.WriteLine("[X] Error triaging {0} : {1}", fileName, e.Message); } } } Console.WriteLine(); foreach (var key in certDictionary.Keys) { if (string.IsNullOrEmpty(certDictionary[key].First)) { continue; } Console.WriteLine("[*] Private key file {0} was recovered\r\n", key); Console.WriteLine("[*] PKCS1 Private key\r\n"); Console.WriteLine(certDictionary[key].First); Console.WriteLine("\r\n[*] Certificate\r\n"); Console.WriteLine(certDictionary[key].Second); Console.WriteLine(); } Console.WriteLine("[*] Hint: openssl pkcs12 -export -inkey key.pem -in cert.cer -out cert.p12"); } }