0x00 每周蓝军技术推送(2022.5.14-5.20)
0x01 PPID Spoofing & BlockDLLs with NtCreateUserProcess
在这篇文章中,作者介绍了如何使用
NtCreateUserProcess
这一个未被官方文档化的API函数,NtCreateUserProcess函数是CreateProcessA(W)的底层实现。可以规避部分EDR的检测。作者的灵感来源是来自Capt. Meelo的Making NtCreateUserProcess Work一文,NtCreateUserProcess的函数原型如下:
123456789101112131415NTSTATUSNTAPINtCreateUserProcess(_Out_ PHANDLE ProcessHandle,_Out_ PHANDLE ThreadHandle,_In_ ACCESS_MASK ProcessDesiredAccess,_In_ ACCESS_MASK ThreadDesiredAccess,_In_opt_ POBJECT_ATTRIBUTES ProcessObjectAttributes,_In_opt_ POBJECT_ATTRIBUTES ThreadObjectAttributes,_In_ ULONG ProcessFlags,_In_ ULONG ThreadFlags,_In_ PRTL_USER_PROCESS_PARAMETERS ProcessParameters,_Inout_ PPS_CREATE_INFO CreateInfo,_In_ PPS_ATTRIBUTE_LIST AttributeList);ProcessHandle
和ThreadHandle
分别是需要传出的进程和线程句柄,可以为NULL。
ProcessDesiredAccess
和ThreadDesiredAccess
是进程和线程访问权限掩码。可以直接为PROCESS_ALL_ACCESS和THREAD_ALL_ACCESS,具体可以参见以下文档,ProcessObjectAttributes
和ThreadObjectAttributes
是进程和线程对象属性,指向OBJECT_ATTRIBUTES结构,此处可以为NULL
ProcessFlags
和ThreadFlags
是进程线程标志,Meelo是查看ProcessHack源码获得的,此处可以为NULLProcessParameters
是进程参数信息,指向的是RTL_USER_PROCESS_PARAMETERS
结构,通过逆向CreateProcessA函数,可以发现使用RtlCreateProcessParametersEx
进行初始化1234UNICODE_STRING NtImagePath;RtlInitUnicodeString(&NtImagePath, (PWSTR)L"\\??\\C:\\Windows\\System32\\mmc.exe");PRTL_USER_PROCESS_PARAMETERS ProcessParameters = NULL;RtlCreateProcessParametersEx(&ProcessParameters, &NtImagePath, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, RTL_USER_PROCESS_PARAMETERS_NORMALIZED);CreateInfo是一个指向
PS_CREATE_INFO
结构的指针,对于PS_CREATE_INFO结构的初始化也很简单。1234// process create infoPS_CREATE_INFO CreateInfo = { 0 };CreateInfo.Size = sizeof(CreateInfo);CreateInfo.State = PsCreateInitialState;最后一个参数是
AttributeList
,AttributeList指向的是PPS_ATTRIBUTE_LIST结构体,这是一个链表结构,可以通过RtlAllocateHeap函数自主申请链表的大小。在第一个节点中,必须要添加PS_ATTRIBUTE_IMAGE_NAME(进程映像名)这个属性。12345typedef struct _PS_ATTRIBUTE_LIST{SIZE_T TotalLength; // sizeof(PS_ATTRIBUTE_LIST)PS_ATTRIBUTE Attributes[2]; // Depends on how many attribute entries should be supplied to NtCreateUserProcess} PS_ATTRIBUTE_LIST, * PPS_ATTRIBUTE_LIST;
|
|
作者在这篇文章中主要实现了两个功能,一个是PPID Spoofing,也就是父进程欺骗,另外一个是BlockDLLs,BlockDLLs简单的来说就是阻止一些非可信的DLL模块加载到进程中。
进程隐藏可以通过设置进程的Attribute即可,具体操作如下,将进程的PS_ATTRIBUTE_PARENT_PROCESS(父进程)属性设置为指定的父进程的Handle即可。:
1234// add parent process attributeAttributeList->Attributes[1].Attribute = PS_ATTRIBUTE_PARENT_PROCESS;AttributeList->Attributes[1].Size = sizeof(HANDLE);AttributeList->Attributes[1].ValuePtr = hParent;BlockDLLs允许系统根据不同的策略加载不同安全等级的Dll文件,因为一些安全软件会通过往进程中加载dll来进行行为监控,利用这个特性就可以阻止非windows的dll加载,包括安全软件的dll。这里可以看到完整的BlockDlls的介绍,主要有两种方法。
通过
SetProcessMitigationPolicy
函数设置阻止策略。123PROCESS_MITIGATION_BINARY_SIGNATURE_POLICY policy;policy.MitigationOptIn = 1;SetProcessMitigationPolicy(ProcessSignaturePolicy, &policy, sizeof(policy))通过UpdateProcThreadAttribute修改线程属性。
12DWORD64 ProtectionLevel = PROCESS_CREATION_MITIGATION_POLICY_BLOCK_NON_MICROSOFT_BINARIES_ALWAYS_ON; //policy.MitigationOptInUpdateProcThreadAttribute(si.lpAttributeList, 0, PROC_THREAD_ATTRIBUTE_MITIGATION_POLICY, &ProtectionLevel, sizeof(ProtectionLevel), NULL, NULL)
|
|
0x02 Windows环境下的自保护探究
- 这篇文章作者的思路是这样的,在kill 杀软进程的时候,会使用OpenProcess打开杀软进程,在OPenProcessAPI函数底层呢,会调用ObRegisterCallbacks注册回调函数,所以作者的目的就是通过注册回调函数,首先判断当前进程ID是否是杀软自身的PID,如果是的话,则去除Kill进程的权限。1OperationInformation->Parameters->CreateHandleInformation.DesiredAccess &= ~PROCESS_TERMINATE;