对抗内存扫描

目前两种对抗内存扫描比较有效的方法:

本文使用其中的第一种。

payload 为 Cobalt Strike 4.4 stageless beacon x64。

核心思路

静态

AES + BASE64:

https://github.com/kokke/tiny-AES-c

https://learn.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptstringtobinarya

动态

在 sleep 时,将所有相关可执行内存去除可执行权限,sleep 结束后,继续执行触发 VEH 异常处理,在 VEH 处理函数中恢复内存可执行权限。

开发环境

vcpkg 安装 minhook:

获取 minhook.x64.libMinHook.h

技术细节

动态 API 调用

动态调用的 API 函数名不会出现在导入表中:

AES 解密

Hook 时用于替换原有 API 的函数

VirtualAlloc:获取 beacon 加载时的内存地址和大小。

Sleep:如果 sleep 小于 1s,不修改内存属性,否则将内存属性修改为 RW。

VEH 处理函数

验证触发异常的地址是否为 beacon 地址,如果是,将内存属性修改为 RWX。

Shellcode 加载执行

首先注册 VEH 处理函数,然后 hook VirtualAlloc 和 Sleep,最后通过 CertEnumSystemStoreLocation 函数触发 shellcode 执行,此 API 中包含一处函数指针指向第三个参数的地址。

主函数

防止多次上线:

BASE64 解码:

AES 解密,shellcode 加载执行:

bin to hpp

将 shellcode 二进制文件转换为 C++ 头文件: