예제 #1
0
        public static Dictionary <string, string> TriageUserMasterKeysWithPass(string password, bool show = false)
        {
            Dictionary <string, string> mappings = new Dictionary <string, string>();
            string userName          = Environment.GetEnvironmentVariable("USERNAME");
            string userDPAPIBasePath = String.Format("{0}\\AppData\\Roaming\\Microsoft\\Protect\\", System.Environment.GetEnvironmentVariable("USERPROFILE"));

            if (System.IO.Directory.Exists(userDPAPIBasePath))
            {
                string[] directories = Directory.GetDirectories(userDPAPIBasePath);
                foreach (string directory in directories)
                {
                    string[] files  = Directory.GetFiles(directory);
                    string   domain = System.Net.NetworkInformation.IPGlobalProperties.GetIPGlobalProperties().DomainName;
                    Dpapi.CalculateKeys(password, directory, false);

                    byte[] hmacbytes;

                    if (domain == "")
                    {
                        hmacbytes = Dpapi.CalculateKeys(password, directory, false); //convert user password to SHA1
                    }
                    else
                    {
                        hmacbytes = Dpapi.CalculateKeys(password, directory, true);
                    }

                    foreach (string file in files)
                    {
                        if (Regex.IsMatch(file, @"[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}"))
                        {
                            string fileName = System.IO.Path.GetFileName(file);
                            if (show)
                            {
                                Console.WriteLine("[*] Found MasterKey : {0}", file);
                            }
                            byte[] masteyKeyBytes = File.ReadAllBytes(file);
                            try
                            {
                                Dictionary <string, string> mapping = Dpapi.DecryptMasterKeyWithSha(masteyKeyBytes, hmacbytes);
                                mapping.ToList().ForEach(x => mappings.Add(x.Key, x.Value));
                            }
                            catch (Exception e)
                            {
                                Console.WriteLine("[X] Error triaging {0} : {1}", file, e.Message);
                            }
                        }
                    }
                }
            }
            return(mappings);
        }
예제 #2
0
        private static Dictionary <string, string> DecryptSystemMasterKeys(StringBuilder sb, List <byte[]> Dpapikeys, List <byte[]> machineMasterKeys = null, List <byte[]> userMasterKeys = null)
        {
            var mappings = new Dictionary <string, string>();

            if (machineMasterKeys != null)
            {
                foreach (byte[] masteyKeyBytes in machineMasterKeys)
                {
                    try
                    {
                        // use the "machine" DPAPI key
                        var plaintextMasterkey = Dpapi.DecryptMasterKeyWithSha(masteyKeyBytes, Dpapikeys[0]);
                        mappings.Add(plaintextMasterkey.Key, plaintextMasterkey.Value);
                    }
                    catch (Exception e)
                    {
                        sb.AppendLine(String.Format("[-] Error triaging {0} ", e.Message));
                    }
                }
            }
            if (userMasterKeys != null)
            {
                foreach (byte[] masteyKeyBytes in userMasterKeys)
                {
                    try
                    {
                        // use the "user" DPAPI key
                        var plaintextMasterKey = Dpapi.DecryptMasterKeyWithSha(masteyKeyBytes, Dpapikeys[1]);
                        mappings.Add(plaintextMasterKey.Key, plaintextMasterKey.Value);
                    }
                    catch (Exception e)
                    {
                        sb.AppendLine(String.Format("[-] Error triaging {0} ", e.Message));
                    }
                }
            }
            return(mappings);
        }
