导语:在上一篇《免杀的艺术 1》中,我们详细列举了各种实现免杀的技术。 今天,我们将继续为大家进行免杀的话题——PE文件后门的植入, 不过还是和上一篇一样,我们建议读者需要了解x86程序集,调试器和PE文件的基本知识。 现在几乎所有的安全研

camera-door-750x410.jpg

在上一篇《免杀的艺术 1》中,我们详细列举了各种实现免杀的技术。

今天,我们将继续为大家进行免杀的话题——PE文件后门的植入,

不过还是和上一篇一样,我们建议读者需要了解x86程序集,调试器和PE文件的基本知识。

现在几乎所有的安全研究人员,安全测试人员和恶意软件分析人员每天都要处理各种各样与后门攻击相关的工作,原因很简单,将后门放置到在系统中插入后门或在程序中保留随意访问的权限是当下最流行的一种攻击方式。

鉴于此,本文会主要为大家介绍往32位PE文件中植入后门的方法,但由于PE文件是微软在Unix平台的COFF(Common Object File Format 通用对象文集格式)的基础上制成的。所以凡是适用于COFF格式下可执行二进制文件的后门植入方法,都适用于32位PE文件,另外,由于保持后门的隐蔽性对于恶意软件的隐藏至关重要,所以本文将会像第一篇一样列举各种实现32位PE文件后门的免杀技术。

专业术语

和第一篇一样,我们先来对一些专业术语做一些介绍:

红队渗透测试:渗透测试是正义黑客大展身手的地方。他们可以对漏洞评估中识别出的许多漏洞进行测试,以量化该漏洞带来的实际威胁和风险。这群人我们通常称为“白帽黑客”。

地址空间布局随机化(ASLR):是参与保护缓冲区溢出问题的一个计算机安全技术,为了防止攻击者可靠地跳转到内存中的特定的被利用函数中,ASLR会对进程的关键数据区域的地址空间位置进行随机布置,其中包括可执行的部分、堆、栈及共享库的位置。

代码洞:代码洞是由另一个程序写入其他进程内存中的一段代码。这些代码可以通过在目标进程内创建远程线程来执行。代码的代码洞通常是对代码脚本函数的其中一部分进行引用,该脚本函数具有注入自定义指令的能力。例如,如果脚本的内存有5个字节的容量,可是目前实际只使用3个字节的容量,则剩余的2个字节的容量就可以用来添加外部代码。

校验和:是指传输位数的累加,当传输结束时,接收者可以根据这个数值判断是否接到了所有的数据。如果数值匹配,那么说明传送已经完成。通过这种方法可以检验文件运行的完整性,但校验和并不会去验证这个完整数据本身的真实性。

实现PE文件后门植入的方法

本文中所有的实现技术都是基于开源SSH的putty工具来可执行的。选择putty工具来植入后门有很多原因,其中之一便是putty工具能支持多个数据库而且能实现Windows API的本地C ++项目,而选择开源SSH的访问协议能让我们在植入后门时更加隐蔽,不容易被检测到。

我们所使用的后门代码是来自metasploit项目中的常用命令 “windows/meterpreter/reverse_tcp ”,因为该命令不仅能将meterpreter shellcode注入到目标PE文件中,同时还能保持程序的正常运行。另外,注入的shellcode会选择在一个新的线程上开始运行,然后在伺机和正常运行的程序产生连接关系。之所以要选择新的线程,就是为了避免被杀软产品发现。

在PE文件中植入后门大致包含4大部分:

1.找到后门代码的可用空间
2.截获程序流程
3.注入后门代码
4.恢复程序流程

而怎样具体执行这4大部分,才是成功植入后门的关键。

代码可用空间的实现

如何在PE文件中选择合适的空间来插入后门代码使我们实现后门的关键一步,

解决空间问题的两种主要方法:

1.增加新空间

