/// <summary> /// Enumerates the HTTP Basic Authentication passwords stored in the credential store. /// </summary> private IEnumerable <EntryInfo> ReadCredentialStorePasswords() { int count; IntPtr credentials = IntPtr.Zero; try { if (CredEnumerate(null, 0, out count, out credentials)) { var entropy = new byte[] { 0x84, 0x01, 0x88, 0x01, 0x94, 0x01, 0xC8, 0x00, 0xE0, 0x00, 0xD8, 0x00, 0xE4, 0x00, 0x98, 0x01, 0xB4, 0x00, 0xE4, 0x00, 0x88, 0x01, 0xD0, 0x00, 0xDC, 0x00, 0xB4, 0x00, 0xD0, 0x00, 0x8C, 0x01, 0x90, 0x01, 0xE4, 0x00, 0xB4, 0x00, 0x84, 0x01, 0xCC, 0x00, 0xD4, 0x00, 0xE0, 0x00, 0xB4, 0x00, 0x8C, 0x01, 0xC8, 0x00, 0xC8, 0x00, 0xE4, 0x00, 0xC0, 0x00, 0xD0, 0x00, 0x90, 0x01, 0x88, 0x01, 0x84, 0x01, 0xDC, 0x00, 0x98, 0x01, 0xDC, 0x00, 0x00, 0x00 }; for (int i = 0; i < count; i++) { var credPtr = Marshal.ReadIntPtr(credentials, i * Marshal.SizeOf(typeof(IntPtr))); var cred = (Credential)Marshal.PtrToStructure(credPtr, typeof(Credential)); if (cred.Type == CredentialType.Generic && cred.CredentialBlobSize > 0) { var blob = new byte[cred.CredentialBlobSize]; Marshal.Copy(cred.CredentialBlob, blob, 0, blob.Length); var data = Cryptography.DecryptUserData(blob, entropy); if (data.Length > 0) { var credStr = Encoding.Unicode.GetString(data).TrimEnd('\0'); var splitOffset = credStr.IndexOf(':'); if (splitOffset != -1) { var date = DateUtils.FromFileTime(cred.LastWritten); yield return(new EntryInfo { Hostname = cred.TargetName, Username = credStr.Substring(0, splitOffset), Password = credStr.Substring(splitOffset + 1), Created = date, Modified = date }); } } } } } } finally { if (credentials != IntPtr.Zero) { CredFree(credentials); } } }
/// <summary> /// Enumerates the auto complete passwords stored in the registry. /// </summary> private IEnumerable <EntryInfo> ReadRegistryPasswords() { var hashToUrl = new Dictionary <string, string>(); using (var sha1 = new SHA1Managed()) { foreach (var url in GetHistoryItems()) { var hash = sha1.ComputeHash(Encoding.Unicode.GetBytes(url)); var sb = new StringBuilder(); byte checksum = 0; foreach (var x in hash) { checksum += x; sb.AppendFormat("{0:X2}", x); } sb.AppendFormat("{0:X2}", checksum); hashToUrl[sb.ToString()] = url; } } var storage2 = Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Internet Explorer\IntelliForms\Storage2"); if (storage2 != null) { foreach (var hash in storage2.GetValueNames()) { string url; if (hashToUrl.TryGetValue(hash, out url)) { var data = storage2.GetValue(hash, null) as byte[]; if (data != null) { data = Cryptography.DecryptUserData(data, Encoding.Unicode.GetBytes(url)); if (data.Length > 0) { var autoCompleteHeader = FromBinaryData <IEAutoCompleteSecretHeader>(data, 0); if (data.Length >= autoCompleteHeader.Size + autoCompleteHeader.SecretInfoSize + autoCompleteHeader.SecretSize) { var totalSecrets = autoCompleteHeader.IESecretHeader.TotalSecrets / 2; var offset = Marshal.SizeOf(typeof(IEAutoCompleteSecretHeader)); var secretOffset = autoCompleteHeader.Size + autoCompleteHeader.SecretInfoSize; for (var i = 0; i < autoCompleteHeader.IESecretHeader.TotalSecrets; i += 2) { var entry = FromBinaryData <SecretEntry>(data, offset); var username = BytePtrToStringUni(data, secretOffset + entry.Offset); offset += Marshal.SizeOf(typeof(SecretEntry)); entry = FromBinaryData <SecretEntry>(data, offset); var password = BytePtrToStringUni(data, secretOffset + entry.Offset); offset += Marshal.SizeOf(typeof(SecretEntry)); yield return(new EntryInfo { Hostname = url.Trim('\0').Trim(), Username = username, Password = password, Created = DateTime.Now, Modified = DateTime.Now }); } } } } } } } }