67

十种进程注入技术介绍:常见注入技术及趋势调查

 5 years ago
source link: https://www.freebuf.com/articles/system/187239.html?amp%3Butm_medium=referral
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

前言

进程注入是一种广泛使用的躲避检测的技术,通常用于恶意软件或者无文件技术。其需要在另一个进程的地址空间内运行特制代码,进程注入改善了不可见性,同时一些技术也实现了持久性。尽管目前有许多进程注入技术,但在这篇文章中,我将会介绍十种在野发现的,在另一个程序的地址空间执行恶意代码的进程注入技术,并提供这些技术应用的截图,以便于逆向工程和恶意软件分析,然后协助检测并防御这些进程注入技术。

beQraeE.jpg!web

一、通过CREATEREMOTETHREAD和LOADLIBRARY进行经典DLL注入

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

F3y2uqV.gif

恶意软件首先需要选择被注入的目标进程(例如svchost.exe),这通常可以通过调用三个应用编程接口(API)搜索进程来完成:CreateToolhelp32Snapshot,Process32First和Process32Next。CreateToolhelp32Snapshot是用于枚举指定进程或所有进程的堆或模块状态的API,其会返回一个快照。Process32First会检索有关快照中第一个进程的信息,然后通过循环Process32Next来迭代。找到目标进程后,恶意软件通过调用OpenProcess获取目标进程的句柄。

如图一所示,恶意软件调用VirtualAllocEx来获得写入其DLL路径的空间。然后恶意软件调用WriteProcessMemory在已分配的内存中写入路径。最后,为了让代码在另一个进程中执行,恶意软件作者会调用API,例如CreateRemoteThread,NtCreateThreadEx或RtlCreateUserThread。后两个并未存在应用记录,但是一般的想法就是将LoadLibrary的地址传递给其中一个API,以便远程进程不得不代表恶意软件执行DLL。

很多杀毒软件都会追踪和标记CreateRemoteThread,此外,注入也需要磁盘上存在恶意DLL。但这是可以被检测到的。考虑到攻击者最常通过注入代码以逃避检测,所以一些老练的攻击者可能并不会使用这种方法。下面的截图展示了一个叫Rebhip的恶意软件应用了此技术。

BrU3ium.jpg!web

二、PORTABLE EXECUTABLE注入(PE注入)

这种技术斌没有传递LoadLibrary的地址,而是将其恶意代码复制到已存在的开放进程并执行(通过shellcode或调用CreateRemoteThread)。PE注入相对于LoadLibrary注入的一个优点是恶意软件不必在磁盘上放一个恶意DLL。与第一种技术类似,恶意软件在宿主进程中分配到内存,其并没有编写“DLL路径”,而是通过调用WriteProcessMemory来编写其恶意代码。然而,这种方法的一个缺陷是目标基址的改变,当恶意软件将其PE注入到另一个进程时,其会有一个新的不可预测的基址,这就要求其动态地重新计算PE的地址。为了解决这个问题,恶意软件需要在宿主进程中找到其重定位表地址,并通过循环其重定位描述符来解析绝对地址。

NVZz6bR.gif

此技术类似于其他技术,例如反射式DLL,因为它们不会将任何文件放在磁盘,但是,反射式DLL注入方法甚至会更加隐蔽。它们不依赖于任何额外的Windows API(例如CreateRemoteThread或LoadLibrary),因为它们在内存中加载和执行自己。反射式DLL注入通过创建一个DLL来实现,该DLL在执行时将自身映射到内存,而不是依赖于Windows的loader。

在分析PE注入时,调用CreateRemoteThread之前通常会看到循环(通常是两个“for”循环,一个嵌套在另一个中)这种技术在crypter(加密和混淆恶意软件的软件)中非常流行。在图二中,样本的单元测试中正在利用这种技术。代码有两个嵌套循环来调整其重定位表,可以在调用WriteProcessMemory和CreateRemoteThread之前看到它。“AND 0x0fff”指令是另一个好指示,表明前12位用于获取包含重定位块的虚拟地址的偏移量。既然恶意软件已经重新计算了所有必要的地址,那么它需要做的只是将其起始地址传递给CreateRemoteThread并让它执行。

y2a2muf.jpg!web

