CS免杀-AllocADsMem内存申请
字数 1330 2025-08-09 18:44:03

CS免杀技术:利用AllocADsMem和ReallocADsMem实现内存申请

1. 概述

本文详细介绍了如何利用Windows API中的AllocADsMemReallocADsMem函数实现内存申请操作,用于Cobalt Strike等C2框架的免杀技术。这两个函数位于activeds.dll中,是较少被安全产品监控的内存分配函数。

2. 核心函数分析

2.1 AllocADsMem

函数原型:

LPVOID AllocADsMem(DWORD cb);
  • 参数:cb - 要分配的内存大小(字节)
  • 返回值:成功返回分配的内存指针,失败返回NULL

2.2 ReallocADsMem

函数原型:

LPVOID ReallocADsMem(LPVOID pOldMem, DWORD cbOld, DWORD cbNew);
  • 参数:
    • pOldMem - 之前分配的内存指针
    • cbOld - 旧内存块大小
    • cbNew - 新内存块大小
  • 返回值:成功返回重新分配的内存指针,失败返回NULL

2.3 FreeADsMem

函数原型:

BOOL FreeADsMem(LPVOID pMem);
  • 参数:pMem - 要释放的内存指针
  • 返回值:成功返回TRUE,失败返回FALSE

3. 实现原理

这些函数是Active Directory Service Interfaces (ADSI)的一部分,主要用于目录服务操作。由于它们不是常规的内存分配函数(如malloc或VirtualAlloc),因此可以绕过一些基于行为检测的安全产品。

4. 实际应用代码示例

4.1 基本使用

#include <Windows.h>
#include <activeds.h>

int main() {
    // 加载activeds.dll
    HMODULE hActiveDS = LoadLibraryA("activeds.dll");
    
    // 获取函数地址
    typedef LPVOID(WINAPI* pAllocADsMem)(DWORD);
    pAllocADsMem AllocADsMem = (pAllocADsMem)GetProcAddress(hActiveDS, "AllocADsMem");
    
    // 分配内存
    LPVOID pMem = AllocADsMem(1024);
    if (pMem) {
        // 使用内存...
        
        // 释放内存
        typedef BOOL(WINAPI* pFreeADsMem)(LPVOID);
        pFreeADsMem FreeADsMem = (pFreeADsMem)GetProcAddress(hActiveDS, "FreeADsMem");
        FreeADsMem(pMem);
    }
    
    FreeLibrary(hActiveDS);
    return 0;
}

4.2 在Cobalt Strike中的应用

#include <Windows.h>
#include <activeds.h>

typedef LPVOID(WINAPI* pAllocADsMem)(DWORD);
typedef LPVOID(WINAPI* pReallocADsMem)(LPVOID, DWORD, DWORD);
typedef BOOL(WINAPI* pFreeADsMem)(LPVOID);

void* AllocateMemory(size_t size) {
    HMODULE hActiveDS = LoadLibraryA("activeds.dll");
    pAllocADsMem AllocADsMem = (pAllocADsMem)GetProcAddress(hActiveDS, "AllocADsMem");
    
    void* memory = AllocADsMem((DWORD)size);
    FreeLibrary(hActiveDS);
    return memory;
}

void* ReallocateMemory(void* oldMem, size_t oldSize, size_t newSize) {
    HMODULE hActiveDS = LoadLibraryA("activeds.dll");
    pReallocADsMem ReallocADsMem = (pReallocADsMem)GetProcAddress(hActiveDS, "ReallocADsMem");
    
    void* newMem = ReallocADsMem(oldMem, (DWORD)oldSize, (DWORD)newSize);
    FreeLibrary(hActiveDS);
    return newMem;
}

void FreeMemory(void* memory) {
    HMODULE hActiveDS = LoadLibraryA("activeds.dll");
    pFreeADsMem FreeADsMem = (pFreeADsMem)GetProcAddress(hActiveDS, "FreeADsMem");
    
    FreeADsMem(memory);
    FreeLibrary(hActiveDS);
}

5. 免杀优势分析

  1. 非标准内存分配函数:不像VirtualAlloc等常见API那样容易被监控
  2. 合法用途掩盖:这些函数原本用于Active Directory操作,看起来更合法
  3. 低检测率:大多数EDR/AV不会特别监控这些函数的内存分配行为
  4. 灵活性:可以与其他技术结合使用,如API间接调用

