前置知识
免杀马的实现就是将shellcode加密、shellcode加载器、反沙箱及编译器编译等几种技术组合在一起实现免杀
前面一篇文章讲了shellcode加密、shellcode加载器、反沙箱以及简单讲了以下编译器编译,在选择编译器时VS还是g++?
选择g++,因为g++编译的空包exe比VS编译低两个数量级。但除了编译器选择还有编译器应该如何编译 —— 编译器编译命令,编译器编译命令也是一个很大的影响因数
免杀实验
首先使用charGPT
写个冒泡排序
这是一段完全无害的代码,如果报毒,那么绝对是编译的问题,分别用VS
与g++
编译这一段代码上传VT
,看看VT
报毒情况
VS编译:
g++编译:
g++ scl2.cpp -o scl.exe -mconsole
可以看到g++
编译的命令要比VS
低很多,后面继续用g++
编译这一段代码,不同的是不断改变g++
的编译命令
先测试一些常见的命令
g++ scl2.cpp -o scl.exe -mconsole -pipe
g++ scl2.cpp -o scl.exe -mconsole -time
g++ scl2.cpp -o scl.exe -mconsole -s
一些参数还可能会导致报毒变多,-s
参数就是一个很典型的例子,6
个报毒
g++ scl2.cpp -o scl.exe -mconsole -pie
-pie
参数编译后运行没有反应,跳过
g++ scl2.cpp -o scl.exe -mconsole -shared
-shared
参数编译后运行无法运行,跳过
--target-help
下面还有几百个参数
我试了一些不是没有变化就是不能运行或是不会用,这个时候我想到了chargpt
,这种时候用chargpt
就是很合适了
-s
参数用于剥离可执行文件中的符号表,这样可以使反汇编变得更困难,也可以减少程序被误判为恶意程序的概率。-fno-stack-protector
参数可以禁用堆栈保护机制,这样可以减少杀软对程序的误报。-fvisibility=hidden
参数可以隐藏编译出的符号表,这也可以使反汇编变得更困难。-Wl,--dynamicbase -Wl,--nxcompat
参数可以启用程序地址空间随机化和数据执行保护,这可以提高程序的安全性,同时也可以减少杀软的误报
前面第一个-s
,前面试过了,6个报毒,直接舍弃。试试后面的4个
g++ scl.cpp -o scl.exe -mconsole -fno-stack-protector
1个报毒
g++ scl.cpp -o scl.exe -mconsole -fno-stack-protector -fvisibility=hidden
1个报毒
g++ scl.cpp -o scl.exe -mconsole -fno-stack-protector -fvisibility=hidden -Wl,--dynamicbase
1个报毒
g++ scl.cpp -o scl.exe -mconsole -fno-stack-protector -fvisibility=hidden -Wl,--dynamicbase -Wl,--nxcompat
0个报毒
补充
g++ scl2.cpp -o scl.exe -mconsole -Wl,--nxcompat
单独使用-Wl,--nxcompat
参数还是会导致报毒
实验结论
在代码确定免杀的情况下报毒,是编译的问题。使用g++
编译时-s
参数会导致报毒增多(6/71)
-fno-stack-protector -fvisibility=hidden -Wl,--dynamicbase -Wl,--nxcompat
连在一起使用可减少报毒(0/71)
g++ scl2.cpp -o scl.exe -mconsole -fno-stack-protector -fvisibility=hidden -Wl,--dynamicbase -Wl,--nxcompat