利用NtReadVirtualMemory实现IAT中规避高危API
字数 1669 2025-09-01 11:25:54

利用NtReadVirtualMemory实现IAT中规避高危API的技术分析

1. 技术背景

在恶意软件开发中,直接导入高危API(如LoadLibraryGetProcAddress等)会导致IAT(Import Address Table)中存在明显特征,容易被安全产品检测。本文介绍一种通过NtReadVirtualMemory读取内存来动态获取函数地址的技术,可以有效规避IAT中的高危API。

2. 技术演进过程

2.1 传统Win32 API方式

最简单的Shellcode Loader直接使用Win32 API:

  • LoadLibrary加载DLL
  • GetProcAddress获取函数地址
  • 直接调用目标函数

问题:IAT中会显示这些高危API,容易被检测。

2.2 动态API调用方式

通过LoadLibraryGetProcAddress实现动态API调用:

  • 仅保留这两个基础API
  • 其他函数通过它们动态获取

改进:IAT中仅剩LoadLibraryGetProcAddress,但仍可被检测。

2.3 现代动态获取函数地址技术

当前主流技术:

  1. 查询PEB和EAT(Export Address Table)
  2. 遍历内存并通过特征匹配定位函数

3. 核心创新技术:通过NtReadVirtualMemory获取函数地址

3.1 技术原理

使用NtReadVirtualMemory(NT Native API)读取进程内存,解析PE和PEB结构来获取DLL基址和函数地址,完全规避IAT中的高危API。

3.2 关键工具:resolve.c

resolve.c是一个核心工具,输入参数:

  • NtReadVirtualMemory的地址
  • DLL名称
  • 函数名称

输出:目标函数的地址

工作原理

  1. 通过Native API解析PE及PEB结构
  2. 获取DLL基址
  3. 解析导出表获取函数地址

4. 获取NtReadVirtualMemory地址的四种方法

4.1 方法1:直接输出

基本实现

// 获取NtReadVirtualMemory地址并直接输出

VT检测结果:11/72检测率

优化方案

  • 使用AI生成200行以上的合法程序(如任务管理器)
  • 在特定条件下(如输入'z')才输出地址
  • VT检测率降至5/72

注意事项

  • Microsoft Defender本地不会查杀
  • 需要尝试多种程序类型(进程管理、文件操作、数学运算等)

4.2 方法2:格式化字符串漏洞

实现代码

char input[100];
sprintf(input, "%p %p %p %p"); // 格式化字符串漏洞

编译命令

cl /GS- /Od leak-2.c

原理

  • 利用未指定变量的格式化字符串漏洞
  • 随机打印栈上的值,包括NtReadVirtualMemory地址

4.3 方法3:栈越界读

实现代码

char buffer[8];
for(int i=16; i<=23; i++) {
    printf("%p ", buffer[i]); // 栈越界读取
}

编译命令

cl /GS- /Od leak-3.c

原理

  • 利用小缓冲区越界读取栈上数据
  • 特定偏移(16-23)处保存着NtReadVirtualMemory地址

4.4 方法4:堆越界读

实现代码

char *heap_buf = (char*)malloc(8);
for(int i=16; i<=23; i++) {
    printf("%p ", heap_buf[i]); // 堆越界读取
}

编译命令

cl /GS- /Od leak-4.c

原理

  • 类似栈越界读,但在堆上实现
  • 特定偏移处保存目标地址

5. 完整技术实现流程

  1. 通过上述任意方法获取NtReadVirtualMemory地址
  2. 使用resolve.c工具解析目标函数地址:
    resolve.exe <NtReadVirtualMemory地址> <DLL名称> <函数名称>
    
  3. 使用获取的函数地址直接调用目标API

6. 防御规避效果

  • IAT中不显示任何高危API
  • 结合AI生成的合法程序外壳,VT检测率可降至5/72
  • Microsoft Defender本地不查杀
  • 使用内存读取而非API调用,行为更隐蔽

