10种常见的进程注⼊技术的总结
译者:
0x00 前⾔
进程注⼊是⼀种⼴泛应⽤于恶意软件和⽆⽂件攻击中的逃避技术,这意味着可以将⾃定义代码运⾏在另⼀个进程的地址空间内。进程注⼊提⾼了隐蔽性,也实现了持久化。尽管有⾮常多的进程注⼊技术,但是本⽂我只列举了10种常见的技术。我还提供了这些技术的相关截图以便逆向和恶意软件的分析,并帮助防御这些技术。
0x01 通过CreateRemoteThread和LoadLibrary的DLL注⼊
这是进程注⼊最常见的技术。恶意软件将恶意的动态链接库的路径写⼊另⼀个进程的虚拟地址空间内,通过在⽬标进程中创建远程线程来确保远程进程加载它。
恶意软件⾸先需要选择⽬标进程(例如)。通常使⽤API:CreateToolhelp32Snapshot, Process32First, 和 Process3 2Next来完成。CreateToolhelp32Snapshot是个⽤于枚举指定进程或所有进程的堆或模块的状态,并且它返回⼀个快照。Process32 First得到快照中的第⼀个进程的信息,然后Process32Next来遍历所有的进程。在到⽬标进程后,恶意软件调⽤OpenProcess得到⽬标进程的句
柄。
如上图所⽰,恶意软件调⽤VirtualAllocEx得到写⼊路径的内存空间。然后调⽤WriteProcessMemory在分配的内存中写⼊路径(动态链接库)。最后,调⽤API(如CreateRemoteThread、NtCreateThreadEx、RtlCreateUserThread)使得另⼀个进程执⾏代码。后两个API是未⽂档化的。然⽽,通常想法是将LoadLibrary的地址传⼊这些API中的⼀个,以便远程进程执⾏DLL。
CreateRemoteThread被许多安全产品跟踪并标记。⽽且,它在磁盘上⾯留下了⼀个恶意的DLL可供检测。考虑到攻击者注⼊代码最常见的⽬的是逃避防御,⾼明的攻击者不会使⽤这种⽅式。下⾯是名为Rebhip(Sha256: 07b8f25e7b536f5b6f686c12d04edc3 7e11347c8acd5c53f98a174723078c365)的恶意软件使⽤了这种技术。
0x02 可执⾏⽂件注⼊(PE注⼊)
恶意软件并不传⼊LoadLibrary的地址,⽽是拷贝恶意代码到打开的进程中并执⾏(通过⼩段shellcode或者调⽤CreateRemoteTh read)。与LoadLibrary相⽐,PE注⼊的优势是恶意软件不需要在磁盘中释放⼀个恶意的DLL。与上个技术类似,恶意软件在⽬标进程中分配内存,调⽤WriteProcessMemory将恶意代码⽽不是DLL路径写⼊内存。然⽽,这种⽅式的缺陷是被复制的映像的基址的改变。当⼀个恶意软件注⼊PE到另⼀个进程,它的新基址是不可预料的,需要动态重新计算PE的地址。为了完成这个,
恶意软件需要到⽬标进程的重定位表,并根据它的重定位描述解析被复制映像的绝对地址。
这种技术和其他技术很类似,如反射DLL注⼊和内存模块加载,因为他们都不释放任何⽂件到磁盘。但是,内存模块和反射DLL 注⼊更加隐蔽。他们不依赖Windows API(如CreateRemoteThread或LoadLibrary),因为他们在内存中加载并执⾏⾃⾝。反射DLL 注⼊通过在内存中创建⼀个DLL映射执⾏,⽽不依赖Windows的加载器。内存模块加载和反射DLL注⼊类似,其不同之处只是在于内存模块加载的注⼊器或加载器负责映射⽬标DLL到内存中⽽不是DLL⾃⾝映射。在之前的中,讨论过这两种技术。
当分析PE注⼊时,在调⽤CreateRemoteThread之前通常能看见循环(通常是两个for循环,⼀个嵌套在另⼀个中)。这种技术在crypter(加密和混淆软件)中⾮常流⾏。下图中的样本(Sha256: ce8d7590182db2e51372a4a04d6a0927a65b2640739f9ec01cfd6 c143b1110da)充分利⽤了这种技术。在调⽤WriteProcessMemory和CreateRemoteThread之前有两层循环来处理重定位。“and 0x 0fff”指令也是⼀个⽐较好的表征,它标明了头12位⽤于得到包含重定位块的虚拟地址的偏移量。现在恶意软件重新计算了所有需要的地址了,只需要将起始地址传⼊CreateRemoteThread并执⾏就⾏了。
0x03 进程hollow(⼜名进程替换和RunPE)
恶意软件有⼀种技术叫进程hollow,⽽不是注⼊代码到程序中(如DLL注⼊)。进程hollow发⽣在恶意
软件unmap⽬标进程的合法内存代码,并使⽤恶意的代码覆写⽬标进程的内存(如)的时候。
恶意软件⾸先以挂起模式创建⼀个新进程来容纳恶意代码。如下图(Sha256: eae72d803bf67df22526f50fc7ab84d838efb2865c 27aef1a61592b1c520d144),以CREATE_SUSPENDED (0x00000004)为参数调⽤CreateProcess。新进程的主线程创建后就处于挂起状态,直到调⽤ResumeThread才会继续执⾏。接下来,恶意软件需要使⽤恶意的payload来填充合法⽂件的内容。调⽤ZwU nmapViewOfSection或者NtUnmapViewOfSection来unmap⽬标进程的内存。这两个API将释放section指向的所有内存。内存unmap 之后,使⽤WriteProcessMemory将恶意软件的节写⼊⽬标进程。调⽤SetThreadContext将⼊⼝点指向它已写⼊的新的代码节。最后,调⽤ResumeThread恢复挂起进程的执⾏。
createprocessa0x04 线程执⾏劫持(⼜名挂起、注⼊并恢复)
这种技术类似于进程hollow。在线程执⾏劫持中,恶意软件的⽬标是进程中已存在的线程,⽽且没有创建任何进程或线程。因此,在分析期间你可能看见CreateToolhelp32Snapshot和Thread32First、OpenThread。
在得到⽬标线程的句柄后,恶意软件调⽤SuspendThread将线程挂起。调⽤VirtualAllocEx和WriteProc
essMemory来分配内存并执⾏代码注⼊。代码包含shellcode,恶意DLL的路径和LoadLibrary的地址。
下图(Sha256: 787cbc8a6d1bc58ea169e51e1ad029a637f22560660cc129ab8a099a745bd50e)描述了⼀个普通⽊马是如何使⽤这种技术的。为了劫持线程的执⾏,恶意软件调⽤SetThreadContext修改⽬标线程的EIP寄存器(包含下条执⾏指令的地址的寄存器)。随后,恶意软件恢复线程继续执⾏它已写⼊到宿主进程的shellcode。从攻击者的⾓度看,这种⽅式是有问题的,因为在系统调⽤的中途挂起并恢复线程可能引起系统崩溃。为了避免这种情况的发⽣,更复杂的利⽤技术是,⼀旦EIP寄存器在NTDLL.dll中就恢复并重试。
0x05 通过SetWindowsHookEx钩⼦注⼊
钩⼦是⽤于拦截函数调⽤的⼀种技术。恶意软件能利⽤指定线程中事件触发来加载他们的恶意DLL。通常使⽤SetWindowsHook Ex来安装消息钩⼦。SetWindowsHookEx有4个参数。第⼀个参数是事件的类型。事件有很多的,有键盘按键(WH_KEYBOARD)和⿏标输⼊(WH_MOUSE)等。第⼆个参数是个函数指针,指向恶意软件想要处理事件的函数。第3个参数是包含函数的模块。因此,通常可以看见LoadLibrary、GetProcAddress、SetWindowsHookEx。最后⼀个参数是消息钩⼦关联的线程。如果值为0,则针对所有线程。然⽽,只针对某个线程的⽬标会⼩很多,因此也可能看见CreateToolhelp32Snapshot和Thread32Next。⼀旦DLL被注⼊后,恶意软件将执⾏恶意代码。下图中,
软件Locky(Sha256: 5d6ddb8458ee5ab99f3e7d9a21490ff4e5bc9808e18b9e20b6 dc2c5b27927ba1)就使⽤了这种技术。
0x06 通过注册表修改(如AppInit_DLLs,AppCertDlls,IFEO)
Appinit_DLL, AppCertDlls, IFEO(映像劫持)可以⽤于注⼊和持久化。完整的路径如下:
AppInit_DLLs
恶意软件能在AppInit_DLLs键下插⼊恶意的DLL的路径,以便其他进程加载。该键下每个DLL会被加载到所有的加载User32.dll的进程中。User32.dll是常见的Windows基础库。因此,当恶意软件修改这个⼦键时,⼤量进程将加载恶意的DLL。下图中,⽊马Ginw ui(Sha256: 9f10ec2786a10971eddc919a5e87a927c652e1655ddbbae72d376856d30fa27c)依赖了这种技术。它通过调⽤RegCr eateKeyEx打开AppInit_DLLs键,并调⽤RegSetValueEx修改它。
AppCertDlls
这种⽅式类似与AppInit_DLLs,除了该键下的DLL会加载到调⽤Win32 API CreateProcess, CreateProcessAsUser, CreateProce ssWithLogonW, CreateProcessWithTokenW, WinExec的进程中。
IFEO
IFEO通常⽤于调试。开发者能在该键下设置调试器,来附加调试。因此,当可执⾏⽂件启动时,附加到它的程序也会启动。为了使⽤这功能,你能简单的设置调试器的路径,并附加到你想分析的可执⾏⽂件上。下图,⽊马Diztakun(Sha256: f0089056fc6a314 713077273c5910f878813fa750f801dfca4ae7e9d7578a148)使⽤了这种技术,它修改了任务管理器的调试器的值。
0x07 APC注⼊和AtomBombing
恶意软件利⽤异步过程调⽤(APC)来强制另⼀个线程执⾏附加到APC队列的⾃定义代码。每个线程都有⼀个APC队列,当线程进⼊可变状态(编辑注: 这⾥疑为英⽂原⽂的拼写错误,有两处使⽤了alterable state⼀词,⽽⼀处使⽤了alertable state,疑应为alt erable state)时,可以被执⾏。当调⽤SleepEx, SignalObjectAndWait, MsgWaitForMultipleObjectsEx, WaitForMultipleObjectsEx, WaitForSingleObjectEx时进⼊可变状态。恶意软件通常查询线程是否处于可变状态,然后调⽤OpenThread和QueueUserAPC来向线程插⼊APC。QueueUserAPC有3个参数:1. ⽬标线程的句柄 2. 恶意软件想要执⾏的函数指针 3. 传给函数的参数。下图,恶意软件Amanahe(Sha256: f74399cc0be275376dad23151e3d0c2e2a1c966e6db6a695a05ec1a30551c0ad)⾸先调⽤了OpenTh
read 来得到另⼀个线程的句柄,然后调⽤QueueUserAPC,以LoadLibrary作为函数指针注⼊恶意DLL。
AtomBombing由⾸次提出,然后在Dridex V4中使⽤。正如之前博⽂中讨论的,这种技术也依赖APC注⼊。然⽽它使⽤atom表来写⼊到另⼀个进程的内存。
0x08 通过SetWindowLong的窗⼝内存注⼊(EWMI)
EWMI依赖注⼊到资源管理器托盘窗⼝内存中,并在恶意软件家族Gapz和PowerLoader中使⽤多次。当注册⼀个窗⼝类时,应⽤程序能指定额外的内存字节,称为额外的窗⼝内存(EWM)。然⽽,在EWM中没有太多的空间。为了规避这个限制,恶意软件将代码写⼊的共享段中,并使⽤SetWindowLong和SendNotifyMessage得到⼀个指向shellcode的函数指针,然后执⾏它。
当写⼊共享段时,恶意软件有两个选项。它能创建⼀个共享段⾃⼰映射到另⼀个进程(如explorer)中,或者打开⼀个已存在的共享段。前者有分配堆内存的开销,⽽且还要调⽤NtMapViewOfSection等API,因此后者更常⽤。在恶意软件将shellcode写⼊共享段后,使⽤GetWindowLong和SetWindowLong来访问并修改Shell_TrayWnd的额外的窗⼝内存。GetWindowLong是⽤于通过32位值作为偏移得到窗⼝类对象中额外窗⼝内存,同时使⽤SetWindowLong能改变指定偏移的值。通过完成这个,恶意软件能改变窗⼝类中的函数指针,将它指向共享段的shellcode。
和上述的技术⼀样,恶意软件需要触发写⼊的代码。之前说,它是通过调⽤类似CreateRemoteThread,SetThreadContext,Qu eueUserAPC这些API来实现的。与之前不同的是,这种技术是通过使⽤SendNotifyMessage来触发代码执⾏的。
⼀旦执⾏SendNotifyMessage,Shell_TrayWnd将接收到并将控制移交给SetWindowLong设置的地址。下图,名为(Sha256: 5 e56a3c4d4c304ee6278df0b32afb62bd0dd01e2a9894ad007f4cc5f873ab5cf)的恶意软件使⽤了这种技术。
0x09 使⽤Shims注⼊
微软提供了给开发者,这主要是为了向后兼容。Shims允许开发者不必重写代码就能修复程序。通过利⽤shims,开发者告诉操作系统如何处理他们的应⽤程序。Shims本质是Hook API的⽅式。恶意软件能利⽤shims实现注⼊和持久化。当加载⼆进制时,Wind ows运⾏Shim引擎以检查shim数据库,以便使⽤合适的修复。
有很多修复可以利⽤,但是恶意软件最喜欢的是⼀些安全相关的(如DisableNX, DisableSEH, InjectDLL等)。为了安装⼀个shi m数据库,恶意软件部署了。例如,常见的⼀种⽅式是执⾏,并将它指向恶意的sdb⽂件。如下图,⼀个⼴告软件“Search Protect by Conduit”(Sha2
56: 6d5048baf2c3bba85adc9ac5ffd96b21c9a27d76003c4aa657157978d7437a20),使⽤shim来实现了持久化和注⼊。它执⾏⼀个“InjectDLL”shim到⾕歌chrome中加载vc32loader.dll。有⼀些现成的⼯具可以分析sdb⽂件,下⾯是我使⽤分析的结果。
0x0A IAT hook和Inline hook(应⽤层rootkit)
IAT hook和inline hook通常也叫应⽤层rootkit。IAT hook使⽤⽤于改变导⼊地址表的技术。当合法的程序调⽤位于DLL中API时,将会执⾏被替换的API。相反,在inline hook中,恶意程序修改API函数本⾝。如下图,恶意软件FinFisher(Sha256: f827c92fbe832 db3f09f47fe0dcaafd89b40c7064ab90833a1f418f2d1e75e8e),IAT就hook了CreateWindowEx。
0x0B 总结
本⽂中,我描述了恶意软件⽤于隐藏⾃⾝⾏为的10种不同的技术。通常,恶意软件直接注⼊shellcode到另⼀个进程中或者强制其他进程加载恶意DLL。如下表,我已经将不同的技术进⾏了分类,并提供了样本,⽤于查看在本⽂提到的每个注⼊技术。这可以帮助研究者⽤于在逆向时识别各种技术。
攻击者和研究员⼀直在研究新的注⼊和隐蔽的技术。本⽂介绍了10种常见的技术,但是还有其他的,如。防御者任重道远。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论