STATEMENT
声明
由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,雷神众测及文章作者不为此承担任何责任。
雷神众测拥有对此文章的修改和解释权。如欲转载或传播此文章,必须保证此文章的完整性,包括版权声明等全部内容。未经雷神众测允许,不得任意修改或者增减此文章内容,不得以任何方式将其用于商业目的。
星火实验室 专注于实战攻防与研究,研究涉及实战攻防、威胁情报、攻击模拟与威胁分析等,团队成员均来自行业具备多年实战攻防经验的红队、蓝队和紫队专家。本着以攻促防的核心理念,通过落地ATT&CK攻防全景知识库,全面构建实战化、常态化、体系化的企业安全建设与运营。
概述
进程注入是一种在活动进程的地址空间中执行任意代码的方法。在另一进程的上下文中运行代码能允许访问该进程的內存、系统网络资源以及提升权限。同时进程注入是很多恶意软件均使用到的防御绕过手法,这次我们根据ATT&CK防御绕过战术中来探究每种注入手法,这篇文章会先浅析该注入手法的原理并列出对应ATT&CK子项,然后使用其上线CS免杀情况(360windows defender),最后根据数据源进行检测并结合sysmon view进行展示。
在T1055战术中的Windows注入演变出越来越多得方式,但相关的API调用可以总结为下图:
图源:https://muchangfeng.gitbook.io
文章会先介绍T1055中的相关注入,然后再介绍未包含再T1055中的手法,若文章有不对的地方,望师傅指出,谢谢大家。
T1055注入浅析及免杀测试
2.1 经典注入 (T1055.001 02):
2.1.1 简介
经典注入的方式分别对应ATT&CK的T1055.001与T1055.002,其区别就是前者(001)使用dll落盘使用loadlibrary加载:
而后者(002)dll不落盘而在内存加载(可以结合反射注入或者自加载实现),如有引导头可以不用计算导出函数的偏移,直接传入所分配的地址:
其两者的流程是一样的:
NtOpenProcess获得目标进程句柄
NtAllocateVirtualMemory在目标进程创建内存空间 NtWriteVirtualMemory 在所分配的内存空间写入payloadNtCreateThreadEx创建线程执行。
总体的调用流程如下图所示:
2.1.2 杀软测试
2.1.3 检测:
T1055.001可以通过数据源DS0011(模块)与DS0009(进程)进行检测,而T1055.002少调用了Loadlibrary函数只有通过DS0009(进程)去检测,我们可以通过其调用链(Process Create 启动进程 Process Accessed 获得句柄CreateRemoteThread注入)比较直观的看到其行为:
2.2 线程劫持注入 (T1055.003):
2.2.1 简介
线程劫持注入(挂起线程注入)对应T1055.003,其流程开始部分也是与经典注入类似,其主要原理是通过OpenProcess获得目标进程句柄并找到主线程后,将其挂起,然后通过VirtualAllocEx写入payload,最后恢复主线程的执行。
前面获得句柄的操作与2.2经典注入一样,差异部分在于通过获得目标进程的主线程并将其暂停,如下图:
接着调用SetThreadContext设置eiprip指向payload的地址,最后ResumeThread恢复主线程执行payload:
其总体调用流程如下图:
2.2.2 杀软测试
360、windows defender测试:
挂起线程注入,如果不在注入主线程并执行代码后重新跳回主线程,则会导致进程崩溃,所以不能直接使用cs的shellcode,可以编写新建线程的shellcode并压入返回地址,再一同注入进程并通过createthread执行相应的shellcode。
2.2.3检测:
T1055.003根据ATT&CK上的检测只能通过DS0009(过程)进行检测,主要通过HOOK系统API,流程修改(Sysmon ID8),进程访问(Sysmon ID 10):
2.3 APC注入(T1055.004):
2.3.1简介
APC(异步过程调用)注入对应T1055.004,异步过程调用是一种在特定线程环境中异步执行的系统机制。APC有两种形式,由系统产生的APC称为内核层APC,由应用程序产生的APC被称为用户层APC。APC是往线程中插入一个回调函数,当程序调用SleepEx、signalObjectAndWait、WaitForSingleObjecsEx等函数时会调用所插入的回调函数。
用户层APC有两种注入方式实现,第一种是创建当前系统线程快照,经遍历后通过NtOpenThread获取目标进程的主线程句柄:
然后调用NtSuspendThread挂起该进程—> NtQueueApcThread往APC队列插入回调的函数地址和参数 NtAlertResumeThread 恢复挂起的线程运行。
其总体调用流程如下图:
而另一种方式(early bird)是先以挂起的方式CREATE_SUSPENDED创建进程,获得所创建进程的主线程句柄:
然后与2.1经典注入的方式类似: NtAllocateVirtualMemory在目标进程创建内存空间 NtWriteVirtualMemory 在所分配的内存空间写入payload。
在写入payload后调用NtQueueApcThread往APC队列插入payload的执行地址 NtAlertResumeThread 恢复挂起的线程运行。
其总体调用流程如下图:
2.3.2杀软检测
360:
Windows defender:
2.3.3 检测:
T1055.004根据ATT&CK上的检测只能通过DS0009(过程)进行检测,主要通过HOOK系统API,流程修改(Sysmon ID8),进程访问(Sysmon ID 10):
2.4 TLS线程(T1055.005):
2.4.1 简介
TLS线程局部存储注入对应T1055.005,线程本地存储意思是每一个线程在使用全局变量的时候都产生一个只属于本线程的副本,这样我们就可以直接使用这个副本,而不会影响到其他线程。TLS有分为静态TLS与动态TLS,静态TLS较常用到,需先定义一个回调函数,该函数会在程序初始化会调用(比main函数更早执行,可用作反调试手段):
在PE结构里的NT头可以看到TLS的位置:
同样可以在IDA看到TlsCallback的函数指针:
在TLS中可以直接执行shellcode,也可以结合其他手段(进程镂空、经典注入等)注入相关进程中。
在TLS中需配合其他注入的方法如傀儡进程等,才能达到注入其他程序的效果。
2.4.2 杀软测试
如果使用TLS注入其他进程需要跟其他手法结合,下面是360和WD的测试,360能正常上线:
WD报TurtleLoader:
2.4.3检测
因为TLS能跟其他方式相结合,所以需结合实际所使用到的注入方式进行检测。
2.5 Process-Hollowing (T1055.0012):
2.5.1 简介
Process-Hollowing(傀儡进程、进程镂空)对应T1055.0012,主要原理是创建一个挂起状态的进程,然后取消该进程的内存映射,并替换成恶意payload,最后恢复该进程的运行状态。其写法有比较复杂的也较为有简单的,主要区别有是否使用
NtUnmapViewOfSection清空原有进程的section、当程序映射的基址不同时的重定位处理、是否调用NtQueryInformationProcess查找PEB。
其流程是先通过CREATE_SUSPENDED标志位创建挂起的进程:
然后找所创建程序的PEB,这里有两种方式可以找到PEB,一是通过程序挂起时的ebx(rdx)找到 TIB再通过偏移找到PEB:
第二种是通过NtQueryInformationProcess找到所创建程序的PEB:
接着使用NtUnmapViewOfSection清空原有进程的section,这步不是必须的:
之后使用VirtualAllocEx相关api在子进程申请空间,然后将payload的头及每个节复制到子进程中,并若payload的基址和子进程的基址不相等则重定位处理:
最后通过计算对应入口点并设置回eax(rcx),ResumeThread恢复线程运行:
其总体调用流程如下图:
2.5.2 杀软测试
360:
Windows defender:
2.5.3 检测:
T1055.0124根据ATT&CK上的检测只能通过DS0009(过程)进行检测,同样主要通过HOOK系统API,流程修改(Sysmon ID8),进程访问(Sysmon ID 10):
2.6 Process doppelganging (T1055.0013)
2.6.1 简介
Process doppelganging(进程分身),在近几年提出的注入手法,其主要原理是:通过NtCreateTransaction函数创建一个事务句柄,再传入事务句柄去CreateFileTransactedW创建一个文件流句柄,然后通过writefile往文件流句柄写入数据,接着通过传入文件流句柄调用NtCreateSection获得section,最后调用NtRollbackTransaction回滚:
通过获得该section传入NtCreateProcess()创建进程,然后修改该进程的ProcessParameters和Environment
最后计算入口并传入NtCreateThreadEx()创建线程执行。
总体流程:
其它的注入手法
3.1全局钩子注入 (T1056.001)
3.1.1简介
Windows大部分程序是基于消息机制的,有一个消息过程函数,根据不同得消息完成不同的功能。Windows操作系统提供的钩子基址就是用来截获和监视系统中的不同消息。根据范围不同,可以分为全局钩子和局部钩子。全局钩子是作用于整个系统的基于消息的应用。当安装全局钩子后,只要进程接收到可以发出钩子的消息,全局钩子就有操作系统加载到该进程中,达到注入DLL的目的。
程序设置WH_GETMESSAGE消息的全局钩子,因为其类型的钩子会监视消息队列,windows进程都有一个自己的消息队列,都会加载WH_GETMESSAGE类型的全局钩子DLL。
3.1.2 免杀测试
Windows defender虽可以执行的,但会被提示上传分析。
3.1.3 检测
可以通过监控Windows API 的调用(例如SetWindowsHook
GetKeyState和GetAsyncKeyState)进行检测。
3.2 注册表相关的注入(T1546)
3.2.1AppInit_DLL(T1546.010)
在注册表中存在以下两项,计算机HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindows NTCurrentVersionWindows的AppInit_DLLs键值为DLL的路径,LoadAppInit_DLL的键值为1。
当User32.dll被加载到进程时,会读取AppInit_DLLs注册表项,如果有值,调用LoadLibrary()加载所设置的dll。另外此dll注入不是注入到所有运行进程,而是注入到所加载User32.dll的进程中。
3.2.2 AppCertDlls(T1546.009)
当攻击者在注册表中HKEY_LOCAL_MACHINESystemCurrentControlSetControlSession Manager设置了DLL路径,那么使用CreateProcess,CreateProcessAsUser,CreateProcessWithLoginW,CreateProcessWithTokenW或WinExec等函数所创建的程序将会加载其DLL。
3.2.3 IFEO(T1546.012)
映像劫持是通过篡了注册表HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindows NTCurrentVersionImage File Execution Options中的键值实现的,例如这里有notepad.exe项,再在这子项里新建一个REG_SZ类型的名字为Debugger键,内容为cmd.exe的值项。这样就轻易的实现映像劫持,当每次运行notepad.exe时都会运行cmd.exe程序。
3.2.4 免杀测试
Windows defender对上述几个修改注册表的动作是不会有提示的,但是360安全大脑会有类似下面提示,其实是可以绕过360安全大脑进行添加的:
3.2.5 检测
AppInit_DLL(T1546.010)和AppCertDlls(T1546.009)根据ATT&CK上的检测可以通过DS0017(命令)、DS0011(模块)、DS0009(过程)、DS0024(注册表)进行检测,而IFEO T1546.012只能通过DS0017(命令)、DS0009(过程)、DS0024(注册表)进行检测:
3.3Transacted Hollowing
3.3.1简介
近来也出现了一些经改良注入手法如Transacted Hollowing和Process Ghosting、Process Herpaderping等。前者(Transacted Hollowing)是Process Hollowing和Process Doppelganging结合的产物,它一开始是像Process doppelganging那样通过TxF不落地创建IMAGE Section,然后将该Section映射到通过挂起创建傀儡进程中,并不是像Process Hollowing那样调用调用writeprocessmemory将每个节写入:
使用NtMapViewOfSection会在映射image section时,会尝试映射到imagebase,所以不需要做重定位,然后重新设置入口点RcxEax再ResumeThread()恢复线程,后面的流程跟Process Hollowing手法一致。
Transacted Hollowing总体流程:
3.4Process Ghosting
3.4.1简介
Process Ghosting只是通过设置FILE_DISPOSITION_INFORMATION.DeleteFile = TRUE实现近似不落地创建image section,因为该标志是windows deletefile时所设置的:
然后通过该section句柄传入NtCreateProcessEx来创建进程,最后与Process Doppelganging类似均要修改PEB等信息,并创建线程执行:
Process Ghosting总体流程:
3.5 自加载手法
3.5.1简介
关于PE加载手法有比较常见的如MemoryMoudle、RDI(T1620)、DarkLoadLibrary,其实原理也是类似的,下面以RDI(T1620)为例,主要分为下面几个步骤:
1.获取所加载image 的基址。
2.通过查询Kernel32动态库,找到LoadLibraryA,GetProcAddress,VirtualAlloc的地址。
3. 通过VirtualAlloc分配的内存用于加载Dll.
4.将Header和 sections 复制到分配的内存区域。
5.修复导入表
6.修复重定位表
7.调用DLL入口点
3.5.2检测
关于检测反射注入T1620有三个方面的数据源:DS0011模块加载、DS0009API执行、DS0012脚本执行,在实际中可以对相应反射加载的函数进行监视,如CreateThread()、Assembly.Load()等,同时对导出函数名字进行标记,分析判断异常的父子进程及正常进程进程的异常行为等。
小结
这次我们通过ATT&CK中的战术内容梳理出windows相关的注入手法,测试其杀软绕过,并根据其数据源做出检测。谢谢大家观看。
RECRUITMENT
招聘启事
END
长按识别二维码关注我们
原文始发于微信公众号(雷神众测):ATT&CK-防御绕过之进程注入攻防分析