注入程序教程(十种流行进程注入技术详细分析)(1)

注入程序教程(十种流行进程注入技术详细分析)(2)

前言

流程注入是一种恶意软件和无文件间谍攻击中使用的最为广泛的漏洞攻击技术,而且在攻击时还需要在另一个进程的地址空间内运行自定义代码。过程注入除了提高了攻击的隐蔽性之外,也实现了持久性攻击。尽管目前有许多流程注入技术,但在本文中,我只介绍十种在野外看到的能够运用另一个进程运行恶意代码的技术。在介绍的同时,我还会提供这些技术的屏幕截图,以便于逆向工程和恶意软件分析,协助针对这些常见技术进行的检测和防御。

注入程序教程(十种流行进程注入技术详细分析)(3)

一、经典的DLL注入

这种技术是用于将恶意软件注入另一个进程的最常用技术之一,其方法就是恶意软件将路径写入到其他进程的虚拟地址空间中的恶意动态链接库(DLL),并通过在目标进程中创建远程线程来确保远程进程加载它。

恶意软件首先需要找到注入过程,例如svchost.exe,要做到这一点,通常通过调用三个应用程序接口(API)来搜索进程:CreateToolhelp32Snapshot,Process32First和Process32Next。 CreateToolhelp32Snapshot是用于枚举指定进程或所有进程的堆或模块状态的API,通过它返回一个snapshot。 然后,Process32First检索snapshot中有关第一个进程的信息。最后,在循环中使用Process32Next来遍历它们。找到目标进程后,恶意软件通过调用OpenProcess获取目标进程的句柄。

如下图所示,恶意软件调用VirtualAllocEx时,会用一个空格来写入其DLL的路径。然后恶意软件调用WriteProcessMemory写入分配的内存中的路径。最后,为了让代码在另一个进程中执行,恶意软件会调用API,如CreateRemoteThread,NtCreateThreadEx或RtlCreateUserThread。而NtCreateThreadEx或RtlCreateUserThread则是无文档的,不过,一般的想法是将LoadLibrary的地址传递给其中一个API,以便远程进程必须代表恶意软件执行DLL。

目前,CreateRemoteThread已被许多安全产品跟踪和标记。此外,它需要可以检测到的磁盘上的恶意DLL。考虑到攻击者常常使用注入代码以逃避安全防护,现在的杀毒软件可能不会使用这种方法。下面的屏幕截图显示了一个名为Rebhip的恶意软件执行此技术的过程。

注入程序教程(十种流行进程注入技术详细分析)(4)

上图显示Rebhip蠕虫执行典型的DLL注入

Sha256:07b8f25e7b536f5b6f686c12d04edc37e11347c8acd5c53f98a174723078c365

注入程序教程(十种流行进程注入技术详细分析)(5)

二、PE注入

恶意软件不会传递LoadLibrary的地址,而是将其恶意代码复制到现有的开放进程中,并使其执行(通过一个小的shellcode或通过调用CreateRemoteThread)。相比LoadLibrary技术,PE注入的一个优点是恶意软件不必放弃磁盘上的恶意DLL。类似于第一种所介绍的经典注入技术,恶意软件会在主机进程(例如VirtualAllocEx)中分配内存,而不是写入DLL路径,它通过调用WriteProcessMemory写入其恶意代码。然而,使用这种方法的前提是要更改复制图像的基址。当恶意软件将其PE注入另一个进程时,它将具有不可预测的新基址,要求它动态地重新计算其PE的固定地址。为了解决这一问题,恶意软件需要在主机进程中找到其重定位表的地址,并通过循环遍历其重定位描述符来解析复制映像的绝对地址。

注入程序教程(十种流行进程注入技术详细分析)(6)

这种技术类似于其他技术,如反射式DLL注入和内存模块,因为它们不会将任何文件丢弃到磁盘。然而,内存模块和反射式DLL注入方法甚至更加隐蔽。它们不依赖任何额外的Windows API(例如,CreateRemoteThread或LoadLibrary),因为它们在内存中加载并通过自身执行。反射式DLL注入通过创建一个DLL,在执行时将自身映射到内存中,而不依赖于Window的加载器。内存模块类似于反射式DLL注入,注入器或加载器负责将目标DLL映射到内存而不是DLL映射本身。

在分析PE注入时,在调用CreateRemoteThread之前,看到循环(通常是两个“for”循环,一个嵌套在另一个循环中)是非常常见的。这种技术在密码(加密和模糊恶意软件的软件)中非常受欢迎。在下图中,样本单元测试利用的就是这种技术。该代码有两个嵌套循环来调整其重定位表,可以在调用WriteProcessMemory和CreateRemoteThread之前看到它。“and 0x0fff”指令也是另一个很好的指标,可以显示用于获取包含重定位块的虚拟地址偏移量的前12位。现在,恶意软件已经重新计算了所有必需的地址,它需要做的就是将其起始地址传递给CreateRemoteThread并将其执行。