7. 技术要点总结

  1. 核心创新:利用NtReadVirtualMemory读取内存解析PE结构,完全规避IAT
  2. 地址获取:四种内存泄露方法各有优劣,可根据场景选择
  3. 隐蔽性:结合合法程序外壳和特定触发条件增强隐蔽性
  4. 兼容性:在最新Windows Defender下仍有效

8. 防御建议(针对蓝队)

  1. 监控NtReadVirtualMemory的异常调用模式
  2. 检测内存泄露漏洞的利用行为
  3. 分析PEB/EAT解析行为
  4. 关注格式化字符串和缓冲区越界读的异常模式
利用NtReadVirtualMemory实现IAT中规避高危API的技术分析 1. 技术背景 在恶意软件开发中,直接导入高危API(如 LoadLibrary 、 GetProcAddress 等)会导致IAT(Import Address Table)中存在明显特征,容易被安全产品检测。本文介绍一种通过 NtReadVirtualMemory 读取内存来动态获取函数地址的技术,可以有效规避IAT中的高危API。 2. 技术演进过程 2.1 传统Win32 API方式 最简单的Shellcode Loader直接使用Win32 API: LoadLibrary 加载DLL GetProcAddress 获取函数地址 直接调用目标函数 问题 :IAT中会显示这些高危API,容易被检测。 2.2 动态API调用方式 通过 LoadLibrary 和 GetProcAddress 实现动态API调用: 仅保留这两个基础API 其他函数通过它们动态获取 改进 :IAT中仅剩 LoadLibrary 和 GetProcAddress ,但仍可被检测。 2.3 现代动态获取函数地址技术 当前主流技术: 查询PEB和EAT(Export Address Table) 遍历内存并通过特征匹配定位函数 3. 核心创新技术:通过NtReadVirtualMemory获取函数地址 3.1 技术原理 使用 NtReadVirtualMemory (NT Native API)读取进程内存,解析PE和PEB结构来获取DLL基址和函数地址,完全规避IAT中的高危API。 3.2 关键工具:resolve.c resolve.c 是一个核心工具,输入参数: NtReadVirtualMemory 的地址 DLL名称 函数名称 输出:目标函数的地址 工作原理 : 通过Native API解析PE及PEB结构 获取DLL基址 解析导出表获取函数地址 4. 获取NtReadVirtualMemory地址的四种方法 4.1 方法1:直接输出 基本实现 : VT检测结果 :11/72检测率 优化方案 : 使用AI生成200行以上的合法程序(如任务管理器) 在特定条件下(如输入'z')才输出地址 VT检测率降至5/72 注意事项 : Microsoft Defender本地不会查杀 需要尝试多种程序类型(进程管理、文件操作、数学运算等) 4.2 方法2:格式化字符串漏洞 实现代码 : 编译命令 : 原理 : 利用未指定变量的格式化字符串漏洞 随机打印栈上的值,包括 NtReadVirtualMemory 地址 4.3 方法3:栈越界读 实现代码 : 编译命令 : 原理 : 利用小缓冲区越界读取栈上数据 特定偏移(16-23)处保存着 NtReadVirtualMemory 地址 4.4 方法4:堆越界读 实现代码 : 编译命令 : 原理 : 类似栈越界读,但在堆上实现 特定偏移处保存目标地址 5. 完整技术实现流程 通过上述任意方法获取 NtReadVirtualMemory 地址 使用 resolve.c 工具解析目标函数地址: 使用获取的函数地址直接调用目标API 6. 防御规避效果 IAT中不显示任何高危API 结合AI生成的合法程序外壳,VT检测率可降至5/72 Microsoft Defender本地不查杀 使用内存读取而非API调用,行为更隐蔽 7. 技术要点总结 核心创新 :利用 NtReadVirtualMemory 读取内存解析PE结构,完全规避IAT 地址获取 :四种内存泄露方法各有优劣,可根据场景选择 隐蔽性 :结合合法程序外壳和特定触发条件增强隐蔽性 兼容性 :在最新Windows Defender下仍有效 8. 防御建议(针对蓝队) 监控 NtReadVirtualMemory 的异常调用模式 检测内存泄露漏洞的利用行为 分析PEB/EAT解析行为 关注格式化字符串和缓冲区越界读的异常模式