免杀系列之利用blockdlls和ACG保护恶意进程
blockdlls
Cobalt Strike 3.14版本以后添加了blockdlls功能,它将创建一个子进程并限定该子进程只能加载带有Microsoft签名的DLL。
这个功能可以阻止第三方安全软件向子进程注入DLL,也就无法对子进程进行hook,最终起到保护子进程的效果。
XPN在博客中分享了实现同样功能的c代码
#include <Windows.h>
int main()
{
STARTUPINFOEXA si;
PROCESS_INFORMATION pi;
SIZE_T size = 0;
BOOL ret;
// 请求一个 STARTUPINFOEXA 结构体
ZeroMemory(&si, sizeof(si));
si.StartupInfo.cb = sizeof(STARTUPINFOEXA);
si.StartupInfo.dwFlags = EXTENDED_STARTUPINFO_PRESENT;
//获取要分配的 PROC_THREAD_ATTRIBUTE_LIST 大小
InitializeProcThreadAttributeList(NULL, 1, 0, &size);
//为 PROC_THREAD_ATTRIBUTE_LIST 分配内存
si.lpAttributeList = (LPPROC_THREAD_ATTRIBUTE_LIST)HeapAlloc(
GetProcessHeap(),
0,
size
);
// 初始化我们的列表
InitializeProcThreadAttributeList(si.lpAttributeList, 1, 0, &size);
// 启用阻止未经Microsoft签名的DLL功能
DWORD64 policy = PROCESS_CREATION_MITIGATION_POLICY_BLOCK_NON_MICROSOFT_BINARIES_ALWAYS_ON;
// Assign our attribute
UpdateProcThreadAttribute(si.lpAttributeList, 0, PROC_THREAD_ATTRIBUTE_MITIGATION_POLICY, &policy, sizeof(policy), NULL, NULL);
// 创建进程
ret = CreateProcessA(
NULL,
(LPSTR)"C:\\Windows\\System32\\cmd.exe",
NULL,
NULL,
true,
EXTENDED_STARTUPINFO_PRESENT,
NULL,
NULL,
reinterpret_cast<LPSTARTUPINFOA>(&si),
&pi
);
}
通过STARTUPINFOEX结构体指定了要创建子进程的安全策略(开启PROCESS_CREATION_MITIGATION_POLICY_BLOCK_NON_MICROSOFT_BINARIES_ALWAYS_ON),这个安全策略起到了阻止加载非Microsoft签名dll的作用。
生成子进程后,使用ProcessHacker能够看到开启blockdlls功能的提示,如下图:

开启blockdlls功能后,尝试对这个进程进行dll注入,注入的代码可参考三好学生
注入时报错,提示如图:

接下来,需要了解此功能相关细节。在微软官方文档中,找到了相关API GetProcessMitigationPolicy(),可读取进程的安全策略。
而签名策略对应的结构体为PROCESS_MITIGATION_BINARY_SIGNATURE_POLICY,资料显示该API支持的最低系统为Win8,这里猜测API GetProcessMitigationPolicy()同blockdlls支持的操作系统版本应该相同。
经过测试,发现Cobalt Strike中blockdlls支持的系统最低为Win8。
分析blockdlls在CS中的实现
如果我们搜索CS beacon二进制文件,我们会看到对UpdateProctThreadAttribute的引用:

