一、 序
杀毒软件检测木马,后门等黑器时,最传统也是最有效的方法之一是特征码比较。越是名气大的黑器越是被追杀的体无完肤。有时候好不易突破了对方防火墙的堵截,想传个心爱的后门过去,可立足未稳就已经被对方的杀毒软件枪毙了。当然,各种加壳软件能在一定程度上减小后门被发现的可能性,但现在杀毒软件自动脱壳的功能越来越强,给文件加壳终究是一种治标不治本的方法。因此,最好还是能从程序本身入手,将特征码找出来并修改掉,就算不加壳也能确保不被查杀。不放心的话,再加个极品壳,来个双保险,岂不爽哉!
二、 基本原理
想要修改特征码就必须先找出它的所在。冰狐兄有篇名为《杀毒软件能奈我何——网络神偷特征码修改实战》的文章介绍了字节替换的原理,总结起来就一句话:如果文件中的特征码被我们填入的数据(比如0)替换了,那杀毒软件就不会报警,以此确定特征码的位置。这个方法简单而有效,但是手动操作起来工作量太大。受作者启发,我编写了个小程序来自动实现特征码定位的功能。
三、 参数设置和注意事项
CCL的原理是将原文件中部分字节替换为0,然后生成新文件,再根据杀毒软件来检测这些文件的结果判断特征码的位置。使用CCL之前应该先设置一下参数,包括操作方式是自动还是手动,生成文件的路径。
自动操作时,有一个参数很重要,就是每生成一个文件等待的秒数。因为我们要保证杀毒软件在这个几秒钟内对替换过的文件进行了检测,并能删除该文件(如果含特征码的话),然后CCL根据刚才的生成文件是否被删除来决定下面的操作。如果间隔时间过短,杀毒软件没有来得及检测,CCL就进入了下一轮操作,嘿嘿,轻者判断结果出错,重者系统很可能会崩溃的!建议先把时间设大一些,比如7到10秒。
应该明确的是,这种检测对已加壳的文件是无效的,因为带壳文件被替换的字节不是原程序的真身,而是加壳后的数据。不多说了,下面进入实战演练!
四、 实战之一:winshell特征码的自动定位
铛铛铛!第一个目标是winshell,检测一下,一声刺耳的驴叫,卡巴斯基报警发现了Backdoor.Win32.Winshell.50
下面让我们利用自动替换功能来定位特征码。首先运行CCL,将参数设为自动,等待时间7秒,最小定位精度设为16个字节。然后关闭杀毒软件即时监测功能(以后均简称为监测),打开待检测文件。成功读入后会弹出PE文件段选择窗口[如图2],这是让用户选择对文件的哪一个部分进行替换。我们双击.text段(这是可执行文件的代码段),然后用户输入区会显示相应数据。我们再点击“添加区段”,就成功地添加了一个待检测区段。当然,你也可以直接在“用户输入区”填入数据然后添加。双击已添加的区段,可以删除任务。
这里有个问题,我们应该选择几个段进行检测呢?最简单的方法是一个都不选,程序会默认对整个文件进行检测。但有时候文件过大,或者你能确定特征码位于某个段中,为了避免替换时间过长,就可以选择特定的范围进行检测。
还有一个选项叫“是否填充0”,这个选项的功能是指为了预先排除某些部分的干扰,我们在生成文件中将该部分用0填充。呵呵,举个例说明一下,文件有A、B两处特征码,为了更精确的定义A,我们可以将B所在的段预先填0,然后专门定位A所在的部分。关于填充0的时机,大家在使用过程中会慢慢总结出来的。好了,回到winshell,这里我们选择“不填充0”,也就是正常替换。
我们单击确定,弹出了操作窗口。
窗口里显示了各种信息,包括文件名、生成路径、操作方式和需要硬盘空间(手动的话)。这时,别忘了打开监测,并且最好将该功能设为“遇到病毒时自动删除,不提醒用户”。然后打开“我的电脑”,进入生成文件的文件夹,让“我的电脑”窗口保持在前台。为什么呢?因为有的杀毒软件只对前台窗口生成的文件进行即时监测,比如我机上的卡巴斯基。还有一些杀毒软件,就算“我的电脑”窗口在前台也不一定对生成文件检测,这时可以不断的在文件图标上单击右键,来“刺激”一下杀毒软件。是不是有点儿复杂哈?
回到CCL,确认窗口显示的信息无误后,单击GO,开始自动检测。这时,你会发现“我的电脑”文件夹里多了两个文件,名称形如“OUT_XXXXXXXX_YYYYYYYY”,其中8个X代表当前替换0的起始偏移,8个Y代表替换多少字节的0。几秒钟内,会有一个文件被杀毒软件自动删除。(我再强调一下,7秒钟是你设定的等待时间,要确保含特征码的文件在这7秒内被删除掉。)7秒钟后,会生成另外两个文件,这是CCL进行下一轮检测了。这样等啊等,期间不停的在生成文件图标上点鼠标右键(不知道除了卡巴斯基,其它的杀毒软件需不需要这样的刺激),过了2分多钟,结果出来了。
-------------定位结果------------
序号 起始偏移 大小 结束偏移
0001 0000180C 00000014 00001820
0002 00002130 00000050 00002180
0003 00002810 00000028 00002838
0004 000028D8 00000014 000028EC
这个结果说明特征码可能在这四段中。定位成功了?呵呵,不要急,这才刚刚完成了一半,下面还要对文件进行修改,并最后确定特征码的位置与类型。小提示:四处结果不一定都需要改,如果只改动一处就成功,那是最好不过的。挑一处段大小最小的改吧,就第一项,从文件偏移0x180C开始的0x14个字节。我们用OllyDbg打开winshell.exe,来到0x0040180C处。这里省略了文件偏移和内存偏移的转换,不知道要先补补课。代码如下:
0040180E 83C0 C1 add eax,-3F
00401811 83F8 39 cmp eax,39
00401814 0F87 5C01000> ja win.00401976
0040181A 33C9 xor ecx,ecx
0040181C 8A88 0C1A400> mov cl,byte ptr ds:[eax+401A0C]
00401822 FF248D E4194> jmp dword ptr ds:[ecx*4+4019E4]
怎么改呢?这里讲两个通用的方法。特征码不可能只由某一句指令来确定,这样误报率会非常高,因此通常是多条指令的组合,我们只要将这个组合打乱既可。最简单的方法当然是两条指令调个顺序,我们把它叫做指令顺序调换法,它使用的范围仅限于互不干扰的两条指令。可有很多情况,指令的执行顺序是不能调的,比如上面的6条指令,这时就用第二种方法,那就是,咳咳,通用跳转法则:在文件中寻找一个空隙,(由于对齐的原因,PE文件中往往会有一些空隙处没有代码,全部为0。为什么?补课的先!)将原来的指令改成一个跳转,跳到这个空隙去执行,空隙处填入我们原来的指令,执行完毕再跳转回去。我们将OllyDbg的滚动条向下拉,Look,在0x00405D20处有空隙。
修改方法见下面(改之前别忘了先将原文件备份一下):
0040180E /E9 0D450000 jmp winshell.00405D20
00401813 |90 nop
00401814 |0F87 5C010000 ja winshell.00401976
为什么要改add和cmp两句?因为jmp指令占了5个字节,而add和cmp均为3字节指令,只能两个一起改了。好,我们将0x0040180E处改为jmp 00405D20,多出一个字节我们改为nop。(不改nop也行,但是OllyDbg显示时会出现花指令,我们是追求完美的。)接着在空白处将原来的add和cmp两条指令补上,尾部再来个jmp回去的代码。在jmp回去时,可以回到nop,也可以直接跳到ja处,这里选择跳回nop。
00405D20 83C0 C1 add eax,-3F
00405D23 83F8 39 cmp eax,39
00405D26 ^ E9 E8BAFFFF jmp winshell.00401813
修改完毕,我们保存一下先。在OllyDbg窗口中单击右键选择“复制到可执行文件—>全部保存”,然后保存到winshell.exe中。OK,在菜单中选择“重新运行”,回到0040180E处,确定刚才的修改已经保存了。关闭OllyDbg,找到winshell.exe,用杀毒软件进行扫描。嘿嘿,卡巴斯基已经认不出它来了!打完收功!
你也许会问,不管什么杀毒软件都是这样修改吗?答案是:NO。各个杀毒软件对特征码的定义是不一样的,唯一的方法就是分别对每个平台进行检测,再有针对性的修改。修改方法一样:指令顺序调换法(这种最简单)和通用跳转法!对了,还有一点:尽量在代码段中找空,但有时候代码段中的空隙实在是不够,就把跳转的代码写在别的段中。由于这些段的默认属性里没有“可执行”这一项,你把代码移过去执行自然会报错,这时用PE修改工具将段属性加上可执行就可以了。
五、 实战之二:手动与自动结合定位黑社会2.0的特征码
(后来我知道这里有一点小失误,因为我改的是服务端的代码,而黑社会的服务端是在自已的机器上运行的。不过没关系,可以当作另一种类型特征码的展示。)
Winshell是VC编译的文件,那么对于别的语言编写的程序,比如汇编、VB等等,这种定位还有效吗?原则上来说,只要是编译成机器码的程序都可以定位。VB是一种解释语言,它的可执行文件的代码不单纯是机器码(汇编指令),不知道CCL对它的定位效果如何。黑社会2.0是一个VB编写的集远程管理与攻击为一体的黑器,下面来测试一下它的特征码定位。OK,闲言碎语不要讲,让我们直奔主题。
黑社会的执行文件是AsPack加的壳,可以用AspackDie1.41自动脱去。这一次我们改变一下操作方法,由全自动改为手动与自动结合,先利用手动替换来大体确定特征码的范围。首先运行CCL,设置参数为手动,按规定个数输出文件,输出个数为100。参数设置完后打开已脱壳的文件,在弹出的PE段选择对话框中直接点击“确定”按钮,也就是对整个文件进行替换。关闭监测,然后在操作窗口中单击“GO”,很快100个文件就生成了。(友情提醒:手动生成大量文件时,一定要将监测关闭,不然杀毒软件要同时处理这成百上千个带毒文件,可能会崩溃的!)
我们用杀毒软件对这100个文件进行扫描,在杀毒软件删除了所有含特征码的文件后,只剩下两个文件。我们在工具栏中选择“定位”按钮并打开刚才的生成文件夹,确定后主窗口上便显示出了定位信息。
编号为1的结果显示是从偏移0000开始替换的,在我的机器上这个结果不用考虑,因为卡巴斯基软件对于没有PE头的文件是不进行特征码检测的,文件1中恰好是PE头被替换了,自然就不会被删除。(据说别的杀毒软件,比如Norton,不管有没有PE文件头都会进行特征码检测,具体情况要具体分析。)因此初步确定特征码在编号2的文件所表示的范围内,既0x2DC2到0x44A3之间的0x16E1个字节的范围内。
重新设置参数为自动,读入原文件,在“用户输入区”直接输入起始位置2DC2和检测大小16E1,不填充0,然后点击添加区段,确定后进入操作窗口。打开监测,单击GO,开始自动检测,操作方法和检测winshell时一样。又经过一番对鼠标右键的折磨,终于得出了结果:
-------------定位结果------------
序号 起始偏移 大小 结束偏移
0001 000031C6 00000016 000031DC
0002 00003A16 0000002C 00003A42
0003 00003A44 0000002C 00003A70
0004 00003A71 0000002C 00003A9D
0005 00003AA0 0000002C 00003ACC
0006 00003ACD 0000002C 00003AF9
哇,有6处耶!老规矩,柿子要挑软的捏,我们先来查看范围最小的0001项。OllyDbg打开原文件,找到0x004031C6处,看看是些什么。怎么回事?不是汇编指令啊!除了0就是几个毫无意义的数据。
004031C6 00 db 00
…
004031D4 BA db BA
004031D5 DA db DA
004031D6 C9 db C9
004031D7 E7 db E7
004031D8 BB db BB
004031D9 E1 db E1
004031DA 00 db 00
…
不是汇编指令,那可不可能是字符串呢?我们在命令行里打“dd 004031d4”,既显示0x004031d4处的内容,然后将数据窗口的显示方式改为“文本?ASCII(32)”,随即左下角小窗口中显示出“黑社会”三个字,而且有三处。[见图7]原来“BADAC9E7BBE1”是这三个汉字的ASCII代码。难道杀毒软件就靠文件中的“黑社会”去识别黑社会?
为了证明我们的想法,我们用32位编辑工具UltraEdit打开原文件,搜索“黑社会”三个字,一共找到了7处。干脆,一不做二不休,我们将7处“黑社会”全部替换为“白晶晶”。
保存一下,再用杀毒软件检测。我靠,果然认不出来了!黑社会2.0的特征码就这样被我们搞定了,真是得来全不费工夫啊,竟然是直接用汉字作为特征码!运行一下修改过的文件,挺好使,就是“关于”窗口上的标题从“黑社会”变成“白晶晶”了,呵呵!
六、 关于多处特征码的一点补充
前面两个实战中,我们虽然定位出了多处特征码,但只修改其中一处就可以了,这种情况不一定适用于所有的程序。根据笔者经验,特征码可能有主副之分。主特征码被修改,则无论副特征码是否存在,文件均可以逃过追杀;但如果只修改副特征码,而不修改主特征码,则文件始终会被杀毒软件辩认出来,只不过识别出的版本有所差别。所以,我们修改的目标重点是文件中的主要特征码。
七、 结语
差不多了,我们来总结一下吧!
用CCL定位特征码时,手动替换和自动替换应该互补使用,没有一个方法是全能的。通常为用手动确定大范围,用自动精确定位小范围。定位成功后,看特征码的类型。如果是汇编指令,用“指令顺序调换法”或“万能跳转法”进行修改;如果是字符串等,在不影响原程序运行的情况下,替换掉既可。
操作方法也很重要,操作过程中注意和杀毒软件的配合,多试几次,掌握不同杀毒软件的特点,合理设置等待时间和最小定位精度等参数。更重要的是,确保自动检测过程中,杀毒软件对生成文件进行了检测,适当加上点“刺激”(比如我的鼠标右键刺激大法)。
讲到这儿,相信你应该知道怎样打造自己的无敌黑器了吧