注入程序教程(十种流行进程注入技术详细分析)(7)

上图为调用CreateRemoteThread之前PE注入循环的结构示例

Sha256:ce8d7590182db2e51372a4a04d6a0927a65b2640739f9ec01cfd6c143b1110da

三、PROCESS HOLLOWING

Process Hollowing是现代恶意软件常用的一种进程创建技术,虽然在使用任务管理器之类的工具查看时,这些进程看起来是合法的,但是该进程的代码实际上已被恶意内容所替代。

当恶意软件从目标进程的内存中解除HOLLOWING合法代码并用恶意可执行文件覆盖目标进程的内存空间(例如,svchost.exe)时,会发生进程中断。

恶意软件首先会创建一个新进程,以挂起模式托管恶意代码。如下图所示,通过调用CreateProcess并将流程创建标志设置为CREATE_SUSPENDED(0x00000004)完成。新进程的主线程被创建为挂起状态,直到ResumeThread函数被调用才会运行。接下来,恶意软件需要用恶意的有效载荷来替换合法文件的内容。这可以通过调用ZwUnmapViewOfSection或NtUnmapViewOfSection来取消映射目标进程的内存。这两个API基本上释放了一个指向所有内存的部分,当内存被取消映射后,加载器会执行VirtualAllocEx为恶意软件分配新内存,并使用WriteProcessMemory将每个恶意软件的部分写入目标进程空间。恶意软件调用SetThreadContext将entrypoint指向已编写的新代码段。最后,恶意软件通过调用ResumeThread来恢复挂起的线程,以使进程处于暂停状态。

上图就是Ransom.Cryak执行HOLLOWING的过程

Sha256:eae72d803bf67df22526f50fc7ab84d838efb2865c27aef1a61592b1c520d144

四、线程劫持注入(THREAD EXECUTION HIJACKING)

THREAD EXECUTION HIJACKING又名SUSPEND, INJECT, AND RESUME (SIR),这种技术与先前讨论的PROCESS HOLLOWING有一些相似之处。在线程执行劫持的过程中,恶意软件会针对进程的现有线程,并避免任何其他干扰进程或线程创建的操作。因此,在分析期间,你可能会看到对CreateToolhelp32Snapshot和Thread32First的调用,它们都紧随OpenThread。

在获取目标线程的句柄后,恶意软件通过调用SuspendThread来执行注入,将线程置于挂起模式。恶意软件调用VirtualAllocEx和WriteProcessMemory来分配内存并执行代码注入。该代码可以包含shellcode,恶意DLL的路径和LoadLibrary的地址。

下图展示了使用这种技术的trojan.generic,为了劫持线程的执行,恶意软件通过调用SetThreadContext修改目标线程的EIP寄存器(包含下一条指令的地址)。之后,恶意软件恢复线程来执行它已写入主机进程的shellcode。从攻击者的角度来看,SIR方法可能是有问题的,因为在系统调用中暂停和恢复线程可能导致系统崩溃。为避免这种情况,如果EIP寄存器在NTDLL.dll的范围内,攻击者将会恢复更复杂的恶意软件,然后重试。

注入程序教程(十种流行进程注入技术详细分析)(8)

上图为trojan.generic执行线程劫持的过程

Sha256:787cbc8a6d1bc58ea169e51e1ad029a637f22560660cc129ab8a099a745bd50e

注入程序教程(十种流行进程注入技术详细分析)(9)

五、通过SETWINDOWSHOOKEX进行注入

Hooking是一种用于拦截函数调用的技术,恶意软件可以利用挂钩功能,在特定线程触发攻击时加载其恶意DLL。这通常通过调用SetWindowsHookEx来将钩子例程安装到钩子链中来完成。 SetWindowsHookEx函数有四个参数,第一个参数是攻击的类型,这些攻击反映了钩子攻击类型的范围,并且从键盘上的键(WH_KEYBOARD)到输入到鼠标(WH_MOUSE),CBT都不同。第二个参数是指向恶意软件想要在攻击中调用的函数的指针执行。第三个参数是包含该函数的模块。因此,在调用SetWindowsHookEx之前,看到对LoadLibrary和GetProcAddress的调用是非常常见的。该函数的最后一个参数是挂钩过程与之关联的线程。如果此值设置为零,则所有线程在触发事件时执行操作。然而,恶意软件通常针对一个线程来减少对操作的干扰,因此也可以在SetWindowsHookEx之前查看调用CreateToolhelp32Snapshot和Thread32Next来查找和定位单个线程。一旦DLL被注入,恶意软件代表其threadId被传递给SetWindowsHookEx函数的进程执行其恶意代码。在下图中,Locky Ransomware就实现了这种技术。

