免杀系列之利用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- ...
随机推荐
- go微服务框架kratos学习笔记二(kratos demo 结构)
目录 api cmd configs dao di model server service 上篇文章go微服务框架kratos学习笔记一(kratos demo)跑了kratos demo 本章来看 ...
- SQL语句的其他关键字
目录 数据准备 编写SQL语句小技巧 查询关键字之where筛选 查询关键字之group by 分组 查询关键字之having过滤 查询关键字之distinct去重 查询关键字之order by排序 ...
- 安全测试前置实践1-白盒&黑盒扫描
作者:京东物流 陈维 一.引言 G.J.Myers在<软件测试的艺术>中提出:从心理学角度来说,测试是一个为了寻找错误而运行程序的过程. 那么安全测试则是一个寻找系统潜在安全问题的过程,通 ...
- YII2.0的文件上传, 并把文件名称重新编译
/** *@Action 文件上传示例 *@这里我们演示的是一个YII2.0的文件上传, 并把文件名称重新编译 *@我们上传的是一个叫 photo 的jpg和png格式的文件 */ Controlle ...
- Ununtu服务器安装Nginx与PHP
Ununtu服务器安装Nginx与PHP 1. 安装Nginx: 1.1 sudo apt update sudo apt install nginx 验证结果,使用命令: sudo systemct ...
- 全网最硬核 JVM 内存解析 - 1.从 Native Memory Tracking 说起
个人创作公约:本人声明创作的所有文章皆为自己原创,如果有参考任何文章的地方,会标注出来,如果有疏漏,欢迎大家批判.如果大家发现网上有抄袭本文章的,欢迎举报,并且积极向这个 github 仓库 提交 i ...
- ES6 新增的一些特性
还有symbol和set,map, bind,call,apply 1. let关键字 (1)基本用法:let关键字用来声明变量,它的用法类似于var,都是用来声明变量. (2)块级作用域:let声明 ...
- Tarjan学习笔寄
tarjan算法 参考博客: https://www.cnblogs.com/nullzx/p/7968110.html https://www.cnblogs.com/ljy-endl/p/1156 ...
- LeetCode 654:最大二叉树
先立个flag吧,坚持每日刷题的小目标,希望自己能坚持下来,如果有需要一起打卡的uu,可以一起监督哈,在菜鸡的路上慢慢变好 题目:最大二叉树 给定一个不重复的整数数组 nums . 最大二叉树 可以用 ...
- Linux 内存管理 pt.2
哈喽大家好我是咸鱼,在<Linux 内存管理 pt.1>中我们学习了什么是物理内存.虚拟内存,了解了内存映射.缺页异常等内容 那么今天我们来接着学习 Linux 内存管理中的多级页表和大页 ...