这种方法的好处显而易见,就是新增加的这部分空间是根据新增加的后门代码的多少来变化,没有空间限制,但缺点也很明显,由于空间被修改的痕迹太过明显,所以很容易被检测到。

使用一个汇编程序或PE编辑器(如LordPE),我们可以为所有的PE文件扩充一个区段头,比如借助LordPE,就可以在本文所使用的putty工具的区块表中,扩充一个1000字节大小的区段。

1.png

当新扩充一个区段时,要将段标志设置为“Read/Write/Execute”, 当运行后门shellcode时,这个设置对于PE映像映射到内存至关重要。

2.png

在扩充完区段头之后,我们还要来继续来调整整个PE文件大小,这可以使用十六进制编辑器中,在PE文件的段尾来添加对应的空字节来实现。

3.png

至此,PE文件中新的空间就算添加完成了。然后来试着运行以下该文件,如果运行正常,我们就可以通过调试器来修改新增加的这个区段了。

4.png

不过目前几乎所有的杀毒软件都能识别出“Read/Write/Execute”这样的异常代码,

即使添加的空间不会被赋予什么运行权限,也会被检测到。

5.png

2.利用代码洞

解决代码可用空间问题的第二种方法便是使用目标可执行文件中的代码洞。几乎所有编译的二进制文件都有代码洞,我们可以利用这些即有的代码洞实现后门植入。由于这种方法利用的是现有的空间,即便在植入后门以后,整个PE文件的大也不会改变。不过该方法也有很多缺点, 比如由于代码洞的数量和大小会因文件而异,所以可用空间也会受限于文件的代码洞,这也就决定了当我们要植入后门代码时,应尽可能地精简这些代码。另一个缺点是当恶意应用程序在代码洞里的空间进行恶意运行时,其执行必须重新定向到代码洞所在地址,而且所有位于代码洞的代码还要被赋予“execute”权限,甚至连一些以自修改的方式编码或混淆的shellcode也需要“write”权限才能进行代码更改。

不过有一种办法可以解决代码洞的空间限制约束,就是同时使用多个代码洞,同时还可以把植入的后门代码分割为几部分,降低被检测到的风险,不过这样平白无故的对区段进行权限分割反而会引起杀软的注意。

目前只有很少的高级方法才能做到即能够修改运行时的内存权限又能避免直接更改区段权限,由于这些方法需要定制的shellcode,编码和IAT解析技术,所以我们会把它列为下一篇的分析重点,请大家继续关注。

借助于Cminer工具,我们可以很容易找到这些PE二进制文件的所有代码洞,例如,通过命令./Cminer putty.exe 300,我们可以找到putty.exe中所有长度大于300字节的代码洞,

6.png

可以看出,我们找到了5个符合条件的代码洞,起始地址是代码洞的虚拟内存地址(VMA),当PE文件加载到内存中时,文件偏移量是以字节为单位的PE文件内的代码洞的位置地址。

7.png

从上图可以看出,大部分代码洞的位置都分布在这些区段内,但由于这些区段代码都没有“execute”权限,所以我们还做一些权限修改。由于我们所测试的后门代码在400到500字节左右,所以这5个代码洞都足够用了。另外代码洞的起始地址要进行保存,在将这段代码的权限更改为“Read/Write/Execute”之后,我们寻找代码可用空间的这一步就算完成了。接下来,我们就要解决程序执行流的重定向问题了。 

截获程序流程

我们在这一步中,要实现的是通过修改来自目标可执行文件的指令将执行流重定向到后门代码。不过请大家注意,由于所有二进制指令都具有大小的(以字节为单位),而我们为了跳转到后门代码地址,将使用5-6个字节的长跳跃。因此,在修改二进制文件的指令时,这个指令的大小必须与长跳转的字节大小相同,否则指令将会失败。

选择合适的空间来重定向绕过杀软产品的动态检测和沙箱分析机制是非常重要的。如果直接进行重定向,则可能在杀软的动态分析阶段就暴露了。 