注入程序教程(十种流行进程注入技术详细分析)(10)

上图为使用钩子注入的Locky Ransomware

Sha256:5d6ddb8458ee5ab99f3e7d9a21490ff4e5bc9808e18b9e20b6dc2c5b27927ba1

六、通过修改注册的方法来注入(比如APPINIT_DLLS,APPCERTDLLS,IFEO)

通过修改注册的方法来注入,比如APPINIT_DLLS,APPCERTDLLS,IFEO。Appinit_DLL,AppCertDlls和IFEO(图像文件执行选项)都是注册表项,恶意软件可用于注入和持久性攻击。条目位于以下位置:

HKLMSoftwareMicrosoftWindows NTCurrentVersionWindowsAppinit_Dlls

HKLMSoftwareWow6432NodeMicrosoftWindows NTCurrentVersionWindowsAppinit_Dlls

HKLMSystemCurrentControlSetControlSession ManagerAppCertDlls

HKLMSoftwareMicrosoftWindows NTcurrentversionimage file execution options

AppInit_DLLs

恶意软件可以将其恶意库的位置插入到Appinit_Dlls注册表项下,以使另一个进程加载其库。此注册表项下的每个库都将加载到加载User32.dll的每个进程中。 User32.dll是用于存储图形元素(如对话框)的非常常用的库。因此,当恶意软件修改此子项时,大多数进程将加载恶意库。下图显示了木乃伊依赖这种注入和持久性的方法,它只需打开Appinit_Dlls注册表项,方法是调用RegCreateKeyEx,并通过调用RegSetValueEx来修改它的值。

注入程序教程(十种流行进程注入技术详细分析)(11)

上图显示了Ginwui修改AppIniti_DLLs注册表项

Sha256:9f10ec2786a10971eddc919a5e87a927c652e1655ddbbae72d376856d30fa27c

AppCertDlls

这种方法与AppInit_DLLs方法非常相似,只是将此注册表项下的DLL加载到调用Win32 API函数CreateProcess,CreateProcessAsUser,CreateProcessWithLogonW,CreateProcessWithTokenW和WinExec的每个进程中。

图像文件执行选项(IFEO)

IFEO通常用于调试目的,开发人员可以在此注册表项下设置“调试器值”,将程序附加到另一个可执行文件进行调试。因此,每当启动可执行文件时,将附加到该程序。要使用此功能,你可以简单地给出调试器的路径,并将其附加到要分析的可执行文件。恶意软件可以修改此注册表项以将其注册到目标可执行文件中。在下图中,Diztakun木马通过修改任务管理器的调试器值来实现此技术。

注入程序教程(十种流行进程注入技术详细分析)(12)

上图为Diztakun木马修改IFEO注册表项的过程

Sha256:f0089056fc6a314713077273c5910f878813fa750f801dfca4ae7e9d7578a148

七、APC注入和AtomBombing内存注入

恶意软件可以利用异步过程调用(APC)强制另一个线程通过将其附加到目标线程的APC队列来执行其自定义代码。每个线程都有一个APC队列,它们在目标线程进入可变状态时等待执行。如果调用SleepEx,SignalObjectAndWait,MsgWaitForMultipleObjectsEx,WaitForMultipleObjectsEx或WaitForSingleObjectEx函数,线程将进入预警状态。恶意软件通常会查找处于可更改状态的任何线程,然后调用OpenThread和QueueUserAPC将APC排队到线程。 QueueUserAPC有三个参数:

1.目标线程的句柄;

2.指向恶意软件想要运行的功能的指针;

3.传递给函数指针的参数。

在下图中,Amanahe恶意软件首先调用OpenThread来获取另一个线程的句柄,然后使用LoadLibraryA调用QueueUserAPC作为函数指针,将其恶意DLL注入另一个线程。

2016年EnSilo网络安全公司的研究团队发现了一个可以绕过Windows查杀机制的方法,可以绕过所有Windows的杀毒软件和安全机制,他们把这个方法叫做AtomBombing内存注入。

今年IBM X-Force安全团队发现了一个Dridex银行木马的升级版本,该版本被称为Dridex v4。Dridex v4的重要改进是其使用了AtomBoming技术注入恶意代码从而躲避杀毒软件的查杀。

另外,AtomBoming技术还依赖APC注入。但是,它使用atom表写入另一个进程的内存。

注入程序教程(十种流行进程注入技术详细分析)(13)

上图为Almanahe 病毒执行APC注入的过程

Sha256:f74399cc0be275376dad23151e3d0c2e2a1c966e6db6a695a05ec1a30551c0ad

注入程序教程(十种流行进程注入技术详细分析)(14)

八、通过SETWINDOWLONG提供EXTRA WINDOW MEMORY INJECTION(EWMI)