三、PROCESS HOLLOWING技术(又名 PROCESS REPLACEMENT AND RUNPE)

恶意软件可以不用将代码注入宿主程序,而是利用Process Hollowing技术。当恶意软件从目标进程中取消映射,并使用恶意可执行文件覆盖目标进程的内存空间时,会发生Process Hollowing。

MbIrYnr.gif

恶意软件首先会创建一个新进程,以挂起模式托管恶意代码,如图三所示,这是通过调用CreateProcess并将Process Creation Flag设置为CREATE_SUSPENDED(0×00000004)来完成的。新进程的主线程是在挂起状态下创建的,并且在调用ResumeThread函数之前不会执行。接下来,恶意软件需要使用恶意载荷交换合法文件的内容,这是通过调用ZwUnmapViewOfSection或NtUnmapViewOfSection来取消映射目标进程的内存完成的。这两个API基本上释放了一个区的所有内存。现在内存处于未映射状态,loader执行V​​irtualAllocEx为恶意软件分配新内存,并使用WriteProcessMemory将每个恶意软件的部分写入目标进程空间。而恶意软件通过调用SetThreadContext将入口点指向它已编写的新代码段。最后,恶意软件通过调用ResumeThread恢复挂起的线程,使进程退出挂起状态。

aqmYviY.jpg!web

四、线程执行劫持技术(或者说SUSPEND, INJECT, AND RESUME (SIR))

该技术与先前讨论的Process Hollowing技术有一些相似之处。在线程执行劫持中,恶意软件以进程的现有线程为目标,并避免任何其他的进程或线程创建操作。因此,在分析期间,你可能会看到对CreateToolhelp32Snapshot和Thread32First的调用,然后是OpenThread。

qABfUzV.gif

获取目标线程的句柄后,恶意软件通过调用SuspandThread来挂起这个线程,然后调用VirtualAllocEx和WriteProcessMemory来分配内存并执行代码注入。代码可以包含shellcode,恶意DLL的路径以及LoadLibrary的地址。

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

3UVzAfi.jpg!web

五、通过SETWINDOWSHOOKEX进行HOOK注入

HOOK是一种拦截函数调用的技术,恶意软件可以利用HOOK的功能在特定线程中触发事件时加载其恶意DLL。这通常通过调用SetWindowsHookEx将hook routine安装到HOOK链中来完成。SetWindowsHookEx函数有四个参数。第一个参数是事件的类型。事件反映了HOOK类型的范围,从键盘上的按键(WH_KEYBOARD)到鼠标输入(WH_MOUSE),CBT等等。第二个参数是指向恶意软件想要在事件上调用的函数的指针。第三个参数是包含该函数的模块。因此,在调用SetWindowsHookEx之前,通常会看到对LoadLibrary和GetProcAddress的调用。此函数的最后一个参数是与HOOK过程相关联的线程。如果此值设置为零,则所有线程都会在触发事件时执行操作。但是,恶意软件通常针对一个线程以降低噪声,因此在SetWindowsHookEx之前也可以看到调用CreateToolhelp32Snapshot和Thread32Next来查找和定位单个线程。注入DLL后,恶意软件代表其threadId传递给SetWindowsHookEx函数的进程执行其恶意代码。在图5中,Locky Ransomware实现了这种技术。

eIb2UbI.jpg!web

六、通过修改注册表实现注入和持久性

Appinit_DLL,AppCertDlls和IFEO(映像文件执行选项)都是恶意软件用于注入和持久性的注册表项。条目位于以下位置:

   HKLM\Software\Microsoft\Windows NT\CurrentVersion\Windows\Appinit_Dlls
   HKLM\Software\Wow6432Node\Microsoft\Windows NT\CurrentVersion\Windows\Appinit_Dlls
   HKLM\System\CurrentControlSet\Control\Session Manager\AppCertDlls
   HKLM\Software\Microsoft\Windows NT\currentversion\image file execution options

AppInit_DLLs

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

bamqYbi.jpg!web

AppCertDlls

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

映像文件执行选项(IFEO)

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

Rvyeyyu.jpg!web

七、APC注入和ATOMBOMBING

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

1)目标线程的句柄; 
2)指向恶意软件想要运行的功能的指针;
3)传递给函数指针的参数。 

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