隐藏在用户交互下:

绕过沙盒和动态分析最重要一点就是要延迟shellcode的运行时间和避免shellcode触发沙箱的检测机制。但是植入后门时,我们是没有这么多的空间来在PE文件中添加这些免杀代码的。

由于使用汇编语言设计防检测机制所耗费的成本过大,所以我们使用了隐藏在用户交互下这个方法,这个方法可以很方便的实现后门免杀的功能。由于该方法在重定向时,必须要求用户亲自开启流程的重定向才能激活后门功能。所以如果这个方法可以正确实现,那免杀将100%的实现,且这种办法还不会增加后门代码的大小。

如下图所示,我们选择了putty上的“Open”,检查给定的IP地址的有效性,

8.png

如果IP地址字段值不为空并且有效,则putty就会启动连接给定IP地址的连接功能。

如果客户端成功创建了SSH会话,就会弹出一个新窗口并请求用户输入登录凭据,

9.png

此时,程序流便开始了重定向,这么做免杀的概率很高,因为目前还没有杀毒软件能够检测到如此复杂过程,所以,我们编写的恶意软件就不必担心进入到沙箱或被动态分析了。

使用基本的逆向工程方法,如下面使用的字符串及字符串的引用,将不难找到要连接IP的地址。在建立连接后,会在窗口出现了一个字符串“login as:”。这个字符串将帮助我们找到连接IP的地址,建议大家使用交互式反汇编器(IDA Pro)。

在交互式反汇编器中选择Views->Open Subviews->Strings,来寻找 “login as:” 字符串

10.png

找到“login as:” 后双击,就能跳出其所在的位置,由于在交互式反汇编器中可以显示出数据节内所有对“login as:” 的交叉引用,按“Ctrl + X”,就能显示出所有交叉引用,

这些交叉引用会显示在“login as:”字符串的函数内部,

56.png 

563.png

这时我们的修改指令就完成了,不过要将这个修改好的指令保存,因为在后面我们还要继续用到。

12.png

通过将PUSH 467C7C指令更改为JMP 0x47A478,后门的重新定向过程就完成了。不够需要注意的是,要记住JMP 0x47A478的地址,在注入后门代码完成后,我们还要把JMP 0x47A478的地址作为返回地址,接下来就该谈谈怎样注入后门代码了。

注入后门代码

在注入后门代码时,我们认为首先需要做的是在注入后门代码

之前保存寄存器,因为所有寄存器中的每个值对于程序的执行是非常重要的。通过将PUSHAD和PUSHFD指令置于代码洞的开头部分,所有寄存器和寄存器标志就都存储在堆栈中了。这些值将在注入后门代码之后弹出,以便程序可以继续正常运行。

13.png

我们已经在前面提到过,我们所使用的后门代码是来自metasploit项目中的常用命令 “windows/meterpreter/reverse_tcp ”,但在注入shellcode时,我们还应该再做些许修改。一般情况下,“windows/meterpreter/reverse_tcp ” 尝试连接到处理程序会有一个给定的次数,如果超过这个次数连接就会失败,程序也会调用ExitProcess API关闭“windows/meterpreter/reverse_tcp ”命令。

14.png

如果连接失败,putty客户端就将停止运行,所以我们要改变几行shellcode,来重新尝试连接,另外,shellcode的大小也能减少

15.png

在汇编代码中进行必要的更改后,使用nasm -f bin stager_reverse_tcp_nx.asm命令进行编译。现在“windows/meterpreter/reverse_tcp ”命令已经可以使用了,但是它不会被直接放置在代码中。我们的目标是在新线程上运行shellcode。为了创建一个新的线程,我们需要用另一个shellcode来让CreateThread API调用“windows/meterpreter/reverse_tcp ”命令。

16.1.png

