"杀毒"和"免杀"矛与盾的两者,对于黑客来说两者都应该学习,做到知己知彼才能达到真正的"王者",今天就以本篇文章给大家分享一下"免杀的技术原理与实现过程"。
一、 杀软是如何检测出恶意代码的?
![“黑客”深度学习之“免杀技术原理与实现”](http://www.axjcy.com/uploadfile/202306/d3b5446fd683d37.jpg)
1、检测特征码
人有自己的特征,代码也有自己的特征。杀毒软件都有着一套特征库,依靠检索程序代码是否和库中特征码是否吻合来判断某段代码是否属于病毒。
2、启发式恶意软件检测
如果该程序的特征和行为与病毒程序类似,其匹配程度达到一定值就可以认为该程序是病毒程序。
3、基于行为检测
与启发式检测类似,只是单纯依靠监测程序行为来作为标准。通过监视恶意代码运行过程,如利用系统监视工具观察恶意代码运行过程时系统环境的变化,或通过跟踪恶意代码执行过程使用的系统函数和指令特征分析恶意代码功能,如出现恶意行为,则属于恶意代码。
二、 免杀是什么?
顾名思义,免杀就是使得恶意软件不被杀毒软件查杀,二者能够共存。
免杀大概可以分为两种情况:
1、二进制的免杀(无源码),只能通过通过修改asm代码/二进制数据/其他数据来完成免杀。
2、有源码的免杀,可以通过修改源代码来完成免杀,也可以结合二进制免杀的技术。
免杀也可以分为这两种情况:
1、静态文件免杀,被杀毒软件病毒库/云查杀了,也就是文件特征码在病毒库了。免杀方式可能是上面的两种方式,看情况。
2、动态行为免杀,运行中执行的某些行为被杀毒软件拦截报读。行为免杀如果没有源码就不是很好搞了。
三、免杀的技术实现方法与流程
3.1首先静态免杀技术流程:
对于静态免杀,针对的是杀毒软件的静态文件扫描,云查(病毒库)杀。
3.1.1 怎么找特征码
1)工具查找
常见的特征码定位工具有CCL、MYCCL。工具大致原理就是分割文件,某些分割部分填入数据(0),如果扫描该部分不报警,则特征码在这个部分。如此反复,直到找到很短的某一段内容。不同工具之前局别是使用的分割算法不同,查找特征码的效果不同。
目前比较常有名气的特征码定位器主要有CCL与MYCCL,他们都采用文件分块定位的办法,定位效果带有运气成份,且可能每次定位出的位置都不尽相同,这个免杀带来了困难。
后来出来了一款新的特征码定位软件VirTest。下面是作者自己的介绍:
我们可以这样假设报毒过程,如果检测文件是PE,如果在CODE位置存在 标志A,在DATA位置存在标志B,在资源位置存在标志C,同时满足这个3个条件,那么杀软就会报毒,VIRTEST工作原理就是要找到引起报毒最后一个标志,也就是假设中的标志C。
因此VIRTEST采用2分排除法,测试标志C所在文件中的位置,由于被杀的文件可能存在多个 类似于ABC这样的连锁条件,所以我们必须要通过一种排除机制,先要找最靠近文件前部的连锁条件,排除掉文件尾部数据,当找到第一个连锁条件后,抹掉引标志C,再恢复尾部数据,
然后继续测试另外的连锁条件,直到找到最后一个连锁条件,抹掉后,整个文件免杀了,则说明特征代码被定为完毕了,所以VIRTEST绝对可以精确的定位出所有的复合特征。这比文件分块定位法先进得多,更为科学。
工具查找肯定是针对二进制文件(有源码的也编译后在检查)。
具体用过MYCCL(使用方法自行查找),确实比手工分割文件定位方便,也可以找到某些文件的特征码,但是有些时候可能会出现非常多非常多...的被杀文件分割,然后...崩溃了。
后来也用了virtest,感觉作者说的挺有道理,应该挺好用吧。然后试了试,确实感觉比MYCCL高大上多了,也可以定位到特征码,但是tmd改了之后怎么还是报呢,反正你可能会折腾很久...
2)手工查找
这里说的是针对有源码的(二进制就别想手工了...),方法非常简单。
mian中屏蔽所有代码,编译,扫描。不报的话继续2,如果依然报毒,去5。
放开一层(可以多层、二分也可以)函数,编译,扫描。不报的话,重复2。直到定位到某个函数或者多个函数,进入3。
在函数内部屏蔽部分代码(二分),编译,扫描。不报,重复2。
直到定位某段代码(无自定义内部调用),特征码在此。
是不是有附加数据,或者资源存储的文件。有,单独检查该文件或者数据,方法从1开始。如果没有,那去找找PE头吧。
大致流程:
1. sub1 //未报
2. sub1 sub2 //未报
3. sub1 sub2 sub3 //报
4. sub1 sub2 sub3(sub31) //未报
5. sub1 sub2 sub3(sub31 sub32) //报
6. sub1 sub2 sub3(sub31 sub32(sub321)) //报
...
直到找到某API调用,或者逻辑代码(没有自定义函数调用)
此方法,虽然笨,但是定位特征码不会很慢,挺准确。
3.1.2. 怎么免杀?
前面已经找到特征码了,怎么免杀呢?
其实前面已经说到了,找到特征码之后,只要改变这个特征码值得话就免杀成功。如果不需要软件正常运行,直接填零得了...开玩笑,这怎么可能。所以修改特征码还得保证软件正常功能。所以也是有讲究的。
常用的修改工具有,OD,C32ASM,UE,010Editor等等。
(一)手工修改
非源码
1). 数据
如果特征码定位到数据(通过IDA/OD等确认),其实不好修改,稍微不慎就会导致程序不能运行,或者影响程序运行流程或结果。
字符串,如果不影响程序逻辑,可以替换大小写;如果无关紧要的数据,随意替换;等等,看情况而定。
整数,如果不影响结果,替换值,清零等等操作。
地址,基本应该不能修改,具体看情况。
PE头数据,根据PE结构具体来看,无用数据清零或修改,有用数据看情况修改。
最后,终极修改方法,找到访问数据的代码,直接修改代码访问数据的地址,数据也可以放到其他地址了,其实就如同修改源码一样修改,肯定没有修改源码那么容易(见后)。
反正特征码定位到数据位置不容易修改(可以再试试后面的盲免杀)。
2). 代码
如果特征码定位到代码(也通过IDA/OD等确认),在不改变程序功能基础上,应用各种方法修改。
等价替换汇编代码,如mov eax,0可以换成xor eax,eax,直接结果相同,二进制代码不同。
交换代码顺序,在不影响逻辑的情况下。
代码块移位,将代码块移动不用的内存位置,通过加入jmp addr跳过去执行,addr是新的代码块地址。
源码:
在有源码的情况下,修改的方式就更灵活了,更简单了。
如果特征码是数据,那么修改数据位置,访问数据的代码位置等(思想类比非源码方式)。
加花指令,这是最有效也是最常用的方式,要点在于如何加话指令。
加数据计算代码,加减乘除各类组合。
加字符串操作代码,增加、删除、查找、替换等。
加多层跳转,跳转间加无效指令(不会执行的)。
加貌似有效的API调用,如LoadLibrary+GetProcAddr+API等。
等等。
(二)工具免杀(盲免杀)
在没找到有效的特征码,或者不好修改的时候,可以试试这种方式。
资源操作:
1). 加资源
使用ResHacker对文件进行资源操作,找来多个正常软件,将它们的资源加入到自己软件,如图片,版本信息,对话框等。
2). 替换资源
使用ResHacker替换无用的资源(Version等)。
3). 加签名
使用签名伪造工具,将正常软件的签名信息加入到自己软件中。
几种方式可以交替重复多次进行组合使用。
PE操作:
1). PE优化
使用PE优化工具对文件进行优化,删除0,PE头优化,附加数据等。
2). 增加节
增加节数据,随意加入无效数据。
加壳:
可以将加壳简单理解为:解密器/解压器+加密器/压缩器(原始代码)。
通过加密器/压缩器将原始代码进行加密压缩,让其特征码变化隐藏,然后组装上解密器/解压器到文件中,运行是先运行解密/解压器,将加密压缩内容解密解压,然后继续运行原始代码。
1). 加冷门壳
壳也有特征,知名壳都已经被分析的非常多了,杀软基本都能查这类壳,或者自动脱壳,然后进行查杀。
所以加冷门壳,壳特征未被分析,不能自动脱壳,可以更好隐藏原始代码,得到免杀效果。
2). 加壳改壳
将常用壳进行修改,让壳特征变化,也可以是杀软失效。
比如修改入口,区段信息修改,入口代码移位。
可以类比为免杀壳,上面介绍的方法都可以使用。
3.2 其次,行为动态免杀
杀毒软件现在都会有主防的功能,对恶意行为进行拦截提示。
比如这些行为:
注册表操作,添加启动项,添加服务,文件写入、读系统文件、删除文件,移动文件
杀进程,创建进程,注入、劫持等
3.2.1行为拦截原理
说白了,恶意行为都是通过API调用来完成的,可能是一个API,可能是多个APi组合。
杀软通过技术手段拦截这些API调用,通过策略来判断是否属于恶意行为。
关键点:
API
策略(顺序,调用源,参数等等)
所以后面的方法就是针对这两点做的工作。
3.2.2如何进行行为免杀呢?
下面介绍的方式对非源码、源码都有效,但是非源码修改起来非常非常麻烦...
1). 替换api
使用相同功能的API进行替换,杀软不可能拦截了所有API,所以这种方式还是有效的。比如MoveFileEx替换MoveFile。
2). 未导出api
寻找相同功能的未导出API进行替换,杀软拦截一般是导出API,或者底层调用,寻找未导出API有一定效果。
寻找方法,通过分析目标API内部调用,找到内部一个或多个未导出API,来完成相同功能。
3). 重写api
完全重写系统API功能(通过逆向),实现自己的对应功能API,对于ring3的行为拦截非常有效。比如实现MoveFile等。
4). api+5
ring3的API拦截通过是挂钩API头几个字节内容,然后进入杀软自己函数进行参数检查之类的。
那么如果调用API时,跳过头部几字节,就可以避开这种拦截方式。
__API:
1 push ebp;
2 mov ebp, esp;
3 mov edi, edi;
4 ...
调用时,不适用1地址,而使用4地址,然后自己函数内部还原跳过几字节的调用。
__API_MY:
push ebp;
mov ebp, esp;
mov edi, edi;
call 4
5). 底层api
该方法类似于2和3,杀软拦截API可能更加高层(语义更清楚),那就可以找更底层API进行调用,绕过拦截,比如使用NT函数。
或者通过DeviceIoControl调用驱动功能来完成API功能。
模拟系统调用。
6). 合理替换调用顺序
有时拦截行为是通过多个API组合来完成的,所以合理替换顺序,绕过杀软拦截策略,也可以绕过改行为拦截。
比如,先创建服务,再将服务对应文件拷贝过去。
7). 绕过调用源
通过调用其它进行功能来完成API的功能。比较经典的如,通过rundll32.exe来完成dll加载,通过COM来操作文件等等。
小结:
方法大概就总结到这,要更好的完成免杀,需要各种方式进行合理灵活组合变化,或者挖掘更多的方法
四、免杀实例讲解
实验主机: Vmware 虚拟机
操作系统: XP sp3
实验用具: MyCCL 2.1、C32Asm、一份病毒样本(encode.exe)、百度杀毒、360杀毒
实战开始:
第一步将杀毒软件的实时防护关闭,以免一会自动把我们实验的样本杀了,然后点击设置:
![“黑客”深度学习之“免杀技术原理与实现”](http://www.axjcy.com/uploadfile/202306/f5aaa539466b7a0.jpg)
第二步用杀软查杀一下病毒样本看看:
![“黑客”深度学习之“免杀技术原理与实现”](http://www.axjcy.com/uploadfile/202306/0490755e4c77614.jpg)
确定没问题。
第三步:打开MyCCL,按上篇讲过的方法,"文件"选好病毒样本、"目录"选好分块文件存放目录、设置分块数量(我这为20),设置好如下图:
![“黑客”深度学习之“免杀技术原理与实现”](http://www.axjcy.com/uploadfile/202306/3215284a4e8db80.jpg)
第四步:点击<生成>,弹出双选框选'Yes',生成完毕。然后打开分块文件目录:
![“黑客”深度学习之“免杀技术原理与实现”](http://www.axjcy.com/uploadfile/202306/6c66b9934c67854.jpg)
确定分块文件生成OK了。
然后第五步:用配置好的360杀毒,对所有分块文件进行查杀:
![“黑客”深度学习之“免杀技术原理与实现”](http://www.axjcy.com/uploadfile/202306/ff664494abf0916.jpg)
第六步: 将报毒的文件手动删除,然后点暂不处理,别点立即处理。因为只有删除掉,MyCCL才能定位特征码。
接下来就可以点击"二次处理"按钮了,二次处理过后,再查杀一下:
![“黑客”深度学习之“免杀技术原理与实现”](http://www.axjcy.com/uploadfile/202306/d2c7e6a99a11d9.jpg)
无毒的话就不用继续查杀,如果有毒,就有重复"查杀删除->二次处理->查杀删除……"的循环。现在点击特征区间看看:
![“黑客”深度学习之“免杀技术原理与实现”](http://www.axjcy.com/uploadfile/202306/8144c91b6740.jpg)
这里的格式是: 前一段是十六进制的文件偏移,后一段是十进制的特征码长度。我们第一次定位的特征码有4041字节!这么大的范围,肯定是不能直接进行修改免杀,所以我们要进行"复合定位"!
第七步:在特征区间这一行,右键->复合定位此处特征。然后就和一开始的情况差不多了,只是范围缩小了:
![“黑客”深度学习之“免杀技术原理与实现”](http://www.axjcy.com/uploadfile/202306/e1a6c9d85ac6119.jpg)
我们再重复刚才的步骤: "生成->查杀删除->二次处理->查杀删除->二次处理……",就能得到更小范围的特征码。一般四次以内的重复操作,就能得到2字节范围的特征码,我们就能进行特征码的修改。
一番重复定位之后,我们最终得到了特征码的区间,通过再次点击"二次处理",可以生成一个定位图:
特征码 物理地址/物理长度 如下:
[特征] 0004A982_00000002
特征码分布示意图:
[--------------------------------------------------]
[--------------------------------------------------]
[--------------------------------------------------]
[--------------------------------------------------]
[--------------------------------M-----------------]
这时候,我们就可以查看一下特征码具体长什么样。我们使用的是C32Asm这一款工具,在百度一查就有安全的下载地址。通过这款工具,我们可以很轻松地查看、修改文件内容,它有"静态反汇编"的功能,所以修改起特征码很方便。
第八步:我们打开C32Asm,将病毒样本(不是分块文件)拖入其中:
![“黑客”深度学习之“免杀技术原理与实现”](http://www.axjcy.com/uploadfile/202306/d38fd8bd05e88d6.jpg)
第九步: 我们点击"十六进制模式",这个模式比较灵活,所以推荐使用。一打开,看见一堆十六进制码,别慌,让我们先跳到特征码的位置!右键点击->跳到:
![“黑客”深度学习之“免杀技术原理与实现”](http://www.axjcy.com/uploadfile/202306/3e1f1d79d291271.jpg)
第十步:将刚才定位出的特征码的位置,填写下去,点击"确定":
![“黑客”深度学习之“免杀技术原理与实现”](http://www.axjcy.com/uploadfile/202306/aed20183d0a9890.jpg)
看到这一段,熟悉病毒特征的朋友应该能看出来,这就是病毒本体的一部分,这几个函数就是病毒会用到的函数。
"E9 7A"被定位为特征码,其实熟悉的朋友应该已经知道怎么改了,因为"E9"就是典型的jmp跳转的机器码。
第十一步:我们右键->对应汇编模式编辑,看看它对应的汇编代码:
![“黑客”深度学习之“免杀技术原理与实现”](http://www.axjcy.com/uploadfile/202306/4a1175ccef525c9.jpg)
可以很清楚地看到,这句代码的意思就是要跳转到某地址上。在这里先讲一个方法——等价替代法,顾名思义就是用具有相同功能的代码替换它。jmp的话,按经验一般可以改成call,也就是将"E9"改为"E8"。
第十二步:在这里我们右键->汇编:
![“黑客”深度学习之“免杀技术原理与实现”](http://www.axjcy.com/uploadfile/202306/d49fcf2501918fb.jpg)
在这里要将JMP改为CALL,点击"汇编",然后就完成了:
![“黑客”深度学习之“免杀技术原理与实现”](http://www.axjcy.com/uploadfile/202306/0e905c5588b78b7.jpg)
最后:我们点击"文件"->"保存",然后退出,再用360杀毒扫描看看:
![“黑客”深度学习之“免杀技术原理与实现”](http://www.axjcy.com/uploadfile/202306/fec64038329b4d5.jpg)
我们已经成功免杀啦!现在360本地引擎已经没办法查出毒来了。我们可以通过同样的原理,完成对BD引擎、小红伞引擎的查杀。
注:以上文章内容只建议大家用来学习了解这项技术,切勿利用该技术去做违背道德和法律的事情!!!