0x20007的属性参数实际上定义为PROC_THREAD_ATTRIBUTE_MITIGATION_POLICY,并且0x10000000000的值解析为PROCESS_CREATION_MITIGATION_POLICY_BLOCK_NON_MICROSOFT_BINARIES_ALWAYS_ON。所以Cobalt Strike在这里所做的是使用CreateProcess API调用以及包含一个缓解策略的结构体STARTUPINFOEX,而该策略正是用于阻止非微软签名DLL的加载。
任意代码保护
ACG是Windows系统的另一个安全策略,用于阻止外部代码分配和/或修改内存,这里不多赘述。
要了解此缓解策略的实际效果,我们创建一个小程序并尝试使用 SetMitigationPolicy 添加开启 ACG :
#include <iostream>
#include <Windows.h>
#include <processthreadsapi.h>
int main()
{
STARTUPINFOEX si;
DWORD oldProtection;
PROCESS_MITIGATION_DYNAMIC_CODE_POLICY policy;
ZeroMemory(&policy, sizeof(policy));
policy.ProhibitDynamicCode = 1;
void* mem = VirtualAlloc(0, 1024, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if (mem == NULL) {
printf("[!] Error allocating RWX memory\n");
}
else {
printf("[*] RWX memory allocated: %p\n", mem);
}
printf("[*] Now running SetProcessMitigationPolicy to apply PROCESS_MITIGATION_DYNAMIC_CODE_POLICY\n");
// Set our mitigation policy
if (SetProcessMitigationPolicy(ProcessDynamicCodePolicy, &policy, sizeof(policy)) == false) {
printf("[!] SetProcessMitigationPolicy failed\n");
return 0;
}
// Attempt to allocate RWX protected memory (this will fail)
mem = VirtualAlloc(0, 1024, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if (mem == NULL) {
printf("[!] Error allocating RWX memory\n");
}
else {
printf("[*] RWX memory allocated: %p\n", mem);
}
void* ntAllocateVirtualMemory = GetProcAddress(LoadLibraryA("ntdll.dll"), "NtAllocateVirtualMemory");
// Let's also try a VirtualProtect to see if we can update an existing page to RWX
if (!VirtualProtect(ntAllocateVirtualMemory, 4096, PAGE_EXECUTE_READWRITE, &oldProtection)) {
printf("[!] Error updating NtAllocateVirtualMemory [%p] memory to RWX\n", ntAllocateVirtualMemory);
}
else {
printf("[*] NtAllocateVirtualMemory [%p] memory updated to RWX\n", ntAllocateVirtualMemory);
}
}
编译并执行这段代码,我们将看到如下内容:

我们可以看到在 SetProcessMitigationPolicy 失败后尝试分配 RWX 的内存页,以及使用诸如 VirtualProtect 之类的调用来分配或修改内存保护,结果都是失败的。
那为什么要提这个呢? 因为我们确实看到了由微软签名的 EDR 注入DLL的例子,@Sektor7Net 展示了 Crowdstrike Falcon 可以不受 PROCESS_CREATION_MITIGATION_POLICY_BLOCK_NON_MICROSOFT_BINARIES_ALWAYS_ON 的影响

但许多EDR产品常见的操作是将他们的DLL注入到其想监测的进程中,围绕特定的API函数实现用户态hook技术(参考文章)。由于hook技术通常需要修改现有的可执行内存页以添加hook,因此EDR通常需要调用VirtualProtect来更新内存保护。如果我们在恶意软件设计上启用ProcessDynamicCodePolicy可能有助于保护其免受EDR hook监测的影响,就可能会强制阻止一个带微软签名的DLL加载。
总结
现在,我们要将这些策略进行整合,在生成恶意进程时,可以用PROCESS_CREATION_MITIGATION_POLICY_BLOCK_NON_MICROSOFT_BINARIES_ALWAYS_ON以及SetMitigationPolicyAPI调用进行保护。当然,还有其他方法可以对进程进行保护,例如通过简单的CreateProcessA生成任意进程。
这里,我仅根据以上展开的思路编写了新款免杀马(开源是不可能开源的,只提供思路大家自行创作),通杀国内外一流杀软,命名“冢虎”,在座的各位师傅有谁赞同,有谁反对?

参考:
https://blog.cobaltstrike.com/2019/05/02/cobalt-strike-3-14-post-ex-omakase-shimasu/
https://www.ired.team/offensive-security/defense-evasion/acg-arbitrary-code-guard-processdynamiccodepolicy#enabling-acg
https://blog.xpnsec.com/protecting-your-malware/
https://www.4hou.com/posts/0Xov
免杀系列之利用blockdlls和ACG保护恶意进程的更多相关文章
- [原创]K8_Delphi源码免杀系列教程
[原创]K8_Delphi源码免杀系列教程[2014] 虽是2014年的,但免杀思路方法并未过时 比如函数动态调用\代码注释法等至今依然有效 链接:https://pan.baidu.com/s/1H ...
- payload免杀之msbuild利用
0x00 前言 红队必备技巧免杀之一,现在主要是.net4.0下实现.待我过几天有空实现一下.net2.0. 0x01 免杀过程 利用cs生成c#的payload,如图所示: 将paypload内容填 ...
- Powershell免杀从入门到实践
转载https://www.jianshu.com/p/fb078a99e0d8 前言 文章首发于Freebuf 在之前发布的一篇 渗透技巧之Powershell实战思路 中,学习了powershel ...
- 2018-2019-2 网络对抗技术 20165232 Exp3 免杀原理与实践
2018-2019-2 网络对抗技术 20165232 Exp3 免杀原理与实践 免杀原理及基础问题回答 一.免杀原理 一般是对恶意软件做处理,让它不被杀毒软件所检测.也是渗透测试中需要使用到的技术. ...
- 2018-2019-2 网络对抗技术 20165319 Exp3 免杀原理与实践
免杀原理及基础问题回答 免杀原理: 免杀指的是一种能使病毒木马免于被杀毒软件查杀的技术.由于免杀技术的涉猎面非常广,其中包含反汇编.逆向工程.系统漏洞等黑客技术,所以难度很高,一般人不会或没能力接触这 ...
- 2018-2019-2 网络对抗技术 20165311 Exp3 免杀原理与实践
2018-2019-2 网络对抗技术 20165311 Exp3 免杀原理与实践 免杀原理及基础问题回答 实验内容 任务一:正确使用msf编码器,msfvenom生成如jar之类的其他文件,veil- ...
- NetSec2019 20165327 Exp3 免杀原理与实践
NetSec2019 20165327 Exp3 免杀原理与实践 pre基础问题回答 一.免杀原理 一般是对恶意软件做处理,让它不被杀毒软件所检测.也是渗透测试中需要使用到的技术. 要做好免杀,就时清 ...
- 2018-2019-2 网络对抗技术 20165304 Exp3 免杀原理与实践
2018-2019-2 网络对抗技术 20165304 Exp3 免杀原理与实践 免杀原理及基础问题回答 一.免杀原理 一般是对恶意软件做处理,让它不被杀毒软件所检测.也是渗透测试中需要使用到的技术. ...
- 2018-2019-2 20165315 《网络对抗技术》Exp3 免杀原理与实践
2018-2019-2 20165315 <网络对抗技术>Exp3 免杀原理与实践 一.实验内容 正确使用msf编码器,msfvenom生成如jar之类的其他文件,veil-evasion ...
- 2018-2019-2 网络对抗技术 20165318 Exp3 免杀原理与实践
2018-2019-2 网络对抗技术 20165318 Exp3 免杀原理与实践 免杀原理及基础问题回答 实验内容 任务一:正确使用msf编码器,msfvenom生成如jar之类的其他文件,veil- ...
随机推荐
- 一键部署十个服务脚本--可拆分---java+mysql+redis+nginx+rocketmq..等等
java + mysql +redis + minio + nginx + rocketmq + rocketmq-console + elasticsearch + kibana + logstas ...
- node使用node-xlsx实现excel的下载与导入,保证你看的明明白白
需求简介 很多时候,我们都会有这样一个业务. 将列表中的数据导出为excel. 这样做的目的是为了方便查看,同时可以保存在本地归档. 还可以将导出的Excel后的数据进行加工. node-xlsx 的 ...
- 写一个 Hello SpringBoot2 项目
需求:向浏览发送/hello请求,并响应 Hello,Spring Boot 2 解决: 项目目录:controller层.Main启动项.pom.xml controller层:写好逻辑跳转,当浏览 ...
- day48:django前戏:HTTP协议&自定义web框架
目录 1.HTTP协议 1.HTTP协议简介 2.HTTP协议概述 3.HTTP协议工作原理 4.HTTP协议请求方法 5.HTTP协议状态码 6.URL 7.HTTP请求格式 8.HTTP响应格式 ...
- day14:列表/集合/字典推导式&生成器表达式&生成器函数
推导式 推导式的定义: 通过一行循环判断,遍历一系列数据的方式 推导式的语法: val for val in Iterable 三种方式: [val for val in Iterable] {val ...
- python:selenium爬取boss网站被关小黑屋
问题描述:使用selenium访问次数过多,被boss反爬封掉IP,这种方式有什么好一点的解决方法,首次可以用图形验证解封,今天访问次数过多,被关进了小黑屋 首次让我用图形界面解封 不过还好,手动解封 ...
- zookeeper重启,线上微服务全部掉线,怎么回事?
注册中心zookeeper被重启,线上微服务全部掉线,怎么回事?! 最近因为一次错误的运维操作,导致线上注册中心zk被重启.而zk重启后发现所有线上微服务开始不断掉线,造成了持续30分钟的P0故障. ...
- c/c++快乐算法第三天
c/c++感受算法快乐(3) 开始时间2023-04-16 22:21:10 结束时间2023-04-17 00:09:34 前言:很好,这周就要结束了,大家都回学校了么,嘻嘻.回顾一下昨天的算法题, ...
- 重新实现hashCode()方法
在Java中,为了让对象在集合中能够更高效地进行查找和比较,我们通常需要重写对象的equals()和hashCode()方法.其中,equals()方法用于比较两个对象是否相等,而hashCode() ...
- Linux云计算运维工程师day29软件安装
1. diff(文本比较) [root@guosaike ~]# cp /etc/passwd{,.ori}备份 [root@guosaike ~]# diff /etc/passwd{,.ori} ...