Click here to Skip to main content
16,016,678 members
Articles / Security

The Secrets of Internet Explorer Credentials

Rate me:
Please Sign up or sign in to vote.
5.00/5 (10 votes)
30 Jan 2017CPOL3 min read 32.4K   173   17   13
Third of several articles covering the secrets of obtaining stored (and encrypted) credentials stored by browsers
Internet Explorer allows two methods of credentials storage: web sites credentials (for example: your Facebook user and password) and autocomplete data. The data can be easily retrieved by anyone who knows how. This article will show you how.

Introduction

This article is the third one of several articles covering the secrets of obtaining stored (and encrypted) credentials stored by browsers (and other applications, for example: MS Outlook). The first article covered Wi-Fi credentials. The second one covers Chrome's credentials. This article covers Internet Explorer and how credentials are stored and can be fetched from it.

The Vault

Since Windows 7, a Vault was created for storing any sensitive data, among it the credentials of Internet Explorer. The Vault is in fact a LocalSystem service - vaultsvc.dll.

Internet Explorer allows two methods of credentials storage: web sites credentials (for example: your Facebook user and password) and autocomplete data. Since version 10, instead of using the Registry, a new term was introduced: Windows Vault. Windows Vault is the default storage vault for the credential manager information. To use the "Vault", you load a DLL named "vaultcli.dll" and access its functions as needed.

The Vaultcli DLL

The vaultcli.dll is used to encapsulate the necessary functions to access the Vault.
Our first step towards fetching the stored credentials would be mapping the necessary functions from this DLL.

C++
BOOL InitVault(VOID) 
{
    BOOL bStatus = FALSE;

    hVaultLib = LoadLibrary(L"vaultcli.dll");

    if (hVaultLib != NULL) 
    {
        pVaultEnumerateItems = (VaultEnumerateItems)GetProcAddress
                                                  (hVaultLib, "VaultEnumerateItems");
        pVaultEnumerateVaults = (VaultEnumerateVaults)GetProcAddress
                                                  (hVaultLib, "VaultEnumerateVaults");
        pVaultFree = (VaultFree)GetProcAddress(hVaultLib, "VaultFree");
        pVaultGetItemW7 = (VaultGetItemW7)GetProcAddress(hVaultLib, "VaultGetItem");
        pVaultGetItemW8 = (VaultGetItemW8)GetProcAddress(hVaultLib, "VaultGetItem");
        pVaultOpenVault = (VaultOpenVault)GetProcAddress(hVaultLib, "VaultOpenVault");
        pVaultCloseVault = (VaultCloseVault)GetProcAddress(hVaultLib, "VaultCloseVault");

        bStatus = (pVaultEnumerateVaults != NULL)
            && (pVaultFree != NULL)
            && (pVaultGetItemW7 != NULL)
            && (pVaultGetItemW8 != NULL)
            && (pVaultOpenVault != NULL)
            && (pVaultCloseVault != NULL)
            && (pVaultEnumerateItems != NULL);
    }
    return bStatus;
}

The Process

You need to check which OS is running. If it's Windows 8 or greater, you call VaultGetItemW8. If it isn't, you call VaultGetItemW7.

The next step would be enumerating the vaults. This is done by calling:

C++
dwError = pVaultEnumerateVaults(NULL, &dwVaults, &ppVaultGuids);

pVaultEnumerateVaults (which is in fact "VaultEnumerateVaults") is an API call for enumerating all vaults in order to view their contents.

Next, we open each vault and enumerate each item it contains. The code looks like this:

