进程注入是一种广泛应用于恶意软件和无文件攻击中的逃避技术,这需要在另一个进程的地址空间内运行自定义代码。进程注入提高了隐蔽性,一些技术也实现了持久性。 尽管有许多流程注入技术,在本博客中,我提供了十种在现实看到注入另一个进程运行恶意代码的技术。 我还提供了许多这些技术的屏幕截图,以便于逆向工程和恶意软件分析,协助针对这些常见技术进行检测和防御。
这种技术是用于将恶意软件注入另一个进程的最常用技术之一。 恶意软件将路径写入到其他进程的虚拟地址空间中的恶意动态链接库(DLL),并通过在目标进程中创建远程线程来确保远程进程加载它。
图 1
恶意软件首先需要定位注入的进程(例如svchost.exe)。这通常通过调用三个应用程序接口(API)来搜索进程:CreateToolhelp32Snapshot,Process32First和Process32Next。 CreateToolhelp32Snapshot是用于枚举指定进程或所有进程的堆或模块状态的API,它返回一个快照。 Process32First检索快照中有关第一个进程的信息,然后在循环中使Process32Next来遍历它们。 找到目标进程后,恶意软件通过调用OpenProcess获取目标进程的句柄。
如图2所示,恶意软件调用VirtualAllocEx有一段空间来写入其DLL的路径。 恶意软件然后调用WriteProcessMemory写入分配的内存中的路径。 最后,为了让代码在另一个进程中执行,恶意软件调用API,如CreateRemoteThread,NtCreateThreadEx或RtlCreateUserThread,后两者是为文档化的函数。
然而,一般的想法是将LoadLibrary的地址传递给这些API之一,以便远程进程必须代表恶意软件执行DLL。CreateRemoteThread被许多安全产品跟踪和标记。 此外,它会在磁盘上的留下恶意DLL文件。考虑到攻击者注入代码的目的一般是防御,所以复杂的攻击者可能不会使用这种方法。 下面的截图显示了一个名为Rebhip的恶意软件便是利用了这种注入技巧。
图 2 Rebhip 蠕虫使用了经典的DLL注入方式
恶意软件不会传递LoadLibrary的地址,而是将其恶意代码复制到现有的打开进程中,并使其执行(通过一个小的shellcode或通过调用CreateRemoteThread)。PE注入相比于LoadLibrary进行注入的一个优点是恶意软件不必在磁盘上释放恶意DLL。类似于第一种注入技术,恶意软件在主机进程(例如VirtualAllocEx)中分配内存,而不是写入“DLL路径”,它通过调用WriteProcessMemory写入其恶意代码。然而,使用这种方法的缺陷是更改了复制映像的基址。当恶意软件将其PE注入另一个进程时,它将具有不可预测的新基址,所以要求它动态地重新计算其PE的固定地址。为了克服这一点,恶意软件需要在主机进程中找到其重定位表地址,并通过循环遍历其重定位描述符来解析复制的映像的绝对地址。
图 3
这种技术类似于其他技术,如反射式DLL注入和内存模块加载,因为它们不会将任何文件释放到磁盘。然而,内存模块加载和反射式DLL注入方法甚至更加隐蔽。它们不依赖任何额外的Windows API(例如,CreateRemoteThread或LoadLibrary),因为它们在内存中加载并执行自身。反射式DLL注入通过创建一个DLL,在执行时将自身映射到内存中,而不依赖于Window的加载器。内存模块加载类似于反射式DLL注入,注射器或加载器负责将目标DLL映射到内存而不是DLL映射本身。在之前的一篇博文中,这两种内存方法被广泛讨论。
在分析PE注入时,在调用CreateRemoteThread之前,看到循环(通常是两个“for”循环,一个嵌套在另一个循环中)是很常见的情况。这种技术在crypter(加密和模糊恶意软件的软件)中非常受欢迎。在图4中,样本使用的便是这种技术。该代码有两个嵌套循环来调整其重定位表,可以在调用WriteProcessMemory和CreateRemoteThread之前看到它。 “and 0x0fff”指令也是另一个很好的标志,显示前12位用于获取到包含重定位块的虚拟地址的偏移量。现在,恶意软件已经重新计算了所有必需的地址,所有它需要做的是将其起始地址传递给CreateRemoteThread并将其执行。
图 4 在调用CreateRemoteThread之前,PE注入的循环结构示例
恶意软件可以执行被称为进程hollowing的技术,而不是将代码注入宿主程序(例如,DLL注入)。进程hollowing 发生于恶意软件从目标进程的内存中清空(镂空)合法代码并用恶意可执行文件覆盖目标进程的内存空间(如,svchost.exe)之时。
图 5
恶意软件首先创建一个新进程,以挂起模式托管恶意代码。如图6所示,该程序通过调用CreateProcess并将流程创建标志设置为CREATE_SUSPENDED(0x00000004)完成。新进程的主线程被创建为挂起状态,直到ResumeThread函数被调用才会运行。接下来,恶意软件需要用恶意的有效载荷来替换合法文件的内容。这可以通过调用ZwUnmapViewOfSection或NtUnmapViewOfSection来取消映射目标进程的内存。这两个API基本上释放了一个部分指向的所有内存。现在内存被取消映射,加载器执行VirtualAllocEx为恶意软件分配新内存,并使用WriteProcessMemory将每个恶意软件的部分写入目标进程空间。恶意软件调用SetThreadContext将entrypoint指向已编写的新代码段。最后,恶意软件通过调用ResumeThread来恢复挂起的线程。
图 6 Ransom.Cryak实现进程hollowing
这种技术与先前讨论的进程hollowing技术有一些相似之处。在线程执行劫持中,恶意软件针对进程的现有线程,并避免任何嘈杂的进程或线程的创建操作。因此,在分析期间,您可能会看到对CreateToolhelp32Snapshot和Thread32First的调用,后跟OpenThread。
图 7
在获取目标线程的句柄后,恶意软件通过调用SuspendThread来将线程置于挂起模式,最终执行注入。恶意软件调用VirtualAllocEx和WriteProcessMemory来分配内存并执行代码注入的操作。 该代码可以包含shellcode,恶意DLL的路径和LoadLibrary的地址。
图8给出了使用这种技术的通用木马程序。 为了劫持线程的执行,恶意软件通过调用SetThreadContext修改目标线程的EIP寄存器(包含下一条指令的地址)。之后恶意软件恢复线程来执行它已写入主机进程的shellcode。 从攻击者的角度来看,SIR方法可能是有问题的,因为在系统调用中暂停和恢复线程可能导致系统崩溃。为避免这种情况,更加复杂的恶意软件如果遇到EIP寄存器在NTDLL.dll的范围内的情况,将会恢复然后重试。
图 8 一般的木马正在执行线程执行劫持
Hooking是一种用于拦截函数调用的技术。恶意软件可以利用挂钩函数,在特定线程触发事件时加载其恶意DLL。这项技术通常通过调SetWindowsHookEx函数来将钩子例程安装到钩子链中来完成。 SetWindowsHookEx函数有四个参数。第一个参数是事件的类型。这些事件反映了钩子类型的范围,并且从键盘上的键(WH_KEYBOARD)到输入到鼠标(WH_MOUSE),CBT等的不同。第二个参数是指向恶意软件想要在事件中调用的函数的指针执行。第三个参数是包含该函数的模块。因此,在调用SetWindowsHookEx之前,看到对LoadLibrary和GetProcAddress的调用是非常常见的。该函数的最后一个参数是挂钩过程与之关联的线程。如果此值设置为零,则所有线程在触发事件时执行操作。然而,恶意软件通常针对一个线程来减少干扰,因此也可以在SetWindowsHookEx之前查看调用CreateToolhelp32Snapshot和Thread32Next来查找和定位单个线程。一旦DLL被注入,恶意软件代表其线程id被传递给SetWindowsHookEx函数的进程执行其恶意代码。在图9中,Locky Ransomware实现了这种技术。
、
图 9 Locky Ransomware 的hook注入过程
恶意软件可以使用Appinit_DLL, AppCertDlls, 以及 IFEO (映像劫持)这三个注册表项可以用于注入和维持注入,这三个注册表项具体的位置如下:
恶意软件可以将其恶意dll文件的位置插入到Appinit_Dlls注册表项下,以使其他进程加载这个dll文件。 此注册表项下的每个dll文件都会随着User32.dll的加载而同样加载到进程中。 User32.dll是用于存储图形元素(如对话框)的非常常用的库。 因此,当恶意软件修改这个注册表子项时,大多数进程都将加载恶意dll文件。 图10显示了木乃伊依赖这种技术进行注入和维持注入的方法。 它只需打开Appinit_Dlls注册表项,方法是调用RegCreateKeyEx,并通过调用RegSetValueEx来修改它的值。
图 10 Ginwui修改AppIniti_DLLs注册表项
这种方法与AppInit_DLLs方法非常相似,只是将此注册表项下的DLL加载到调用CreateProcess,CreateProcessAsUser,CreateProcessWithLogonW,CreateProcessWithTokenW和WinExec的每个进程中。
IFEO通常用于调试目的。开发人员可以在此注册表项下设置“调试器值”,将程序附加到另一个可执行文件进行调试。 因此,每当启动可执行文件时,将附加到该程序。 要使用此功能,您可以简单地给出调试器的路径,并将其附加到要分析的可执行文件。 恶意软件可以修改此注册表项以将其注入到目标可执行文件中。 在图11中,Diztakun木马通过修改任务管理器的调试器值来实现此技术。
图11 : Diztakun木马修改IFEO注册表项
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课