- 本文主要总结了几种不太常见的高级注入技术
- Module Stomping(LoadLibrary)
- Module Stomping(NtMapViewOfSection)
- AtomBombing
- Process Hollowing
- Process Doppelgänging
- Transacted Hollowing
- Process Ghosting等
0x01 Module Stomping(LoadLibrary)
- Module Stomping 模块踩踏,通过加载一个合法的Dll模块,然后使用payload去覆盖dll
- 优点:
- 1) 有效载荷映射为 MEM_IMAGE,对于 EXE 或 DLL 来说看起来是合法的
- 2)使用原始访问权限映射的部分(无RWX)
- 3)冒充合法的Dll(进程模块界面无法检出)
- 步骤:
- 1)调用
LoadLibrary
函数加载合法dll,并得到基地址 - 2)调用
LoadLibrary
函数或者NtMapViewOfSection
获取非法dll,并得到基地址 - 3)调用
memset
将合法dll的内存区域清空,并将非法dll内存复制到合法dll内存 - 4) 根据pe信息,获取非法dll(覆盖后)的入口点
- 5)根据入口点执行
- 1)调用
- https://github.com/Hagrid29/PELoader
0x02 Module Stomping(NtMapViewOfSection)
- 通过
NtMapViewOfSection
函数为dll创建一个内存映射,然后使用payload覆盖dll - 优点:
- 1) Module Stomping(LoadLibrary)全部
- 2) 未连接到模块列表(对于Module32First/Module32Next 不可见)
- 步骤:
- 1) 调用
NtMapViewOfSection
函数加载合法dll,并得到基地址 - 2)调用
LoadLibrary
函数或者NtMapViewOfSection
获取非法dll,并得到基地址 - 3)调用
memset
将合法dll的内存区域清空,并将非法dll内存复制到合法dll内存 - 4) 根据pe信息,获取非法dll(覆盖后)的入口点
- 5)根据入口点执行
- 1) 调用
- https://github.com/Hagrid29/PELoader
- https://github.com/hasherezade/module_overloading
0x03 GhostWriting
- 1) 通过
GetShellWindows
+GetWindowThreadProcessId
+OpenThread
获得explorer.exe的线程句柄 2) 搜索ntdll代码段的指定的汇编指令
12345678MOV [REG1],REG2RET//orMOV [REG1],REG2POP REGxPOP REGx...RET
0x04 AtomBombing
- AtomBombing通过利用APC异步过程调用以及windows原子表(atom tables)实现的高级代码注入
AtomBombing主要实施x个阶段的工作
- 1) 寻找一个处于警告状态的线程,因为APC注入需要一个处于Alertable状态的线程
- 2) 构造一个ROP链【重点】
- 3) 通过APC结合windows atom表,代替WriteProcessMemory的功能
- 4)通过SetThreadContext和ResumeThread执行ShellCode
Step1:将ShellCode写入远程进程
- Tal Liberman发现
GlobalAddAtom
和GlobalGetAtomName
代替WriteProcessMemory将Shellcode写入目标进程,通过调用GlobalAddAtom
将ShellCode保存在全局原子表中,目标进程可以通过GlobalGetAtomName
读取该表中的Shellcode。 - 现在问题就是如何使得目标进程调用
GlobalGetAtomName
,通过APC异步过程调用的方式,使远程进程主动调用GlobalGetAtomName
获取ShellCode。
- Tal Liberman发现
Step2:保存并执行ShellCode
- 目标进程保存执行Shellcode主要有两种方法:
- 1) 寻找一段具有RWX的内存,这个可以通过Hook一个导出函数实现
- 2) 调用VirtualAllocEx分配一段内存
- Tal Liberman创造性的使用ROP链执行ShellCode,主要分3步:
- 1)申请RWX内存
- 2)将从
GlobalGetAtomName
获取的Shellcode拷贝到RWX内存 - 3)执行123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172//ROP链typedef struct _ROPCHAIN{// Return address of MemcpyPVOID pvMemcpy;//// Params for ntdll!ZwAllocateMemoryHANDLE ZwAllocateMemoryhProcess;PVOID ZwAllocateMemoryBaseAddress;ULONG_PTR ZwAllocateMemoryZeroBits;PSIZE_T ZwAllocateMemoryRegionSize;ULONG ZwAllocateMemoryAllocationType;ULONG ZwAllocateMemoryProtect;////ret这个指令PVOID pvRetGadget;//// Params for ntdll!memcpyPVOID MemcpyDestination;PVOID MemcpySource;SIZE_T MemcpyLength;} ROPCHAIN, *PROPCHAIN;//构建ROP链函数ESTATUS main_BuildROPChain(PVOID pvROPLocation,PVOID pvShellcodeLocation,PROPCHAIN ptRopChain){ESTATUS eReturn = ESTATUS_INVALID;ROPCHAIN tRopChain = { 0 };// Params for ntdll!ZwAllocateMemorytRopChain.ZwAllocateMemoryhProcess = GetCurrentProcess();tRopChain.ZwAllocateMemoryBaseAddress = (PUCHAR)pvROPLocation + FIELD_OFFSET(ROPCHAIN,MemcpyDestination);tRopChain.ZwAllocateMemoryZeroBits = NULL;tRopChain.ZwAllocateMemoryRegionSize = (PSIZE_T)((PUCHAR)pvROPLocation + FIELD_OFFSET(ROPCHAIN,MemcpyLength));tRopChain.ZwAllocateMemoryAllocationType = MEM_COMMIT;tRopChain.ZwAllocateMemoryProtect = PAGE_EXECUTE_READWRITE;// Params for ntdll!ZwAllocateMemorytRopChain.MemcpyDestination = (PVOID)0x00;tRopChain.MemcpySource = pvShellcodeLocation;tRopChain.MemcpyLength = sizeof(SHELLCODE);//address of ntdll!memcpyeReturn = GetFunctionAddressFromDll(NTDLL,MEMCPY,&tRopChain.pvMemcpy);if (ESTATUS_FAILED(eReturn)){goto lblCleanup;}printf("ntdll!memcpy: 0x%X", tRopChain.pvMemcpy);//寻找Ret指令的字节码eReturn = main_FindRetGadget(&tRopChain.pvRetGadget);if (ESTATUS_FAILED(eReturn)){goto lblCleanup;}eReturn = ESTATUS_SUCCESS;*ptRopChain = tRopChain;//lblCleanup://return eReturn;}
- 目标进程保存执行Shellcode主要有两种方法:
Step3:执行ShellCode
AtomBombing技术是通过SetThreadContext将EIP设置为ZwAllocateVirtualMemory,然后将ESP设置为ROP链实现Shellcode执行的。方法非常巧妙,以下必须要结合ROP链结构体_ROPCHAIN阅读。
1234567//将线程的EIP设置为ZwAllocateVirtualMemorytContext.Eip = (DWORD) GetProcAddress(GetModuleHandleA("ntdll.dll"), "ZwAllocateVirtualMemory");tContext.Ebp = (DWORD)(PUCHAR)pvRemoteROPChainAddress;tContext.Esp = (DWORD)(PUCHAR)pvRemoteROPChainAddress;//首先执行ZwAllocateVirtualMemory,根据堆栈关系最终执行ShellCodeprintf("[*] Hijacking the remote thread to execute the shellcode (by executing the ROP chain).\n\n\n");eReturn = main_ApcSetThreadContext(hProcess, hAlertableThread, &tContext, pvRemoteContextAddress);1) 执行
ZwAllocateVirtualMemory
,根据上文的_ROPCHAIN结构体ROP链,此时栈顶保存的是memcpy
的地址,接下来是ZwAllocateVirtualMemory
的参数- 2)执行
ZwAllocateVirtualMemory
完成后,因为栈顶是memcpy
地址,ret后,执行流指向memcpy。此时栈顶保存的是搜索到的ret
这个指令的地址,然后是memcpy的参数 - 3)执行完ret之后,根据栈的信息,执行流指向ShellCode,此时完成注入
AtomBombing – A Brand New Code Injection Technique for Windows
- https://github.com/BreakingMalwareResearch/atom-bombing
- AtomBombing利用分析
0x05 Process Hollowing
- 1) CreateProcess(“svchost.exe”, …, CREATE_SUSPENDED, …);
- 2) NtUnmapViewOfSection(…);
- 3)VirtualAllocEx(…);
- 4) For each section{WriteProcessMemory(…, EVIL_EXE, …);}
- 5) Relocate Image*
- 6) Set base address in PEB*/PE
- 7) SetThreadContext(…);
- 8) ResumeThread(…);
0x06 Process Doppelgänging
Process Doppelgänging其本质是利用TxF的回滚特性,将恶意载荷通过Section创建创建,并根据回滚特性恢复原样的一个技术,关注Process Doppelgänging技术细节之前,首先应该关注
NtCreateProcessEx
函数。该函数第6个参数是一个SectionHandle句柄。该句柄来自于transacted file
1234567891011NTSTATUSNTAPINtCreateProcessEx(OUT PHANDLE ProcessHandle,IN ACCESS_MASK DesiredAccess,IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,IN HANDLE ParentProcess,IN ULONG Flags,IN HANDLE SectionHandle OPTIONAL,IN HANDLE DebugPort OPTIONAL,IN HANDLE ExceptionPort OPTIONAL,IN BOOLEAN InJob)原理流程,以下过程第一步在验证概念中没有显示
- 1) 先用恶意程序写覆盖白程序
- 2)然后将覆盖后的文件加载到内存
- 3)加载完成后回滚磁盘上的文件为写覆盖之前的文件
- 4)最后利用(2)加载到内存中的Section创建进程,最终达到执行恶意程序并绕过杀软检查的目的。
实现过程
1)调用
NtCreateTransaction
创建transaction12345678910111213//The ZwCreateTransaction routine creates a transaction object.__kernel_entry NTSYSCALLAPI NTSTATUS NtCreateTransaction([out] PHANDLE TransactionHandle,[in] ACCESS_MASK DesiredAccess,[in, optional] POBJECT_ATTRIBUTES ObjectAttributes,[in, optional] LPGUID Uow,[in, optional] HANDLE TmHandle,[in, optional] ULONG CreateOptions,[in, optional] ULONG IsolationLevel,[in, optional] ULONG IsolationFlags,[in, optional] PLARGE_INTEGER Timeout,[in, optional] PUNICODE_STRING Description);2) 调用
CreateFileTransacted
,WriteFile
和NtCreateSection
等在这个transaction内填入payload3)调用
NtRollbackTransaction
设置事务回滚12345//The ZwRollbackTransaction routine initiates a rollback operation for a specified transaction.__kernel_entry NTSYSCALLAPI NTSTATUS NtRollbackTransaction([in] HANDLE TransactionHandle,[in] BOOLEAN Wait);4) 调用
NtCreateProcessEx
和RtlCreateProcessParametersEx
以内存Section创建进程。- 5)根据PEB读取入口点,调用
NtCreateThreadEx
执行入口点函数
弱点:最终还是要依赖
NtCreateThreadEx
- Process-Doppelganging利用介绍
- https://github.com/3gstudent/Inject-dll-by-Process-Doppelganging/blob/master/inject.c
0x07 Transacted Hollowing
- Transacted Hollowing是一种集合了
Process Hollowing
和Process Doppelgänging
之间的混合体。 - 1) 首先使用
Process Doppelgänging
中的NTFS函数得到一个Section
- 1) CreateTransaction
- 2) CreateFileTransactedW
- 3) NtCreateSection
- 4) RollbackTransaction
2) 然后以挂起方式创建目标进程
12345678910111213CreateProcessInternalW(hToken,NULL, //lpApplicationName(LPWSTR)cmdLine, //lpCommandLineNULL, //lpProcessAttributesNULL, //lpThreadAttributesFALSE, //bInheritHandlesCREATE_SUSPENDED | DETACHED_PROCESS | CREATE_NO_WINDOW, //dwCreationFlagsNULL, //lpEnvironmentstartDir, //lpCurrentDirectory)3) 类似Process Hollowing,使用
NtMapViewOfSection
将Section映射入挂起的进程4)通过Wow64GetThreadContext/Wow64SetThreadContext设置入口点
https://github.com/hasherezade/transacted_hollowing/blob/main/main.cpp
- https://www.freebuf.com/articles/system/181971.html
0x08 Process Ghosting
现代Windows创建进程的基本流程是这样的:
- 1)打开可执行文件,获取文件句柄
hFile = CreateFile(“C:\Windows\System32\svchost.exe”)
- 2) 为文件创建映像,即将文件部分内容映射入内存
hSection = NtCreateSection(hFile, SEC_IMAGE)
- 3) 使用映像部分创建一个进程,hProcess = NtCreateProcessEx(hSection)
- 4) 为进程设置环境变量
- 5)为进程创建一个主线程NtCreateThreadEx
- 1)打开可执行文件,获取文件句柄
Process Ghosting,顾名思义,进程是一个幽灵一般,没有实体部分。即没有文件。
windows中删除文件的方法(并不是实际上的Del)
- 1)使用
CreateFile/NtOpenFile
创建文件的时候,将OpenOptions
设置为FILE_DELETE_ON_CLOSE
,FILE_SUPERSEDE
,FILE_FLAG_DELETE_ON_CLOSE
- 2) 当通过NtSetInformationFile调用FileDispositionInformation文件信息类时,将FILE_DISPOSITION_INFORMATION结构中的 DeleteFile 字段设置为 TRUE 。
- 1)使用
但是,只有当Section映射入进程,并关闭句柄,删除标志才能生效。
攻击流程:
- 1)创建一个文件
- 2)使用NtSetInformationFile(FileDispositionInformation)将文件置于删除挂起状态。注意:尝试使用 FILE_DELETE_ON_CLOSE 不会删除文件。
- 3)将负载可执行文件写入文件。内容不会保留,因为文件已处于删除挂起状态。删除挂起状态还会阻止外部文件打开尝试。
- 4)为文件创建图像部分。
- 5)关闭删除挂起句柄,删除文件。
- 6)使用图像部分创建一个进程。
- 7)分配流程参数和环境变量。
- 8)创建一个线程在进程中执行。
和
Process Doppelgänging技术
本质上都是将文件进行删除,Process Ghosting
利用文件删除标志实现,而Process Doppelgänging技术
是利用NTFS的回滚机制- hat you need to know about Process Ghosting, a new executable image tampering attack
0x09 Ghostly Hollowing
- Ghostly Hollowing是Process Ghosting技术的结合。
- https://github.com/hasherezade/transacted_hollowing/
- https://github.com/Hagrid29/herpaderply_hollowing/blob/main/README.md
0x10 Process Herpaderping
背景:基于现有安全软件更高效的检测恶意软件,在程序运行期间提供了两层保护
- 利用PsSetCreateProcessNotifyRoutinsEx回调函数,该回调函数在进程通过NtThreadEx创建主线程的时候被调用。该回调函数针对磁盘文件进行检测,但是在回调函数被调用之前,可以通过修改磁盘文件内容,从而规避这种检测。
- 利用驱动程序在接收到IRP_MJ_CLEANUP(对应关闭文件句柄)时,检查文件内容是否发生改变。
原理:综上描述,安全软件在进程创建主线程之后触发PsSetCreateProcessNotifyRoutinsEx回调函数进行检查,但是在之前对磁盘文件进行修改,修改为一个正常的文件,安全软件会认为进程是一个正常文件映射的,从而绕过检查。
步骤:
- 1)将二级制文件payload写入磁盘,并获取文件句柄
- 2)将文件映射入内存
- 3)使用映像部分创建一个进程,hProcess = NtCreateProcessEx(hSection)
- 4)使用1)中的文件句柄,修改文件,此时为正常文件。此时安全软件的文件检查得以绕过
- 5)创建进程的主线程
- https://www.4hou.com/posts/qDzy
- Process Herpaderping Technical Deep Dive
- 从Herpaderping规避技术看防御之难
- 高级进程注入总结
0x11 Herpaderply Hollowing
Herpaderply Hollowing是
Process Hollowing
和Process Herpaderping
的混合体。
步骤:
- 1)将二级制文件payload写入磁盘,并获取文件句柄
- 2)将文件映射入内存
- 3)使用映像部分创建一个进程,hProcess = NtCreateProcessEx(hSection)
- 4)使用1)中的文件句柄,修改文件,此时为正常文件。此时安全软件的文件检查得以绕过
- 5)以挂起方式创建进程
- 6)将Section映射入挂起的进程
- 7)运行payload
0x12 Process Lockering
- 步骤:
- 1)读取payload
- 2)将payload写入一个另外一个空文件,用于Lock。
- 3)通过
DuplicateHandle
复制一个文件句柄,并返回新文件的句柄,此时文件处于锁定状态 - 4)通过3)中获取的文件句柄,创建一个新的section
- 5)通过NtCreateProcessEx(HSection)创建进程
- 6)通过PEB寻找入口点,执行payload
0x13 Locker Hollowing
- Locker Hollowing 是 Process Hollowing 和 Process Lockering 的混合体。
- https://github.com/Hagrid29/herpaderply_hollowing