freeBuf
主站

分类

云安全 AI安全 开发安全 终端安全 数据安全 Web安全 基础安全 企业安全 关基安全 移动安全 系统安全 其他安全

特色

热点 工具 漏洞 人物志 活动 安全招聘 攻防演练 政策法规

点我创作

试试在FreeBuf发布您的第一篇文章 让安全圈留下您的足迹
我知道了

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

代码注入之CreateProcess注入
lsec096 2025-04-03 19:43:40 11144
所属地 广东省

CreateProcess注入是一种通过主动创建目标进程来实现代码植入的技术,其主要优点是注入时机比较早,目标进程的防护和检测机制还未启动,可以有效规避目标进程中的一些安全防护和检测。比如,在游戏外挂中,用于在游戏的反外挂驱动起来之前获取游戏进程的读写权限;在红队渗透测试中,用于绕过杀软/EDR基于API Hook的注入检测。本文将介绍CreateProcess注入的基本框架,基于此框架介绍四种不同的注入实现,最后给出检测和对抗方案。

一、核心环节

CreateProcess注入可以分为三个环节:

  1. 主动创建挂起进程:通过CreateProcess等API以CREATE_SUSPENDED标志创建处于挂起状态的目标进程,阻止其立即执行。

BOOL CreateProcessA(
[in, optional]      LPCSTR                lpApplicationName,
[in, out, optional] LPSTR                 lpCommandLine,
[in, optional]      LPSECURITY_ATTRIBUTES lpProcessAttributes,
[in, optional]      LPSECURITY_ATTRIBUTES lpThreadAttributes,
[in]                BOOL                  bInheritHandles,
[in]                DWORD                 dwCreationFlags,  // 填 CREATE_SUSPENDED
[in, optional]      LPVOID                lpEnvironment,
[in, optional]      LPCSTR                lpCurrentDirectory,
[in]                LPSTARTUPINFOA        lpStartupInfo,
[out]               LPPROCESS_INFORMATION lpProcessInformation
);
  1. 注入代码并构造执行时机:在挂起的进程内存中写入shellcode,并构造执行时机,常见的方法有:

    • 创建远线程:以shellcode为线程函数创建远线程,可立即执行,不需要等进程恢复。

    • 添加APC:以shellcode为APC函数添加到主线程的APC队列,在主线程恢复时调用APC。

    • Hook线程IP(指令指针)寄存器:修改目标进程中主线程的IP寄存器指向shellcode,shellcode执行完后跳回原IP处。

    • 修改入口点:修改进程入口点指向shellcode,shellcode执行完后跳回原入口点。

  2. 恢复目标进程执行:恢复目标进程执行,shellcode在指定时机被调用,完成注入。

二、具体实现

2.1 实现框架

基于上述环节,可以给出CreateProcess注入的代码框架,只是获取执行时机这一步骤的具体实现不同。

  1. 创建挂起进程:CreateProcess+CREATE_SUSPENDED

  2. 分配内存:VirtualAllocEx

  3. 构建执行时机:取决于具体注入方式

  4. 恢复主线程:ResumeThread

#define SHELLCODE_SIZE 0x1000

int main(int argc, char** argv) {
    char* victimPath = argv[1];
    char* injectDllPath = argv[2];

    STARTUPINFOA si = { 0 };
    PROCESS_INFORMATION pi = { 0 };

    do {
        // 1. 以挂起状态创建目标进程
        si.cb = sizeof(si);
        if (!CreateProcessA(victimPath, NULL, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &si, &pi))
        {
            printf("[-] Create victim process failed: %d\n", GetLastError());
            break;
        }
        printf("[+] Create victim process OK, pid=%d, main tid=%d\n", pi.dwProcessId, pi.dwThreadId);

        // 2. 在目标进程中分配内存,用于写入Shellcode
        void* shellcodeAddr = VirtualAllocEx(pi.hProcess, NULL, SHELLCODE_SIZE, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
        if (shellcodeAddr == NULL) {
            printf("[-] Alloc memory in victim process failed: %d\n", GetLastError());
            break;
        }
        printf("[+] Alloc memory in victim process OK: %p\n", shellcodeAddr);

        // 3. TODO: 写入shellcode,并构建shellcode的执行时机

        // 4. 恢复目标线程的执行
        ResumeThread(pi.hThread);
        printf("[+] Inject done\n");
    } while (false);

    if (pi.hProcess != NULL)
        CloseHandle(pi.hProcess);
    if (pi.hThread != NULL)
        CloseHandle(pi.hThread);
    return 0;
}

2.2 执行时机的构建

创建远线程

CREATE_SUSPENDED标记创建目标进程,实际上暂停的是目标进程中的主线程,并不影响其他线程的执行。所以,可以通过创建远线程的方式,执行写入的shellcode。比如,把注入的dll的路径写入申请的shellcode位置,然后以LoadLibraryA为线程函数创建远线程,线程函数参数为dll路径,线程执行时就会加载dll。

bool injectByRemoteThread(HANDLE hVictimProcess, void* shellcodeAddr, const char* injectDllPath) {
    // 将注入的dll的路径写入分配的shellcode内存中
    if (!WriteProcessMemory(hVictimProcess, shellcodeAddr, injectDllPath, strlen(injectDllPath) + 1, NULL))
    {
        printf("[-] Write injection dll path to victim process failed: %d\n", GetLastError());
        return false;
    }
    printf("[+] Write injection dll path to victim process OK\n");

    // 创建远线程,线程函数为LoadLibraryA,参数为shellcode地址
    DWORD tid = 0;
    HANDLE hRemoteThread = CreateRemoteThread(hVictimProcess, NULL, 0, (PTHREAD_START_ROUTINE)LoadLibraryA, shellcodeAddr, 0, &tid);
    if (hRemoteThread == NULL) {
        printf("[-] Create remote thread for victim process failed: %d\n", GetLastError());
        return false;
    }
    printf("[+] Create remote thread for victim process OK: tid=%d\n", tid);
    return true;
}

添加APC

除了使用远线程执行shellcode,也可以使用APC的方式执行shellcode。APC(异步过程调用)是Windows系统提供的一种线程间通信机制,通过QueueUserAPC向目标线程的APC队列添加一个APC函数,当目标线程处于alertable状态时,就会执行APC函数。如果AP

可试读前30%内容
¥ 14.9 全文查看
9.9元开通FVIP会员
畅读付费文章
最低0.3元/天
# 代码注入
免责声明
1.一般免责声明:本文所提供的技术信息仅供参考,不构成任何专业建议。读者应根据自身情况谨慎使用且应遵守《中华人民共和国网络安全法》,作者及发布平台不对因使用本文信息而导致的任何直接或间接责任或损失负责。
2. 适用性声明:文中技术内容可能不适用于所有情况或系统,在实际应用前请充分测试和评估。若因使用不当造成的任何问题,相关方不承担责任。
3. 更新声明:技术发展迅速,文章内容可能存在滞后性。读者需自行判断信息的时效性,因依据过时内容产生的后果,作者及发布平台不承担责任。
本文为 lsec096 独立观点,未经授权禁止转载。
如需授权、对文章有疑问或需删除稿件,请联系 FreeBuf 客服小蜜蜂(微信:freebee1024)
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
lsec096 LV.2
这家伙太懒了,还未填写个人描述!
  • 4 文章数
  • 0 关注者
签名不等于可信:详解PE数字签名校验的漏洞与主动规避方案
2025-04-10
代码注入之Hook注入
2025-04-03
代码注入之消息钩子注入
2025-04-02
文章目录