将如上所述的十六进制的createthread.asm文件中的shellcode字节放置在代码后,就可以使用nasm -f bin createthread.asm命令进行汇编了。现在就可以将shellcode植入代码洞了,但在植入shellcode之前,我们应该先对它编码,这样它才能绕过杀软的静态及特征分析。因为目前几乎所有的杀软产品都能检测到metasploit项目中的几乎所有编码器,所以强烈建议使用自定义编码器。至于如何自定义编码器我们将会在另一篇文章中讲解,本文中将使用多个metasploit编码器组合的办法来实现免杀的功能。在每次组合之后,我们会将原始格式的shellcode上传到相应的在线查毒网站,看看免杀效果如何。尝试各种组合,直到把它检测到风险降到最低为止。

在正确编码shellcode之后,我们就可以把它插入代码洞了。选择PUSHFD下的指令,然后在immunity debugger中按Ctrl + E组合键,shellcode就将以十六进制格式粘贴过来。

使用xxd -ps createthread命令,创建线程后的shellcode就会以十六进制格式显示出来,或使用十六进制编辑器打开shellcode并复制十六进制值。将十六进制值粘贴到调试器时,请注意字节限制,由于这些修改都是在immunity debugger中进行的,而对于immunity debugger来说,向编辑代码窗口中粘贴代码时,是有字节限制的。它不会粘贴所有的shellcode,所以,我们每次粘贴时都会剩余最后2个字节,所以我们要多粘贴几次,直到把所有的shellcode复制完。这时,插入后门代码就全部实现了。

17.png

恢复程序流程

在创建玩后门代码线程之后,程序需要返回到正常运行的流程中,这意味着EIP寄存器(它可存储着我们cpu要读取指令的地址)应该返回到重定向之前的状态。但在返回之前,我们应该找到所有保存在寄存器中地址。

18.png

我们可以在shellcode结尾处输入POPFD和POPAD命令,将所有保存在寄存器中的地址从堆栈中找出。在检索完寄存器后,大家一定要记得处理被截获的指令。不过在重定向到代码洞时,我们已经将PUSH 467C7C指令替换为了JMP 0x47A478,所以要输入PUSH 467C7C指令,才能在寄存器中检索出被截获的指令。

在返回之后,我们可以通过插入JMP 0x41CB73指令重定向到代码洞,代码如下所示。

19.png

最后选择所有修改和插入的指令,把它们复制到可执行文件。当所有指令被复制并保存到文件后,关闭调试器并测试可执行文件,如果可执行文件运行顺畅,则证明后门可以使用。

最后,建议固定最终文件校验和,以保持文件的真实性,而不是看起来可疑,这也可能对降低检测分数有影响。

最后,建议处理好最终文件的校验和,以保持文件的真实性,以免被杀毒软件检测出来。

20.png

总结

如果大家完全按照以上的方法进行编写,我们可以保证产生的后门是完全不可检测的。为了保证免杀,本文还将列出一些针对这些后门技术的应对之策,这些措施可以有助于系统管理员,恶意软件记录器和杀毒软件产品的开发人员。

1.部分权限控制

如果涉及到backdoored文件时,部分权限控制对于检测异常程序非常重要,因为编译器永远不会设置代码的全部权限,特别是像“.data”或“.rdata”这样的数据段更不应该有执行权限,而类似的.text的代码段也不应该被赋予编写权限,如果发生了异常,则应该就是恶意程序了。

2.不常见的字段识别

如果程序员不进行任何配置,就在编译器创建5-6通用类型的段,则目前几乎所有的杀毒软件都应该能识别这种不常见和可疑的字段。 

3.签名检查

签名检查属于非常经典的杀软技术,但它也是最有效的,当大家下载一个新的程序或任何一个可执行文件时,签名检查便会开始检测。

4.检查文件校验和

当植入后门程序的校验和值与文件的实际校验和之间存在差异时,就代表程序已经被修改了。

21.png

源链接

Hacking more

...