前置知识

免杀马的实现就是将shellcode加密、shellcode加载器、反沙箱及编译器编译等几种技术组合在一起实现免杀

前面一篇文章讲了shellcode加密、shellcode加载器、反沙箱以及简单讲了以下编译器编译,在选择编译器时VS还是g++?

选择g++,因为g++编译的空包exe比VS编译低两个数量级。但除了编译器选择还有编译器应该如何编译 —— 编译器编译命令,编译器编译命令也是一个很大的影响因数

免杀实验

首先使用charGPT写个冒泡排序

g++编译实现VT全免杀_符号表

这是一段完全无害的代码,如果报毒,那么绝对是编译的问题,分别用VSg++编译这一段代码上传VT,看看VT报毒情况

VS编译:

g++编译实现VT全免杀_符号表_02

g++编译:

g++ scl2.cpp -o scl.exe -mconsole

g++编译实现VT全免杀_符号表_03

可以看到g++编译的命令要比VS低很多,后面继续用g++编译这一段代码,不同的是不断改变g++的编译命令

先测试一些常见的命令

g++编译实现VT全免杀_符号表_04

g++ scl2.cpp -o scl.exe -mconsole -pipe

g++编译实现VT全免杀_符号表_05

g++ scl2.cpp -o scl.exe -mconsole -time

g++编译实现VT全免杀_g++_06

g++ scl2.cpp -o scl.exe -mconsole -s

g++编译实现VT全免杀_编译器_07

一些参数还可能会导致报毒变多,-s参数就是一个很典型的例子,6个报毒

g++ scl2.cpp -o scl.exe -mconsole -pie

g++编译实现VT全免杀_编译器_08

-pie参数编译后运行没有反应,跳过

g++ scl2.cpp -o scl.exe -mconsole -shared

-shared参数编译后运行无法运行,跳过

g++编译实现VT全免杀_g++_09

--target-help下面还有几百个参数

g++编译实现VT全免杀_编译器_10

我试了一些不是没有变化就是不能运行或是不会用,这个时候我想到了chargpt,这种时候用chargpt就是很合适了

g++编译实现VT全免杀_符号表_11

  1. -s参数用于剥离可执行文件中的符号表,这样可以使反汇编变得更困难,也可以减少程序被误判为恶意程序的概率。
  2. -fno-stack-protector参数可以禁用堆栈保护机制,这样可以减少杀软对程序的误报。
  3. -fvisibility=hidden参数可以隐藏编译出的符号表,这也可以使反汇编变得更困难。
  4. -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

g++编译实现VT全免杀_编译器_12

0个报毒

补充

g++ scl2.cpp -o scl.exe -mconsole -Wl,--nxcompat

单独使用-Wl,--nxcompat参数还是会导致报毒

g++编译实现VT全免杀_编译器_13

实验结论

在代码确定免杀的情况下报毒,是编译的问题。使用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