返回

Windows 使用 ProcFilter 限制进程创建,解决白名单失效问题

windows

使用 ProcFilter 在 Windows 上限制进程创建

限制进程创建是一种重要的安全措施,可以有效地控制系统中允许运行的程序,提升系统安全性。本文将探讨如何利用 ProcFilter 工具实现对 Windows 进程创建的控制,特别是解决白名单配置不生效的问题。

问题分析

ProcFilter 作为一个内核级的进程过滤工具,能够拦截和控制系统中的进程创建行为。通常的期望是配置白名单,允许在指定目录下的程序运行,阻止其他位置的程序创建进程。但在实际使用中,可能遇到白名单不生效,导致所有程序都被拦截的问题。这通常是配置上的错误或对 ProcFilter 工作原理理解不深入导致的。例如,YARA 规则配置不当、插件配置错误都可能导致预期之外的结果。

白名单配置的困境

文中提到,虽然使用了 filenameregex 定义白名单路径,例如 "C:\\Windows\\.*""C:\\Program Files\\.*",并使用了 all_App YARA 规则匹配所有的 PE 文件,结果却造成了白名单失效,所有程序均无法启动。其原因在于规则的作用域理解不充分:YARA 规则 all_App 的目标过于宽泛,它匹配到了所有可执行文件,即使那些在白名单中的程序,也会被 Block=true 的配置拦截,使得白名单失去了作用。ProcFilter 的机制是在 dwEventId == PROCFILTER_EVENT_PROCESS_CREATE 事件发生时,首先检查 YARA 规则,其次检查其他配置。

解决方案

针对上述问题,可以从以下几个方面入手解决:

1. 精确的 YARA 规则

避免使用通用的 all_App YARA 规则,因为它匹配了所有的可执行文件,导致白名单无法发挥作用。更精确的 YARA 规则只应该用于需要阻止的可执行文件,而不是全部文件。应该配合白名单使用,或者针对可疑行为设置规则。对于白名单功能而言,通常可以不设置 YARA 规则,完全依赖白名单插件进行控制,或者设置反向 YARA 规则,匹配非白名单路径的执行文件,以实现安全控制。

2. 基于插件的白名单控制

ProcFilter 允许用户编写自定义插件实现更加灵活的控制逻辑。可以通过读取配置文件来判断进程是否允许创建。插件中g_bBlockFilesNotWhitelisted 配置项是一个实现白名单的好方法,如果发现e->lpszFileName不在白名单,就可以直接返回PROCFILTER_RESULT_BLOCK_PROCESS。为了解决上文中插件的逻辑错误,应该仔细处理白名单和黑名单(如果不配置 YARA规则,等同于不存在黑名单)。确保在匹配到白名单项后跳过检查或者执行后续的策略。

以下代码片段是该配置的一种修正示例:

else if (e->dwEventId == PROCFILTER_EVENT_PROCESS_CREATE && e->lpszFileName)
{

   if (g_Whitelist.matchesFilename(e->lpszFileName)) {
       // 如果在白名单,允许执行
        EnterCriticalSection(&g_cs);
        g_WhitelistedPids.insert(e->dwProcessId);
        LeaveCriticalSection(&g_cs);
        return dwResultFlags |= PROCFILTER_RESULT_DONT_SCAN; // 明确跳过其他处理
    }

   if (g_bBlockFilesNotWhitelisted)
   {// 当 BlockFilesNotWhitelisted 启用时,只允许白名单中的文件执行
     
         return PROCFILTER_RESULT_BLOCK_PROCESS; //  不在白名单,阻止执行

   }


}

操作步骤:

  1. 编译并安装 ProcFilter:GitHub 项目 获取源码,按照说明编译并安装 ProcFilter 内核驱动。

  2. 创建配置文件 procfilter.ini 包含必要的配置,包括 BlockFilesNotWhitelisted=1 和白名单路径,例如:

    BlockFilesNotWhitelisted=1
    filenameregex=C:\\Windows\\.*
    filenameregex=C:\\Program Files\\.*
    filenameregex=C:\\Users\\.*
    
3. **修改并编译自定义插件:**  修改代码,确保逻辑正确。编译插件并替换 ProcFilter 默认插件。
4.  **启动 ProcFilter:**  确保 ProcFilter 服务已启动并加载自定义插件。可以通过服务管理器或命令行进行操作。例如:

    ```powershell
    sc.exe start Procfilter
    ```
  1. 测试: 尝试在非白名单路径下执行程序,观察是否被拦截,在白名单路径下执行程序,观察是否可以正常运行。
  2. 更新插件: 根据实际情况更新白名单路径以及插件。

3. YARA规则和插件的协作

如果必须使用 YARA 规则进行某些检测,应避免其与白名单功能冲突。 例如可以使用 not filename 字符串来定义黑名单,如下:

rule non_App{
  meta:
      description = "non-App files"
      
      Block = true
      Log = true
      Quarantine = false
      
  strings:
       $mz = "MZ"
     condition:
        $mz at 0 and not filename contains "C:\\Windows" and not filename contains "C:\\Program Files" and not filename contains "C:\\Users"
}

这个 YARA 规则,它仅仅会检测 filename 路径不在 白名单中 的程序,并拦截。

安全建议

  • 严格测试配置:在生产环境应用任何规则前,务必在测试环境中进行充分的测试。
  • 精细化白名单:白名单应尽量精确,避免使用通配符 * ,这样可以缩小被攻击面,提高安全防护。例如将 C:\\Windows\\*.exe 改成C:\\Windows\\notepad.exe.
  • 日志分析:开启日志功能,便于分析被拦截的进程,可以帮助我们不断优化规则和配置。
  • 谨慎对待系统目录: 对 C:\\Windows 等系统目录添加精确的白名单,可以降低错误配置可能造成的风险。
  • 多层防护:ProcFilter 可以作为多层防御体系的一部分, 与其他安全措施结合使用可以进一步提高安全性。