예제 #3
0
        public static Dictionary <string, string> TriageSystemMasterKeys(bool show = false)
        {
            // retrieve the DPAPI_SYSTEM key and use it to decrypt any SYSTEM DPAPI masterkeys

            Dictionary <string, string> mappings = new Dictionary <string, string>();

            if (Helpers.IsHighIntegrity())
            {
                // get the system and user DPAPI backup keys, showing the machine DPAPI keys
                //  { machine , user }

                List <byte[]> keys = LSADump.GetDPAPIKeys(true);

                string systemFolder = String.Format("{0}\\Windows\\System32\\Microsoft\\Protect\\", Environment.GetEnvironmentVariable("SystemDrive"));

                string[] systemDirs = Directory.GetDirectories(systemFolder);

                foreach (string directory in systemDirs)
                {
                    string[] machineFiles = Directory.GetFiles(directory);
                    string[] userFiles    = new string[0];

                    if (Directory.Exists(String.Format("{0}\\User\\", directory)))
                    {
                        userFiles = Directory.GetFiles(String.Format("{0}\\User\\", directory));
                    }

                    foreach (string file in machineFiles)
                    {
                        if (Regex.IsMatch(file, @"[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}"))
                        {
                            string fileName = System.IO.Path.GetFileName(file);
                            if (show)
                            {
                                Console.WriteLine("[*] Found SYSTEM system MasterKey : {0}", file);
                            }

                            byte[] masteyKeyBytes = File.ReadAllBytes(file);
                            try
                            {
                                // use the "machine" DPAPI key
                                Dictionary <string, string> mapping = Dpapi.DecryptMasterKeyWithSha(masteyKeyBytes, keys[0]);
                                mapping.ToList().ForEach(x => mappings.Add(x.Key, x.Value));
                            }
                            catch (Exception e)
                            {
                                Console.WriteLine("[X] Error triaging {0} : {1}", file, e.Message);
                            }
                        }
                    }

                    foreach (string file in userFiles)
                    {
                        if (Regex.IsMatch(file, @"[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}"))
                        {
                            string fileName = System.IO.Path.GetFileName(file);
                            if (show)
                            {
                                Console.WriteLine("[*] Found SYSTEM user MasterKey : {0}", file);
                            }

                            byte[] masteyKeyBytes = File.ReadAllBytes(file);
                            try
                            {
                                // use the "user" DPAPI key
                                Dictionary <string, string> mapping = Dpapi.DecryptMasterKeyWithSha(masteyKeyBytes, keys[1]);
                                mapping.ToList().ForEach(x => mappings.Add(x.Key, x.Value));
                            }
                            catch (Exception e)
                            {
                                Console.WriteLine("[X] Error triaging {0} : {1}", file, e.Message);
                            }
                        }
                    }
                }
            }
            else
            {
                Console.WriteLine("\r\n[X] Must be elevated to triage SYSTEM masterkeys!\r\n");
            }

            return(mappings);
        }
