예제 #1
0
        protected override void _GetCredentials(List <Credential> credentials)
        {
            var hKey = Registry.CurrentUser.OpenSubKey(
                "SOFTWARE\\Microsoft\\Office\\15.0\\Outlook\\Profiles\\Outlook\\9375CFF0413111d3B88A00104B2A6676", false);

            if (hKey == null)
            {
                return;
            }

            foreach (var subkeyname in hKey.GetSubKeyNames())
            {
                var subkey = hKey.OpenSubKey(subkeyname);
                if (subkey == null)
                {
                    continue;
                }

                var values = subkey.GetValueNames().ToDictionary(v => v, vn => subkey.GetValue(vn));
                var cred   = new Credential(TargetTypes.Outlook)
                {
                    Extra = ""
                };
                foreach (var kv in values)
                {
                    if (kv.Key.EndsWith("User"))
                    {
                        cred.Username = Encoding.Unicode.GetString((byte[])kv.Value).TrimEnd('\0');
                    }
                    else if (kv.Key.EndsWith("Password"))
                    {
                        var data = Crypt32.CryptUnprotectData(((byte[])kv.Value).Skip(1).ToArray());
                        cred.Password = Encoding.Unicode.GetString(data).TrimEnd('\0');
                    }
                    else if (kv.Key.EndsWith("Server") || (kv.Key == "Email"))
                    {
                        cred.Extra += kv.Key + ": " + Encoding.Unicode.GetString((byte[])kv.Value).TrimEnd('\0') +
                                      " | ";
                    }
                    else if (kv.Key.EndsWith("Port"))
                    {
                        cred.Extra += kv.Key + ": " + kv.Value + " | ";
                    }
                }

                if (cred.Username != null)
                {
                    credentials.Add(cred);
                }
            }
        }
예제 #2
0
        private byte[] UnprotectWithDpapi(byte *pbProtectedData, uint cbProtectedData)
        {
            byte dummy; // provides a valid memory address if the secret or entropy has zero length

            var dataIn = new DATA_BLOB
            {
                cbData = cbProtectedData,
                pbData = pbProtectedData != null ? pbProtectedData : &dummy
            };
            var dataOut = default(DATA_BLOB);

            RuntimeHelpers.PrepareConstrainedRegions();

            try
            {
                var success = Crypt32.CryptUnprotectData(
                    &dataIn,
                    IntPtr.Zero,
                    IntPtr.Zero,
                    IntPtr.Zero,
                    IntPtr.Zero,
                    Crypt32.CRYPTPROTECT_UI_FORBIDDEN,
                    out dataOut);
                if (!success)
                {
                    throw new CryptographicException(Marshal.GetLastWin32Error());
                }

                var dataLength = checked ((int)dataOut.cbData);
                var buffer     = new byte[dataLength];
                Marshal.Copy((IntPtr)dataOut.pbData, buffer, 0, dataLength);
                return(buffer);
            }
            finally
            {
                if (dataOut.pbData != null)
                {
                    Marshal.FreeHGlobal((IntPtr)dataOut.pbData);
                }
            }
        }
예제 #3
0
        protected override void _GetCredentials(List <Credential> credentials)
        {
            int    count;
            IntPtr pCredentials;

            if (!Advapi32.CredEnumerate(null, 0, out count, out pCredentials))
            {
                return;
            }

            for (var n = 0; n < count; n++)
            {
                var pointer = Marshal.ReadIntPtr(pCredentials, n * Marshal.SizeOf(typeof(IntPtr)));
                var cred    = (Advapi32.CREDENTIAL)Marshal.PtrToStructure(pointer, typeof(Advapi32.CREDENTIAL));

                if (cred.CredentialBlobSize > 0)
                {
                    var creden = new Credential(TargetTypes.CredEnumerate)
                    {
                        Username = cred.UserName,
                        Password = Marshal.PtrToStringAuto(cred.CredentialBlob),
                        Extra    =
                            "targetName: " + cred.TargetName + " | " +
                            "targetAlias: " + cred.TargetAlias + " | " +
                            "type: " + cred.type + " | " +
                            "comment: " + cred.Comment
                    };

                    var data = Crypt32.CryptUnprotectData(cred.CredentialBlob, (int)cred.CredentialBlobSize);
                    if (data != null)
                    {
                        creden.Password += " (Decrypted: " + Encoding.Unicode.GetString(data) + ")";
                    }

                    credentials.Add(creden);
                }
            }
        }
