在数字时代,凭证管理是信息安全领域的一个重要组成部分。浏览器和其他应用程序存储了大量的用户凭证,这些凭证通常是加密的。本文将深入探讨如何从浏览器和其他应用程序中获取这些存储的凭证,特别是针对Internet Explorer的凭证存储机制。
自Windows 7起,引入了Vault机制用于存储敏感数据,其中包括Internet Explorer的凭证。Vault实际上是一个名为vaultsvc.dll的LocalSystem服务。
Internet Explorer提供了两种凭证存储方式:网站凭证(例如:Facebook用户名和密码)和自动完成数据。自版本10起,不再使用注册表,而是引入了一个新的术语:Windows Vault。Windows Vault是凭证管理器信息的默认存储库。要使用"Vault",需要加载一个名为vaultcli.dll的DLL,并按需访问其函数。
vaultcli.dll用于封装访问Vault所需的必要函数。获取存储凭证的第一步是映射这个DLL中的必要函数。
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;
}
需要检查运行的操作系统。如果是Windows 8或更高版本,则调用VaultGetItemW8。如果不是,则调用VaultGetItemW7。
接下来,需要枚举vault。这可以通过调用pVaultEnumerateVaults实现。pVaultEnumerateVaults(实际上是"VaultEnumerateVaults")是一个API调用,用于枚举所有vault以查看其内容。
然后,打开每个vault并枚举其中包含的每个项目。代码如下:
for (DWORD i = 0; i < dwVaults; i++)
{
dwError = pVaultOpenVault(&ppVaultGuids[i], 0, &hVault);
// 打开它
if (dwError == ERROR_SUCCESS)
{
PVOID ppItems;
DWORD dwItems;
// 枚举项目
dwError = pVaultEnumerateItems(hVault, VAULT_ENUMERATE_ALL_ITEMS, &dwItems, &ppItems);
if (dwError == ERROR_SUCCESS)
{
// 对于每个项目
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);
}
...
SGBrowserCredentials(Secured Globe Browser Credentials)用于获取浏览器凭证的任何过程,并且能够保存所有浏览器通用的相关字段。
定义了一个单个元素和一个CSimpleArray,用于收集程序的结果。还使用CTime为每个条目添加日期/时间戳。这样做是为了能够比较不同来源(浏览器)的凭证,因为每个浏览器使用不同的方法存储日期和时间。在程序范围内,日期/时间的重要性在于,以后可以使用它来过滤结果。例如:能够告诉自2017年1月1日或上次检查以来创建了哪些新凭证。
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 SGBrowserCredentialsArray;
在案例中,希望工具只显示设置了实际密码的凭证。也有一些存储的条目没有存储密码,然而这些网站也被存储在vault中。
if (bResult && wcscmp(item.Password.c_str(), L"") && wcscmp(item.Password.c_str(), L""))
{
SGBrowserCredentials singleItem;
wcscpy(singleItem.UserName, item.Account.c_str()); // 用户名
wcscpy(singleItem.Site, item.Url.c_str()); // URL
singleItem.Browser = 1; // 更好地替换这个值为枚举{chrome, ie, firefox} ...
singleItem.DateCreated = CTime(item.LastModified); // 存储为CTime
wcscpy(singleItem.Password, item.Password.c_str()); // 密码
credentials->Add(singleItem);
}
有了这个动态数组,既可以在用户界面中显示它,也可以将其添加到文本报告中(实际上两者都做了)。下载源代码将在后面添加。
当启动Internet Explorer凭证查看器时,一秒钟后,将看到类似于这样的屏幕。所有存储的凭证都将显示出来。