EWMI依靠注入资源管理器托盘窗口以外的窗口内存,并被恶意软件使用过几次,如Gapz和PowerLoader。注册窗口类时,应用程序可以指定一些额外的内存字节,称为额外的窗口存储器(EWM)。然而,EWM没有太多的空间。为了规避这个限制,恶意软件将代码写入explorer.exe的共享部分,并使用SetWindowLong和SendNotifyMessage来指定一个指向shellcode的函数指针,然后执行它。

当进行共享部分的写入时,恶意软件有两个办法。第一种是可以创建共享部分,并将其映射到自身和另一个进程(例如,explorer.exe)。第二种是它可以简单地打开已经存在的共享部分。第一种在分配堆空间和调用NTMapViewOfSection以及其他一些API调用时花费很大,因此后一种方法被使用的更多。恶意软件在共享部分中写入其shellcode后,会使用GetWindowLong和SetWindowLong访问和修改“Shell_TrayWnd”的额外窗口内存。 GetWindowLong是用于将指定偏移量的32位值检索到窗口类对象的额外窗口存储器中的API,SetWindowLong用于更改指定偏移量的值。只有这样,恶意软件才可以简单地更改窗口类中的函数指针的偏移量,并将其指向写入共享部分的shellcode。

像上面提到的大多数其他技术一样,恶意软件需要触发它编写的代码。在以前讨论的技术中,我也讲过,恶意软件通过调用API(如CreateRemoteThread,QueueUserAPC或SetThreadContext)来实现这一点。通过这种方法,恶意软件通过调用SendNotifyMessage触发注入的代码。在执行SendNotifyMessage之后,Shell_TrayWnd接收并将控件传递给由SetWindowLong先前设置的值指向的地址。在下图中,名为PowerLoader的恶意软件使用的就是这种技术。

注入程序教程(十种流行进程注入技术详细分析)(15)

上图为PowerLoader注入由Shell对象控制的Windows 托盘窗口的额外窗口内存

Sha256:5e56a3c4d4c304ee6278df0b32afb62bd0dd01e2a9894ad007f4cc5f873ab5cf

九、使用SHIMS进行注入

微软向开发人员提供了Shims,主要是为了向后兼容(Backward Compatibility)。Shims允许开发人员将修补程序应用于程序,而无需重写代码。通过利用Shims,开发人员可以命令操作系统如何处理其应用程序,Shims本质上是一种嵌入API并针对特定可执行文件进行注入的方式。恶意软件可以利用Shims来进行持久性攻击并注入可执行文件。 Windows运行Shim引擎时,它会加载二进制文件以检查Shim过的数据库,以便应用适当的修补程序。

虽然目前有许多可以应用的修复程序,但是恶意软件还是喜欢相对安全相关一些的(例如DisableNX,DisableSEH,InjectDLL等)。要安装Shim过的数据库(himming database),恶意软件可以采用各种方法。例如,一个常见的方法是简单执行sdbinst.exe,并将其指向恶意的sdb文件。在下图中,广告软件“Search Protect by Conduit”使用Shims进行持久性和注入攻击,它在Google Chrome中执行“InjectDLL”Shims以加载vc32loader.dll。现在有一些用于分析sdb文件的工具,但是对于下面列出的sdb的分析,我使用了python-sdb。

注入程序教程(十种流行进程注入技术详细分析)(16)

上图为Search Protect用于注入目的的SDB

Sha256:6d5048baf2c3bba85adc9ac5ffd96b21c9a27d76003c4aa657157978d7437a20

十、Hook导入表(IAT hooking)或 INLINE HOOKING

Hook导入表(IAT hooking)和INLINE HOOKING通常被称为用户级rootkit(USERLAND ROOTKITS),HOOK导入表是一种恶意软件用于更改导入地址表的技术。当合法应用程序调用位于DLL中的API时,将执行替换的函数,而不是原始代码。相比之下,使用INLINE HOOKING,恶意软件可以修改API函数本身。在恶意软件FinFisher就是通过修改CreateWindowEx指针的位置执行HOOK导入表的。

注入程序教程(十种流行进程注入技术详细分析)(17)

总结

在这篇文章中,我介绍了恶意软件在另一个进程中隐藏其活动的十种不同技术。通常,恶意软件会直接将其shellcode注入到另一个进程中,或者强制另一个进程加载其恶意库。在下表中,我对本文所讲的十种技术进行了分类,并提供了样本。

注入程序教程(十种流行进程注入技术详细分析)(18)

上表为流程注入可以通过直接将代码注入到另一个进程中,或者通过强制将DLL加载到另一个进程来完成。

攻击者和研究人员经常会发现新的用来实现注入并提供隐身的技术,这篇文章详细介绍了十种常见和新兴的技术,但并没有罗列全,比如COM劫持。

原PO主: xiaohui/嘶吼专业版

,