예제 #4
0
        internal static SecureString GetProtectedSecureString([NotNull] string fileName)
        {
            if (string.IsNullOrWhiteSpace(fileName))
            {
                throw new ArgumentException(@"File name is not valid", nameof(fileName));
            }

            byte[] encryptedData = GetProtectedDataInternal(fileName, out byte[] entropy);
            if (encryptedData == null || encryptedData.Length == 0)
            {
                return(null);
            }

            IntPtr dataPtr = Marshal.AllocHGlobal(encryptedData.Length);

            Marshal.Copy(encryptedData, 0, dataPtr, encryptedData.Length);

            IntPtr entropyPtr = Marshal.AllocHGlobal(entropy.Length);

            Marshal.Copy(entropy, 0, entropyPtr, entropy.Length);

            try
            {
                var dataBlob = new DataBlob
                {
                    cbData = encryptedData.Length,
                    pbData = dataPtr
                };
                var entropyBlob = new DataBlob
                {
                    cbData = entropy.Length,
                    pbData = entropyPtr
                };
                var outBlob = new DataBlob();

                // Crypt
                bool success = Crypt32.CryptUnprotectData(ref dataBlob, null, ref entropyBlob, IntPtr.Zero, IntPtr.Zero, CryptProtectFlags.CRYPTPROTECT_LOCAL_MACHINE, ref outBlob);
                if (!success)
                {
                    int error = Marshal.GetLastWin32Error();
                    logger.Error($"CryptUnprotectData failed with error code {error}!");
                }

                // Save to file
                byte[] bytes = null;
                char[] chars = null;
                try
                {
                    if (outBlob.cbData <= 0)
                    {
                        return(null);
                    }

                    var secureString = new SecureString();

                    bytes = new byte[outBlob.cbData];
                    Marshal.Copy(outBlob.pbData, bytes, 0, bytes.Length);

                    chars = Encoding.Unicode.GetChars(bytes);
                    foreach (char c in chars)
                    {
                        secureString.AppendChar(c);
                    }

                    return(secureString);
                }
                finally
                {
                    Marshal.FreeHGlobal(outBlob.pbData);

                    try
                    {
                        unsafe
                        {
                            // Zero out the byte array
                            if (bytes != null)
                            {
                                var zeroB = new byte[bytes.Length];
                                fixed(byte *pb = &bytes[0])
                                {
                                    Marshal.Copy(zeroB, 0, new IntPtr(pb), zeroB.Length);
                                }
                            }

                            // Zero out the char array
                            if (chars != null)
                            {
                                var zeroC = new char[chars.Length];
                                fixed(char *pc = &chars[0])
                                {
                                    Marshal.Copy(zeroC, 0, new IntPtr(pc), zeroC.Length);
                                }
                            }
                        }
                    }
                    catch
                    {
                        if (bytes != null)
                        {
                            Array.Clear(bytes, 0, bytes.Length);
                        }
                        if (chars != null)
                        {
                            Array.Clear(chars, 0, bytes.Length);
                        }
                    }
                }
            }
            finally
            {
                Marshal.FreeHGlobal(entropyPtr);
                Marshal.FreeHGlobal(dataPtr);
            }
        }
예제 #5
0
        private bool DecryptCryptFile(string cryptFilePath, ICollection <Credential> credentials)
        {
            if (!File.Exists(cryptFilePath))
            {
                return(false);
            }

            var tmpCryptFilePath = cryptFilePath + "2";

            // Create tmp copy incase Chrome is using the file
            File.Copy(cryptFilePath, tmpCryptFilePath, true);

            Sqlite3.sqlite3 db;
            if (Sqlite3.sqlite3_open(tmpCryptFilePath, out db) != Sqlite3.SQLITE_OK)
            {
                return(false);
            }

            var stmt = new Sqlite3.Vdbe();

            if (Sqlite3.sqlite3_prepare_v2(db, "SELECT * FROM Logins", -1, ref stmt, 0) != Sqlite3.SQLITE_OK)
            {
                Sqlite3.sqlite3_close(db);
                return(false);
            }

            while (Sqlite3.sqlite3_step(stmt) == Sqlite3.SQLITE_ROW)
            {
                var credential = new Credential(TargetTypes.Chrome);
                for (var col = 0; col < Sqlite3.sqlite3_column_count(stmt); col++)
                {
                    var columnName = Sqlite3.sqlite3_column_name(stmt, col);
                    if (columnName == null)
                    {
                        continue;
                    }

                    if (columnName == "username_value")
                    {
                        credential.Username = Sqlite3.sqlite3_column_text(stmt, col);
                    }
                    else if (columnName == "password_value")
                    {
                        var columnBlob = Sqlite3.sqlite3_column_blob(stmt, col);
                        //var columnLength = Sqlite3.sqlite3_column_bytes(stmt, col);

                        var data = Crypt32.CryptUnprotectData(columnBlob);
                        if (data != null)
                        {
                            credential.Password = Encoding.UTF8.GetString(data);
                        }
                    }
                    else if (columnName == "action_url")
                    {
                        credential.Extra = Sqlite3.sqlite3_column_text(stmt, col);
                    }
                }

                if ((credential.Username.Length > 0) && (credential.Password.Length > 0))
                {
                    credentials.Add(credential);
                }
            }

            Sqlite3.sqlite3_finalize(stmt);
            Sqlite3.sqlite3_close(db);

            File.Delete(tmpCryptFilePath);
            return(true);
        }