Process Mitigation Policy
发布于 2021-10-23
在Windows平台开发应用软件时,自己的程序被三方程序注入 dll 或者注入 shellcode,干扰了自己程序的正常运行,是件非常头痛的事。更令人难过的是,国内的木马病毒、流氓软件太多了,整个环境都很糟糕。阻止外部任意代码的执行,变成了很重要的安全问题。
Chromium 浏览器通过 chromium_elf.dll 模块来阻止三方 dll 注入到浏览器,具体可以参考我之前写的一篇文章Chrome Early Loading Framework。
此外 Chromium将拒绝第三方软件注入 ,
微软的Edge浏览器开发团队曾经写过一篇文章 Mitigating arbitrary native code execution in Microsoft Edge ,来介绍Edge应用的一些win10最新的安全防护技术。(此时的Edge还是非Chromium内核)。
Process Mitigation Policy
win8 之后,windows有个Process Mitigation Policy,用来防护进程被攻击。它一般有三种设置方法:
- 被保护进程自己调用
SetProcessMitigationPolicy
api 来设置 Process Mitigation Policy - 用管理员权限来运行配置工具
Set-ProcessMitigation
,它会为某个进程名的进程设置 Process Mitigation Policy。其结果其实存在于注册中的HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options
里面 - 创建被保护子进程时设置 Process Mitigation Policy
以设置 Code Integrity Guard (CIG) 为例,三种设置方式如下。
通过Set-ProcessMitigation
设置:
Set-ProcessMitigation -name WindowsProject3.exe -enable BlockNonMicrosoftSigned
通过SetProcessMitigationPolicy
api设置:
PROCESS_MITIGATION_BINARY_SIGNATURE_POLICY bsp = {};
bsp.MicrosoftSignedOnly = 1;
SetProcessMitigationPolicy(ProcessSignaturePolicy, &bsp, sizeof(bsp));
创建被保护子进程时设置:
STARTUPINFOEXA si;
PROCESS_INFORMATION pi;
SIZE_T size = 0;
ZeroMemory(&si, sizeof(si));
si.StartupInfo.cb = sizeof(STARTUPINFOEXA);
si.StartupInfo.dwFlags = EXTENDED_STARTUPINFO_PRESENT;
InitializeProcThreadAttributeList(NULL, 1, 0, &size);
si.lpAttributeList =
(LPPROC_THREAD_ATTRIBUTE_LIST)HeapAlloc(GetProcessHeap(), 0, size);
InitializeProcThreadAttributeList(si.lpAttributeList, 1, 0, &size);
DWORD64 policy =
PROCESS_CREATION_MITIGATION_POLICY_BLOCK_NON_MICROSOFT_BINARIES_ALWAYS_ON;
UpdateProcThreadAttribute(si.lpAttributeList, 0,
PROC_THREAD_ATTRIBUTE_MITIGATION_POLICY, &policy,
sizeof(policy), NULL, NULL);
BOOL ret =
CreateProcessA(NULL, (LPSTR) "C:\\Windows\\System32\\notepad.exe", NULL,
NULL, true, EXTENDED_STARTUPINFO_PRESENT, NULL, NULL,
reinterpret_cast<LPSTARTUPINFOA>(&si), &pi);
进程设置 Process Mitigation Policy 成功之后,可以通过api GetProcessMitigationPolicy
来查询,也可以通过 Process Hacker 这个工具查看进程的 Properties -> General -> Mitigation policies -> Details,如下图所示:
Code Integrity Guard (CIG)
CIG 策略是根据证书来限制进程可以加载的可执行文件。
PROCESS_MITIGATION_BINARY_SIGNATURE_POLICY
里面选项:
- MicrosoftSignedOnly,值为1表示阻止加载没有微软签名的模块
- StoreSignedOnly,值为1表示阻止加载没有微软应用商店签名的模块
- MitigationOptIn,值为1表示阻止加载没有微软、微软应用商店、Windows Hardware Quality签名的模块
如果设置了MicrosoftSignedOnly
,那么非微软签名的 dll 无法注入到进程里了。可以起到一定的防护作用。
Arbitrary Code Guard (ACG)
ACG 策略是防止进程生成动态代码或者修改已经存在的可执行文件。存在的代码页不可写,没有签名的代码页不能被创建。
也就是说不能通过调用ProtectVirtualMemory
、VirtualAlloc
来操作例如PAGE_EXECUTE_READWRITE
这样的内存。内存不能同时拥有写入权限(W)和执行权限(X)。
同样的 ACG 也可以用于阻止三方模块的 dll 注入到进程中。
因为 ACG 限制了动态生成代码指令,因此它与浏览器渲染进程中的 JavaScript 引擎的 JIT 编译优化是相冲突的。因此 Edge 浏览器把 Chakra 的 JIT 放到一个独立进程里,再把 JIT 编译生成的代码映射到渲染进程里。
其他
Process Mitigation Policy 里面的策略非常多,比如CFG、ASLR等等,具体可以参考 SetProcessMitigationPolicy 。
Chromium 浏览器的Sandbox 有些对进程的限制也是用到了 Process Mitigation Policy。
不足
Process Mitigation Policy 的设置方式对于恶意程序来说,也可以绕过的。
通过SetProcessMitigationPolicy
设置,如果在调用之前,防护是不生效的。
通过Set-ProcessMitigation
工具设置,配置写在注册表里。恶意程序找到位置也可以删除掉。
通过创建被保护子进程时设置,假如恶意程序自己启动被保护进程,也是没有办法防护。
另外看起来 ACG 防护策略似乎可以阻止远程代码代码注入 shellcode,但实际不行。可能是因为远程代码代码注入 shellcode 里面对 VirtualAlloc
的调用都在 shellcode 进程里,不在被防护的进程里。
参考
- ProcessDynamicCodePolicy: Arbitrary Code Guard (ACG)
- Protecting Your Malware with blockdlls and ACG
- Mitigating arbitrary native code execution in Microsoft Edge
- Arbitrary Code Guard
- 任意代码保护与内核代码注入的那些事儿
- SetProcessMitigationPolicy
- Windows internals - PPL进程
- Protecting Anti-Malware Services
- Mitigate threats by using Windows 10 security features
- Set-ProcessMitigation
- UpdateProcThreadAttribute