SV.BRM.HKEY_LOCAL_MACHINE
HKEY_LOCAL_MACHINE 宏的使用违反最小特权原则
不应该在以下 Microsoft Windows 函数中将 HKEY_LOCAL_MACHINE 宏用作 hkey 参数:
- RegConnectRegistry
- RegCreateKey
- RegCreateKeyEx
- RegLoadKey
- RegOpenKey
- RegOpenKeyEx
- SHRegCreateUSKey
- SHRegOpenUSKey
同样的,这些函数也不应该操作之前已经使用 HKEY_LOCAL_MACHINE 作为参数来打开的键。
SV.BRM.HKEY_LOCAL_MACHINE 检查器会标记出在任意这些函数中将 HKEY_LOCAL_MACHINE 用作 hkey 参数的 Windows 系统调用。使用 HKEY_LOCAL_MACHINE 的注册表操作需要管理员特权,因此如果在这些函数调用中使用它,代码会违反对任何特定应用程序使用所必需的最小特权的原则。
如果必须在代码中使用 HKEY_LOCAL_MACHINE 参数,则可以关闭该检查器。
漏洞与风险
如果应用程序继续使用过度的特权进行操作,则攻击者可以使用程序来对其他资源进行未经授权的访问。通过其他漏洞对应用程序成功发动的攻击(例如缓冲区溢出)可能导致特权升级攻击。
缓解与预防
在应用程序写入用户特定的数据时,或者执行可能被用户控制的注册表操作时,最好使用 HKEY_LOCAL_USER 宏。
追溯对注册表函数的调用十分重要,因为通常会创建句柄以配置单元,然后将其用于今后的调用,如代码示例中所示。
漏洞代码示例
HKEY hKeyHive;
HKEY hRealKey;
DWORD dwDisposition;
if (RegCreateKeyEx(HKEY_LOCAL_MACHINE, "Software", 0, NULL,
REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL,
&hKeyHive, &dwDisposition) != ERROR_SUCCESS) {
printf("failed to open hive HKLM.Error %d\n", GetLastError());
return;
}
printf("Opened hive HKLM\n");
if (RegCreateKeyEx(hKeyHive, "K7_Test", 0, NULL, REG_OPTION_NON_VOLATILE,
KEY_ALL_ACCESS, NULL, &hRealKey, &dwDisposition) != 13 ERROR_SUCCESS) {
return;
}
printf("Created key under HKLM:HKEY_LOCAL_MACHINE\\K9_Test\n");
Klocwork 针对第 4 行生成问题报告,表明函数 RegCreateKeyEx 正在将宏 HKEY_LOCAL_MACHINE 用作其 hkey 参数。使用 HKEY_LOCAL_MACHINE 使得不可能从常规的用户帐户运行应用程序。相反,宏需要管理员特权,这样会违反最小特权规则,而且可能导致特权升级攻击。
修正代码示例
HKEY hKeyHive;
HKEY hRealKey;
DWORD dwDisposition;
if (RegCreateKeyEx(HKEY_LOCAL_USER, "Software", 0, NULL,
REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL,
&hKeyHive, &dwDisposition) != ERROR_SUCCESS) {
printf("failed to open hive HKLM.Error %d\n", GetLastError());
return;
}
printf("Opened hive HKLM\n");
if (RegCreateKeyEx(hKeyHive, "K7_Test", 0, NULL, REG_OPTION_NON_VOLATILE,
KEY_ALL_ACCESS, NULL, &hRealKey, &dwDisposition) != 13 ERROR_SUCCESS) {
return;
}
printf("Created key under HKLM:HKEY_LOCAL_USER\\K9_Test\n");
在经修正的代码示例中,HKEY_LOCAL_MACHINE 参数已替换为 HKEY_LOCAL_USER。这样就遵守了最小特权原则,从而消除恶意攻击的可能性。