C++
    for (DWORD i = 0; i < dwVaults; i++) 
    {
        dwError = pVaultOpenVault(&ppVaultGuids[i], 0, &hVault);
        // open it
        
        if (dwError == ERROR_SUCCESS) 
        {
            PVOID ppItems;
            DWORD dwItems;

            // enumerate items
            dwError = pVaultEnumerateItems
                      (hVault, VAULT_ENUMERATE_ALL_ITEMS, &dwItems, &ppItems);

            if (dwError == ERROR_SUCCESS) 
            {
                // for each item
                for (DWORD j = 0; j < dwItems; j++) 
                {
                    VAULT_ITEM item;
                    BOOL bResult = FALSE;
                    memset(&item, 0, sizeof(VAULT_ITEM));

                    if (bWin80rGreater) 
                    {
                        bResult = GetItemW8(hVault, (PVAULT_ITEM_W8)ppItems, j, item);
                    }
                    else 
                    {
                        bResult = GetItemW7(hVault, (PVAULT_ITEM_W7)ppItems, j, item);
                    }
...

Now we need to discuss our own data structure for storing browsers (and other programs') credentials.

At this point, 'item' is holding a single credentials entry and we need to store it in our own data structure, the one we designed to store credentials from various sources.

The SGBrowserCredentials Data Structure

The SGBrowserCredentials (Secured Globe Browser Credentials) is used for any process of fetching browser credentials and is capable of holding the relevant fields which are common to all browsers.

We define the single element and a CSimpleArray for the purpose of collecting the results of our program. We also use CTime for the date/time stamp of each entry. We do so to be able to compare credentials from different sources (browsers), as each browser use a different method for storing date and time. The importance of date/time for the scope of our program is to be able to use it later for filtering the results. For example: being able to tell which new credentials were created since 1.1.2017 or since the last time we checked.

C++
typedef struct _SGBrowserCredentials
{
    int Browser; // 0 = chrome, 1 = ie, 2 = firefox, 
    TCHAR Site[256];
    TCHAR UserName[80];
    TCHAR Password[256];
    CTime DateCreated;
    _SGBrowserCredentials()
    {
        Site[0] = 0;
        UserName[0] = 0;
        Password[0] = 0;
        DateCreated = NULL;
    }
} SGBrowserCredentials;

typedef CSimpleArray<SGBrowserCredentials> SGBrowserCredentialsArray;

In our case, we want our tool to only display credentials with actual passwords set. There are also stored entries for web sites with no stored passwords and yet, these sites are stored in the vault as well.

C++
if (bResult && wcscmp(item.Password.c_str(), L"") && wcscmp(item.Password.c_str(), L" "))
{
    SGBrowserCredentials singleItem;
    wcscpy(singleItem.UserName, item.Account.c_str());     // User name
    wcscpy(singleItem.Site, item.Url.c_str());             // URL
    singleItem.Browser = 1; // better replace this value with enum{chrome, ie, firefox} ...
    singleItem.DateCreated = CTime(item.LastModified);     // Date stored as CTime
    wcscpy(singleItem.Password, item.Password.c_str());    // Password
    credentials->Add(singleItem);        
}

With this dynamic array, we can either display it in our user interface or add it to a textual report (in fact, we do both). The source code for downloading will be added later on.

The Tool

Image 1

When you start Internet Explorer Credentials Viewer, a split of a second after, you will see a screen similar to this one. All your stored credentials will be displayed.

 

Further Links

Please visit my Github repos. There is also another article of mine about Chrome.

History

  • 30th January, 2017: Initial version
  • July 18th, fixed memory leaks.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
CEO Secured Globe, Inc.
United States United States
Michael Haephrati is a music composer, an inventor and an expert specializes in software development and information security, who has built a unique perspective which combines technology and the end user experience. He is the author of a the book Learning C++ , which teaches C++ 20, and was published in August 2022.

He is the CEO of Secured Globe, Inc., and also active at Stack Overflow.

Read our Corporate blog or read my Personal blog.





Comments and Discussions

 
QuestionAttribution Pin
Randor 10-Jul-22 22:07
professional Randor 10-Jul-22 22:07 
QuestionMy vote of 5 Pin
Martin Fisher218-Jun-22 13:23
Martin Fisher218-Jun-22 13:23 
AnswerRe: My vote of 5 Pin
Michael Haephrati18-Jun-22 23:39
professionalMichael Haephrati18-Jun-22 23:39 
QuestionMy vote of 5 Pin
Member 1407845219-Jul-20 3:48
Member 1407845219-Jul-20 3:48 
AnswerRe: My vote of 5 Pin
Michael Haephrati18-Jun-22 23:40
professionalMichael Haephrati18-Jun-22 23:40 
GeneralMy vote of 1 Pin
joe.frando3-Jun-18 4:04
joe.frando3-Jun-18 4:04 
GeneralMy vote of 5 Pin
Hans Flocken30-Jan-17 11:37
Hans Flocken30-Jan-17 11:37 
GeneralMy vote of 5 Pin
Hans Flocken30-Jan-17 11:36
Hans Flocken30-Jan-17 11:36 
Great
QuestionUser profiles... Pin
dandy7230-Jan-17 10:02
dandy7230-Jan-17 10:02 
AnswerRe: User profiles... Pin
Michael Haephrati30-Jan-17 11:46
professionalMichael Haephrati30-Jan-17 11:46 
GeneralRe: User profiles... Pin
dandy7230-Jan-17 16:05
dandy7230-Jan-17 16:05 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.