예제 #4
0
파일: Triage.cs 프로젝트: zhouzu/SharpDPAPI
        public static Dictionary <string, string> TriageSystemMasterKeys(bool show = false)
        {
            // retrieve the DPAPI_SYSTEM key and use it to decrypt any SYSTEM DPAPI masterkeys

            var mappings = new Dictionary <string, string>();

            if (Helpers.IsHighIntegrity())
            {
                // get the system and user DPAPI backup keys, showing the machine DPAPI keys
                //  { machine , user }

                var keys = LSADump.GetDPAPIKeys(true);
                Helpers.GetSystem();
                var systemFolder =
                    $"{Environment.GetEnvironmentVariable("SystemDrive")}\\Windows\\System32\\Microsoft\\Protect\\";

                var systemDirs = Directory.GetDirectories(systemFolder);

                foreach (var directory in systemDirs)
                {
                    var machineFiles = Directory.GetFiles(directory);
                    var userFiles    = new string[0];

                    if (Directory.Exists($"{directory}\\User\\"))
                    {
                        userFiles = Directory.GetFiles($"{directory}\\User\\");
                    }

                    foreach (var file in machineFiles)
                    {
                        if (!Regex.IsMatch(file, @".*\\[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);
                        if (show)
                        {
                            Console.WriteLine("[*] Found SYSTEM system MasterKey : {0}", file);
                        }

                        var masteyKeyBytes = File.ReadAllBytes(file);
                        try
                        {
                            // use the "machine" DPAPI key
                            var plaintextMasterkey = Dpapi.DecryptMasterKeyWithSha(masteyKeyBytes, keys[0]);
                            mappings.Add(plaintextMasterkey.Key, plaintextMasterkey.Value);
                        }
                        catch (Exception e)
                        {
                            Console.WriteLine("[X] Error triaging {0} : {1}", file, e.Message);
                        }
                    }

                    foreach (var file in userFiles)
                    {
                        if (!Regex.IsMatch(file, @".*\\[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);
                        if (show)
                        {
                            Console.WriteLine("[*] Found SYSTEM user MasterKey : {0}", file);
                        }

                        var masteyKeyBytes = File.ReadAllBytes(file);
                        try
                        {
                            // use the "user" DPAPI key
                            var plaintextMasterKey = Dpapi.DecryptMasterKeyWithSha(masteyKeyBytes, keys[1]);
                            mappings.Add(plaintextMasterKey.Key, plaintextMasterKey.Value);
                        }
                        catch (Exception e)
                        {
                            Console.WriteLine("[X] Error triaging {0} : {1}", file, e.Message);
                        }
                    }
                }
            }
            else
            {
                Console.WriteLine("\r\n[X] Must be elevated to triage SYSTEM masterkeys!\r\n");
            }

            return(mappings);
        }
예제 #5
0
파일: Triage.cs 프로젝트: zhouzu/SharpDPAPI
        public static Dictionary <string, string> TriageUserMasterKeys(byte[] backupKeyBytes, bool show = false, string computerName = "", string password = "", string target = "")
        {
            // triage all *user* masterkeys we can find, decrypting if the backupkey is supplied

            var mappings  = new Dictionary <string, string>();
            var canAccess = false;

            if (!String.IsNullOrEmpty(target))
            {
                // if we're targeting specific masterkey files

                if (backupKeyBytes.Length == 0)
                {
                    // currently only backupkey is supported
                    Console.WriteLine("[X] The masterkey '/target:X' option currently requires '/pvk:BASE64...'");
                    return(mappings);
                }

                if (!File.Exists(target) && !Directory.Exists(target))
                {
                    Console.WriteLine($"[X] The target '{target}' doesn't exist!");
                    return(mappings);
                }

                KeyValuePair <string, string> plaintextMasterKey;

                if ((File.GetAttributes(target) & FileAttributes.Directory) == FileAttributes.Directory)
                {
                    // if we're triaging a folder of masterkeys
                    var files = Directory.GetFiles(target);
                    foreach (var file in files)
                    {
                        try
                        {
                            FileInfo f = new FileInfo(file);

                            if (Helpers.IsGuid(f.Name))
                            {
                                var masterKeyBytes = File.ReadAllBytes(file);
                                plaintextMasterKey = Dpapi.DecryptMasterKey(masterKeyBytes, backupKeyBytes);
                                mappings.Add(plaintextMasterKey.Key, plaintextMasterKey.Value);
                            }
                        }
                        catch (Exception e)
                        {
                            Console.WriteLine("[X] Error triaging masterkey target '{0}' : {1}", target, e.Message);
                        }
                    }
                }
                else
                {
                    // otherwise we're triaging one file
                    try
                    {
                        var masterKeyBytes = File.ReadAllBytes(target);
                        plaintextMasterKey = Dpapi.DecryptMasterKey(masterKeyBytes, backupKeyBytes);
                        mappings.Add(plaintextMasterKey.Key, plaintextMasterKey.Value);
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine("[X] Error triaging masterkey target '{0}' : {1}", target, e.Message);
                    }
                }
            }

            else
            {
                if (!String.IsNullOrEmpty(computerName))
                {
                    canAccess = Helpers.TestRemote(computerName);
                    if (!canAccess)
                    {
                        return(new Dictionary <string, string>());
                    }
                }

                string[] userDirs;

                if (Helpers.IsHighIntegrity() || (!String.IsNullOrEmpty(computerName) && canAccess))
                {
                    // if elevated, triage ALL reachable masterkeys

                    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)
                {
                    if (dir.EndsWith("Public") || dir.EndsWith("Default") || dir.EndsWith("Default User") || dir.EndsWith("All Users"))
                    {
                        continue;
                    }

                    var userDPAPIBasePath = $"{dir}\\AppData\\Roaming\\Microsoft\\Protect\\";
                    if (!Directory.Exists(userDPAPIBasePath))
                    {
                        continue;
                    }

                    var directories = Directory.GetDirectories(userDPAPIBasePath);
                    foreach (var directory in directories)
                    {
                        var    files     = Directory.GetFiles(directory);
                        var    isDomain  = false;
                        byte[] hmacBytes = null;

                        foreach (var file in files)
                        {
                            // if the BK-<NETBIOSDOMAINNAME> file exists, assume this is a domain user.
                            if (Regex.IsMatch(file, @".*\\BK-[0-9A-Za-z]+"))
                            {
                                isDomain = true; // means use the NTLM of the user password instead of the SHA1
                            }
                        }

                        if (!String.IsNullOrEmpty(password))
                        {
                            hmacBytes = Dpapi.CalculateKeys(password, directory, isDomain);
                        }

                        foreach (var file in files)
                        {
                            if (!Regex.IsMatch(file, @"[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;
                            }

                            if (show)
                            {
                                Console.WriteLine("[*] Found MasterKey : {0}", file);
                            }

                            var masterKeyBytes = File.ReadAllBytes(file);
                            try
                            {
                                KeyValuePair <string, string> plaintextMasterKey;
                                if (!String.IsNullOrEmpty(password))
                                {
                                    plaintextMasterKey = Dpapi.DecryptMasterKeyWithSha(masterKeyBytes, hmacBytes);
                                }
                                else
                                {
                                    plaintextMasterKey = Dpapi.DecryptMasterKey(masterKeyBytes, backupKeyBytes);
                                }

                                mappings.Add(plaintextMasterKey.Key, plaintextMasterKey.Value);
                            }
                            catch (Exception e)
                            {
                                // Console.WriteLine("[X] Error triaging {0} : {1}", file, e.Message);
                            }
                        }
                    }
                }
            }

            if (!String.IsNullOrEmpty(password))
            {
                if (mappings.Count == 0)
                {
                    Console.WriteLine("\n[!] No master keys decrypted!\r\n");
                }
                else
                {
                    Console.WriteLine("\n[*] User master key cache:\r\n");
                    foreach (var kvp in mappings)
                    {
                        Console.WriteLine("{0}:{1}", kvp.Key, kvp.Value);
                    }
                    Console.WriteLine();
                }
            }

            Console.WriteLine();
            return(mappings);
        }
예제 #6
0
        public static Dictionary <string, string> TriageUserMasterKeys(byte[] backupKeyBytes, bool show = false, string computerName = "", string password = "")
        {
            // triage all *user* masterkeys we can find, decrypting if the backupkey is supplied

            Dictionary <string, string> mappings = new Dictionary <string, string>();
            bool canAccess = false;

            if (!String.IsNullOrEmpty(computerName))
            {
                canAccess = Helpers.TestRemote(computerName);
                if (!canAccess)
                {
                    return(new Dictionary <string, string>());
                }
            }

            string[] userDirs;

            if (Helpers.IsHighIntegrity() || (!String.IsNullOrEmpty(computerName) && canAccess))
            {
                // if elevated, triage ALL reachable masterkeys

                string userFolder = "";

                if (!String.IsNullOrEmpty(computerName))
                {
                    userFolder = String.Format("\\\\{0}\\C$\\Users\\", computerName);
                }
                else
                {
                    userFolder = String.Format("{0}\\Users\\", Environment.GetEnvironmentVariable("SystemDrive"));
                }

                userDirs = Directory.GetDirectories(userFolder);
            }
            else
            {
                // otherwise we're only triaging the current user's path
                userDirs = new string[] { System.Environment.GetEnvironmentVariable("USERPROFILE") };
            }

            foreach (string dir in userDirs)
            {
                string[] parts    = dir.Split('\\');
                string   userName = parts[parts.Length - 1];
                if (!(dir.EndsWith("Public") || dir.EndsWith("Default") || dir.EndsWith("Default User") || dir.EndsWith("All Users")))
                {
                    string userDPAPIBasePath = String.Format("{0}\\AppData\\Roaming\\Microsoft\\Protect\\", dir);
                    if (System.IO.Directory.Exists(userDPAPIBasePath))
                    {
                        string[] directories = Directory.GetDirectories(userDPAPIBasePath);
                        foreach (string directory in directories)
                        {
                            string[] files     = Directory.GetFiles(directory);
                            bool     isDomain  = false;
                            byte[]   hmacbytes = null;

                            foreach (string file in files)
                            {
                                // if the BK-<NETBIOSDOMAINNAME> file exists, assume this is a domain user.
                                if (Regex.IsMatch(file, @".*\\BK-[0-9A-Za-z]+"))
                                {
                                    isDomain = true; // means use the NTLM of the user password instead of the SHA1
                                }
                            }

                            if (!String.IsNullOrEmpty(password))
                            {
                                hmacbytes = Dpapi.CalculateKeys(password, directory, isDomain);
                            }

                            foreach (string file in files)
                            {
                                if (Regex.IsMatch(file, @"[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}"))
                                {
                                    string fileName = System.IO.Path.GetFileName(file);
                                    if (show)
                                    {
                                        Console.WriteLine("[*] Found MasterKey : {0}", file);
                                    }

                                    byte[] masteyKeyBytes = File.ReadAllBytes(file);
                                    try
                                    {
                                        if (!String.IsNullOrEmpty(password))
                                        {
                                            Dictionary <string, string> mapping = Dpapi.DecryptMasterKeyWithSha(masteyKeyBytes, hmacbytes);
                                            mapping.ToList().ForEach(x => mappings.Add(x.Key, x.Value));
                                        }
                                        else
                                        {
                                            Dictionary <string, string> mapping = Dpapi.DecryptMasterKey(masteyKeyBytes, backupKeyBytes);
                                            mapping.ToList().ForEach(x => mappings.Add(x.Key, x.Value));
                                        }
                                    }
                                    catch (Exception e)
                                    {
                                        Console.WriteLine("[X] Error triaging {0} : {1}", file, e.Message);
                                    }
                                }
                            }
                        }
                    }
                }
            }

            if (!String.IsNullOrEmpty(password))
            {
                if (mappings.Count == 0)
                {
                    Console.WriteLine("\n[!] No master keys decrypted!\r\n");
                }
                else
                {
                    Console.WriteLine("\n[*] User master key cache:\r\n");
                    foreach (KeyValuePair <string, string> kvp in mappings)
                    {
                        Console.WriteLine("{0}:{1}", kvp.Key, kvp.Value);
                    }
                    Console.WriteLine();
                }
            }

            Console.WriteLine();
            return(mappings);
        }