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。这样就遵守了最小特权原则,从而消除恶意攻击的可能性。

相关检查器

安全培训

应用程序安全培训材料由 Secure Code Warrior 提供。