Internet Explorer 凭据的秘密





5.00/5 (9投票s)
几篇文章中的第三篇,涵盖获取浏览器存储(和加密)凭据的秘密
引言
本文是介绍如何获取浏览器(以及其他应用程序,例如:MS Outlook)存储的(和加密的)凭据的系列文章中的第三篇。第一篇文章介绍了 Wi-Fi 凭据。第二篇文章介绍了 Chrome 的凭据。本文介绍 Internet Explorer,以及如何存储凭据并从中获取凭据。
保险库
自 Windows 7 以来,创建了一个保险库来存储任何敏感数据,其中包括 Internet Explorer 的凭据。实际上,保险库是一个 LocalSystem
服务 - vaultsvc.dll。
Internet Explorer 允许两种凭据存储方法:网站凭据(例如:您的 Facebook 用户名和密码)和自动完成数据。自版本 10 以来,引入了一个新术语来代替注册表:Windows Vault。 Windows Vault 是凭据管理器信息的默认存储保险库。要使用“保险库”,您需要加载名为“vaultcli.dll”的 DLL,并根据需要访问其函数。
Vaultcli 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
。
下一步是枚举保险库。 这是通过调用来实现的
dwError = pVaultEnumerateVaults(NULL, &dwVaults, &ppVaultGuids);
pVaultEnumerateVaults
(实际上是“VaultEnumerateVaults
”)是一个 API 调用,用于枚举所有保险库,以便查看它们的内容。
接下来,我们打开每个保险库并枚举它包含的每个项目。 代码如下所示
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);
}
...
现在我们需要讨论我们自己的数据结构,用于存储浏览器(和其他程序)的凭据。
此时,“item”包含单个凭据条目,我们需要将其存储在我们自己的数据结构中,该结构是我们设计用于存储来自各种来源的凭据的结构。
SGBrowserCredentials 数据结构
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<SGBrowserCredentials> SGBrowserCredentialsArray;
在我们的例子中,我们希望我们的工具只显示设置了实际密码的凭据。 还有一些没有存储密码的网站的存储条目,但这些网站也存储在保险库中。
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);
}
使用此动态数组,我们可以在用户界面中显示它,也可以将其添加到文本报告中(事实上,我们两者都做)。 用于下载的源代码稍后添加。
工具
当您启动 Internet Explorer Credentials Viewer 时,片刻之后,您将看到类似于此屏幕的屏幕。 您所有存储的凭据都将显示出来。
更多链接
请访问我的 Github repos。 还有我另一篇关于 Chrome 的文章。
历史
- 2017 年 1 月 30 日:初始版本
- 7 月 18 日,修复了内存泄漏。