zUVJNjj.jpg!web

AtomBombing是一项由enSilo研究首次引入的技术,然后用于Dridex V4。 正如我们在前一篇文章中详细讨论的那样,该技术也依赖于APC注入。 但是,它使用原子表写入另一个进程的内存。

八、通过SETWINDOWLONG进行附加窗口内存注入(EWMI)

EWMI依赖于注入资源管理器托盘窗口的额外窗口内存,并且已经在Gapz和PowerLoader等恶意软件系列中应用过几次。注册窗口类时,应用程序可以指定一些额外的内存字节,称为额外窗口内存(EWM)。但是,EWM的空间不大。为了规避此限制,恶意软件将代码写入explorer.exe的共享部分,并使用SetWindowLong和SendNotifyMessage使用指向shellcode的函数指针,然后执行它。

在写入共享部分时,恶意软件有两种选择。它既可以创建共享空间,也可以将其映射到自身和另一个进程(例如explorer.exe),也可以只打开已存在的共享空间。除了一些其他API调用之外,前者还有分配堆空间和调用NTMapViewOfSection的开销,因此后一种方法更常用。在恶意软件将其shellcode写入共享部分后,它使用GetWindowLong和SetWindowLong来访问和修改“Shell_TrayWnd”的额外窗口内存。GetWindowLong是一个API,用于将指定偏移量的32位值检索到窗口类对象的额外窗口内存中,SetWindowLong用于更改指定偏移量的值。这样一来,恶意软件可以简单地更改窗口类中的函数指针的偏移量,并将其指向写入共享部分的shellcode。

与上面提到的大多数其他技术一样,恶意软件需要触发它特制的代码。在先前讨论的技术中,恶意软件通过调用诸如CreateRemoteThread,QueueUserAPC或SetThreadContext之类的API来实现此目的。使用此方法,恶意软件会通过调用SendNotifyMessage来触发注入的代码。执行SendNotifyMessage后,Shell_TrayWnd接收控制并将控制转移到之前由SetWindowLong设置的值指向的地址。在图9中,名为PowerLoader的恶意软件使用此技术。

aaaqayI.jpg!web

九、SHIMS注入

Microsoft向开发人员提供SHIMS主要是为了向后兼容。SHIMS允许开发人员将修补程序应用于他们的程序,而无需重写代码。通过利用SHIMS,开发人员可以告诉操作系统如何处理应用程序。SHIMS本质上是一种挂钩API并定位特定可执行文件的方法。恶意软件可以利用SHIMS来定位持久性和注入的可执行文件。Windows在加载二进制文件时运行Shim Engine以检查SHIMS数据库以应用适当的修复程序。

现在有许多方法应用修复程序,但恶意软件的最爱是与安全相关的(例如,DisableNX,DisableSEH,InjectDLL等)。要安装填充数据库,恶意软件可以部署各种方法。例如,一种常见的方法是简单地执行sdbinst.exe,并将其指向恶意sdb文件。在图10中,广告软件“按导管搜索保护”使用垫片进行持久性和注入。它在Google Chrome中执行“InjectDLL”填充程序以加载vc32loader.dll。有一些用于分析sdb文件的现有工具,但是为了分析下面列出的sdb,我使用了python-sdb。

naQZ73z.jpg!web

十、IAT HOOKING和INLINE HOOKING (或者叫应用层ROOTKITS)

IAT hooking和inline hooking通常称为userland rootkit。IAT hooking是恶意软件用于更改导入地址表的技术。当合法应用程序调用位于DLL中的API时,其会执行替换的函数,而不是原始函数。相反,使用inline hooking,恶意软件则会修改API函数本身。在图11中,恶意软件FinFisher通过修改CreateWindowEx指向的位置来执行IAT hooking。

qIBN3ez.jpg!web

总结

在这篇文章中,我介绍了恶意软件用于在另一个进程中隐藏其活动的十种不同技术。通常,恶意软件会直接将其shellcode注入另一个进程,或者强制另一个进程加载其恶意库。在表1中,我对各种技术进行了分类,并提供了样本作为阅读本文所涵盖的每种注入技术的参考。

rIjuErm.jpg!web *参考来源: endgame ,FB小编Covfefe编译,转载请注明来自FreeBuf.COM


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK