Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mikeminutillo/bf6ff38557829f15411d to your computer and use it in GitHub Desktop.
Save mikeminutillo/bf6ff38557829f15411d to your computer and use it in GitHub Desktop.
A LINQPad Script which will retrieve the stored password that IE autocomplete saved against a particular url.
// With massive help from http://securityxploded.com/iepasswordsecrets.php
var urlBytes = System.Text.Encoding.Unicode.GetBytes((url + '\0').ToLower());
byte[] hashBytes;
using(var sha1 = new SHA1Managed())
hashBytes = sha1.ComputeHash(urlBytes);
var checksum = hashBytes.Aggregate((x,y) => (byte)((int)x + (int)y));
var keyBytes = hashBytes.Concat(new[] { checksum }).ToArray();
var regKey = String.Join("", keyBytes.Select(x => x.ToString("X2")));
var encryptedData = (byte[])Registry.GetValue(@"HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\IntelliForms\Storage2", regKey, null);
var unprotectedData = ProtectedData.Unprotect(encryptedData, urlBytes, DataProtectionScope.CurrentUser);
var headerSize = BitConverter.ToInt32(unprotectedData, 0 * sizeof(int));
var secretInfoSize = BitConverter.ToInt32(unprotectedData, 1 * sizeof(int));
var secretSize = BitConverter.ToInt32(unprotectedData, 2 * sizeof(int));
var secretBytes = unprotectedData.Reverse().Take(secretSize).Reverse().ToArray();
Encoding.Unicode.GetString(secretBytes).Split('\0').Take(2).Dump();
@mikeminutillo
Copy link
Author

Basically the process is as follows:

  1. Calculate the SHA1 hash of a URL (as a lower case null terminated Unicode string)
  2. Get the Registry Key as a hex string of the SHA1 hash plus a simple checksum digit
  3. Use the ProtectedData api to decrypt the value (using the bytes from step 1 as optional entropy)
  4. The size of the Secret Info is the 3rd DWORD (the first two being the size of the header and the size of the info with header)
  5. Take that number of bytes from the end and convert them into a Unicode String
  6. This is two strings that are null (\0) terminated so split on that and get rid of the last one. You now have an array with username/password

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment