【免杀】C2免杀技术(五)动态API

admin 2025年5月19日10:07:30评论5 views字数 2322阅读7分44秒阅读模式
一、什么是动态API

在C2免杀领域中,“动态API” 主要指的是绕过静态检测的一种技术手段,其本质是运行时动态解析和调用Windows API函数,而不是在程序编译阶段就明确引用这些API。这种方式可以有效躲避静态分析工具和杀软的签名识别。

为什么使用动态API? 

静态杀软和EDR会扫描程序中是否包含可疑API(比如 CreateRemoteThread、VirtualAllocEx、WriteProcessMemory 等),一旦在导入表(IAT)或代码段中发现这些函数,就可能被标记为恶意。通过动态API调用,这些函数不会直接出现在导入表中,也不会以明文字符串形式出现,提高了免杀能力。

什么是IAT导入表?

在Windows可执行文件(如 .exe 或 .dll)中,导入表(IAT,Import Address Table) 是PE结构中的一个关键部分,它告诉操作系统这个程序运行时需要哪些外部模块(DLL)和函数(API),并在加载时将它们的地址填入到程序中可调用的位置。一句话定义:IAT 是Windows程序用于调用外部DLL函数的一张“函数地址表”,由操作系统在加载时填充。 

举个直观的例子,假设你的程序要使用 Windows 的 MessageBoxA 函数,它位于 user32.dll 中。编译后 (静态导入),在PE文件头的导入表中,会列出DLL名、函数名;加载时操作系统的PE加载器会加载user32.dll,查找MessageBoxA函数的内存地址,并把这个地址写入到你的程序的IAT表项。然后你的代码中对MessageBoxA的调用,实际上是跳转到这个表项。

【免杀】C2免杀技术(五)动态API

因此,杀软和EDR能直接查看IAT,看你的程序调用了哪些函数(如上图),一旦发现这些敏感API,程序可能立即被标记为恶意; 通过动态API可以绕过IAT暴露。

二、免杀效果展示

这里用C++写一个简单的喝水提醒的程序,代码如下:

#include<windows.h>#include<iostream>#include<thread>#include<chrono>voidremindToDrinkWater(){    while (true) {        // 等待1小时(3600秒)        //std::this_thread::sleep_for(std::chrono::hours(1));        std::this_thread::sleep_for(std::chrono::seconds(10));        // 弹出消息框提醒喝水        MessageBoxA(NULL"该喝水了!""喝水提醒", MB_OK | MB_ICONINFORMATION);    }}intmain(){    // 启动提醒喝水的线程    std::thread reminderThread(remindToDrinkWater);    // 主线程保持运行    reminderThread.join();    return 0;}

运行测试,功能正常

【免杀】C2免杀技术(五)动态API

再复制一份,加上动态API解析和调用代码

#include<windows.h>#include<thread>#include<chrono>#include<iostream>typedefint(WINAPI* MessageBoxAFunc)(HWND, LPCSTR, LPCSTR, UINT);voidremindToDrinkWater(){    // 获取 user32.dll 的模块句柄    HMODULE hUser32 = LoadLibraryA("user32.dll");    if (!hUser32) {        std::cerr << "无法加载 user32.dll" << std::endl;        return;    }    // 动态获取 MessageBoxA 函数地址    MessageBoxAFunc pMessageBoxA = (MessageBoxAFunc)GetProcAddress(hUser32, "MessageBoxA");    if (!pMessageBoxA) {        std::cerr << "无法获取 MessageBoxA 函数地址" << std::endl;        return;    }    while (true) {        std::this_thread::sleep_for(std::chrono::seconds(10)); // 测试用:每10秒提醒一次        pMessageBoxA(NULL"该喝水了!""喝水提醒", MB_OK | MB_ICONINFORMATION);    }}intmain(){    std::thread reminder(remindToDrinkWater);    reminder.join();  // 等待线程结束(实际永远运行)    return 0;}

运行测试,功能正常

【免杀】C2免杀技术(五)动态API

将两个程序均编译出来

【免杀】C2免杀技术(五)动态API

使用StudyPE+对比一下两者的导入表,发现右边使用动态API技术的程序比左边少了user32.dll,所以IAT不可能存在MessageBoxA函数

【免杀】C2免杀技术(五)动态API

放到360下检测:第一个被杀;第二个使用了动态API技术,未被检测

【免杀】C2免杀技术(五)动态API

且能正常运行

【免杀】C2免杀技术(五)动态API

三、结尾

免杀效果通常受多方面影响,没有哪一种技术或者手段能够通吃,通常需要多种手段结合才能最终实现免杀;其次,实战中面临的环境也不一样,不同的杀软效果也不一样,具体问题还需具体分析。本系列文章以技术的实现为主,验证时讲究点到为止,以此表达一项技术的有效性。 

原文始发于微信公众号(仇辉攻防):【免杀】C2免杀技术(五)动态API

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2025年5月19日10:07:30
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   【免杀】C2免杀技术(五)动态APIhttps://cn-sec.com/archives/4078943.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息