|
原文链接:不会免杀?看我异或加密如何做到 VT 全免杀
前言
最近逛 github 的时候发现一个 C 的免杀项目,项目介绍中,作者只利用了动态加载 windows api ,和异或加密的方法就达到了在 antiscan.me 上全免杀的效果:
于是,我怀着一颗学徒之心,研究了一下这个项目,下面是我在 vt 上的测试结果:
使用方法
需要的环境:python3 、C++编译环境(我测试的时候是用VS2017编译的,如果是Kali Linux需要使用apt-get install mingw-w64*命令安装相关编译环境)。
先利用msf生成shellcode(这里为了方便测试直接生成弹计算器的shellcode)
msfvenom -p windows/exec CMD=calc.exe EXITFUNC=thread -f raw -o beacon.bin
然后运行 python charlotte.py:
生成后的dll文件就是需要的恶意文件了,执行方法 rundll32 charlotte.dll,随机函数名
具体的命令在运行charlotte.py脚本后会显示,如下图:
Bypass AV 无压力。
源码分析
这个项目一共分为两个部分,大概的思路就是创建一个模板的C++文件,然后利用python对字符串的处理,来解决C++文件中windows api的混淆和 shellcode 的加密。(其实很简单,还是老一套),项目目录结构如下图:
首先,我们来看下C++模板文件的关键代码:
- // If all good, launch the payload
- if ( rvba != 0 ) {
- XOR((char *) createthread, ct_len, ct_key, sizeof(ct_key));
- pCreateThread = GetProcAddress(GetModuleHandle("kernel32.dll"), createthread);
- thba = pCreateThread(0, 0, (LPTHREAD_START_ROUTINE) exec_mem, 0, 0, 0);
- XOR((char *) waitforsingleobject, wfso_len, wfso_key, sizeof(wfso_key));
- pWaitForSingleObject = GetProcAddress(GetModuleHandle("kernel32.dll"), waitforsingleobject);
- pWaitForSingleObject(thba, -1);
- }
- return TRUE;
- }
复制代码
可以看到,这个项目并没有用什么很复杂的技巧,模板C++的代码流程大概是这样的:
申请内存空间——> 更改内存空间属性 ——> 创建线程——> 执行shellcode
不过在调用的函数的时候,都采用了使用GetProcAddress动态获取函数的方式,这样的方法应该是让大部分杀软无法通过导入表中的函数去判断程序的黑白。
接下来,我们看py文件的内容:
第一个部分,读取shellcode内容,还有准备需要混淆的api名字,获取key随机字符串。
第二部分,将shellcode和相关api字符串通通用异或进行混淆:
第三部分,将混淆后的字符串和混淆用的key替换模板中文件的对应部分:
第四部分,用g++生成目标文件,清除中间产生的cpp文件:
总结
这个项目免杀的原因大概有以下几点:
- VT的多引擎查杀是静态查杀,或者说由于生成的是动态链接库文件,使得杀毒引擎只能使用启发式查杀和动态查杀去判断黑白。
- 模板中的字符串赋值类似char buf[] = {'h','e','l','l','o'};。这样让字符串存在于text段,而非常见的rdata段,字符串数据和代码混在一起,让杀毒引擎难以快速识别里面的字符串。(之所以说难以识别,是因为用ida之类的软件还是能看出来的,但是那样要求去用反汇编引擎反编译,识别语法树之类的,操作时间太长,为了平衡杀毒效率和杀毒准确性,一般会在云平台上运行)
- 模板中调用windows api的使用都是动态加载,而且用字符串混淆的方式隐藏了api函数,而且每个字符串的key都不一样,导致杀毒引擎没法识别出本来的字符串,进一步识别。
总得来说,这个项目在静态查杀方面已经做到了免杀当前所有杀毒引擎,是个挺不错得项目。
由于比较懒,并没有按照项目推荐去下g++环境踩坑,以下是在vs2017上存在得一些坑点,大家踩坑的时候自行斟酌。
这个项目的python脚本对g++编译过程是隐藏的,所以一些编译时可能有的错会难以发现。如果发现运行脚本后没有自动生成dll文件的话,建议从编译的步骤开始自个手动编。像我就将脚本移除cpp文件的部分注释了,然后手动编译(结果发现没环境,最后看到作者有写要下环境~)
模板c++文件中对于类型转化的报错,项目中源码如下图,在vs2017上编译的话是会报类型不匹配的错的需要用到类型强转:
改后的源码:
模板c++文件中对字符串的处理并没有加结束符,会导致解密后运行报错,所以需要在字符串末尾加上 0x00,就像这样:
当然,可以在脚本里面直接加:
模板文件中的函数类型没有赋值,所以也会报错。需要加上类型说明和强制转换:
最后,祝大家上线如回家,免杀如喝水!!
参考:https://github.com/9emin1/charlotte
|
|