6. 注意事项

  1. 内存属性:这些函数分配的内存默认是可读写的,不具备执行权限,需要配合VirtualProtect等函数修改权限
  2. DLL加载:需要动态加载activeds.dll,避免静态链接引起怀疑
  3. 错误处理:需要妥善处理内存分配失败的情况
  4. 兼容性:确保目标系统上有activeds.dll(大多数Windows系统都有)

7. 进阶技巧

  1. 结合其他API:可以与EnumChildWindows等GUI API结合,创建更隐蔽的内存操作链
  2. 延迟加载:只在需要时加载activeds.dll,使用后立即释放
  3. API混淆:通过哈希或加密函数名动态解析API地址
  4. 内存加密:在非使用时段加密分配的内存区域

8. 检测与防御

虽然这种方法有一定免杀效果,但防御方可以通过以下方式检测:

  1. 监控所有内存分配行为:不限于常见API
  2. 分析调用链:检查这些函数是否被用于非常规目的
  3. 行为分析:结合内存分配后的使用模式(如立即修改权限)进行检测
  4. DLL加载监控:特别关注activeds.dll的非常规使用

9. 总结

AllocADsMemReallocADsMem提供了一种相对隐蔽的内存分配方式,可以用于绕过一些基于API监控的安全检测。然而,没有任何技术是完美的免杀方案,建议在实际应用中结合多种技术,并根据目标环境进行调整。

CS免杀技术:利用AllocADsMem和ReallocADsMem实现内存申请 1. 概述 本文详细介绍了如何利用Windows API中的 AllocADsMem 和 ReallocADsMem 函数实现内存申请操作,用于Cobalt Strike等C2框架的免杀技术。这两个函数位于 activeds.dll 中,是较少被安全产品监控的内存分配函数。 2. 核心函数分析 2.1 AllocADsMem 函数原型: 参数: cb - 要分配的内存大小(字节) 返回值:成功返回分配的内存指针,失败返回NULL 2.2 ReallocADsMem 函数原型: 参数: pOldMem - 之前分配的内存指针 cbOld - 旧内存块大小 cbNew - 新内存块大小 返回值:成功返回重新分配的内存指针,失败返回NULL 2.3 FreeADsMem 函数原型: 参数: pMem - 要释放的内存指针 返回值:成功返回TRUE,失败返回FALSE 3. 实现原理 这些函数是Active Directory Service Interfaces (ADSI)的一部分,主要用于目录服务操作。由于它们不是常规的内存分配函数(如malloc或VirtualAlloc),因此可以绕过一些基于行为检测的安全产品。 4. 实际应用代码示例 4.1 基本使用 4.2 在Cobalt Strike中的应用 5. 免杀优势分析 非标准内存分配函数 :不像VirtualAlloc等常见API那样容易被监控 合法用途掩盖 :这些函数原本用于Active Directory操作,看起来更合法 低检测率 :大多数EDR/AV不会特别监控这些函数的内存分配行为 灵活性 :可以与其他技术结合使用,如API间接调用 6. 注意事项 内存属性 :这些函数分配的内存默认是可读写的,不具备执行权限,需要配合VirtualProtect等函数修改权限 DLL加载 :需要动态加载activeds.dll,避免静态链接引起怀疑 错误处理 :需要妥善处理内存分配失败的情况 兼容性 :确保目标系统上有activeds.dll(大多数Windows系统都有) 7. 进阶技巧 结合其他API :可以与EnumChildWindows等GUI API结合,创建更隐蔽的内存操作链 延迟加载 :只在需要时加载activeds.dll,使用后立即释放 API混淆 :通过哈希或加密函数名动态解析API地址 内存加密 :在非使用时段加密分配的内存区域 8. 检测与防御 虽然这种方法有一定免杀效果,但防御方可以通过以下方式检测: 监控所有内存分配行为 :不限于常见API 分析调用链 :检查这些函数是否被用于非常规目的 行为分析 :结合内存分配后的使用模式(如立即修改权限)进行检测 DLL加载监控 :特别关注activeds.dll的非常规使用 9. 总结 AllocADsMem 和 ReallocADsMem 提供了一种相对隐蔽的内存分配方式,可以用于绕过一些基于API监控的安全检测。然而,没有任何技术是完美的免杀方案,建议在实际应用中结合多种技术,并根据目标环境进行调整。