01 隐蔽持久驻留
1.1 背景
持久化是一个攻击链周期中非常重要的环节,指用webshell、反弹shell、后门、rootkit长期控制失陷机器的一种技术,可能会涉及到dns隧道、http、icmp 隧道以及加密流量,从而达到一直控制失陷机器而不被发现的目标。
在攻击者利用漏洞获取到某台机器的控制权限之后,会考虑将该机器作为一个持久化的据点,种植一个具备持久化的后门,即使在设备重启、凭据修改或其他可能破坏当前恶意活动的操作发生后,也能够随时连接该被控机器进行深入渗透。
1.2 持久驻留方法
1.2.1 隐藏启动
1.2.1.1 systemd启动
system默认从目录/etc/systemd/system/读取配置文件。但是里面存放的大部分文件都是符号链接,指向目录/lib/systemd/system/,真正的配置文件存放于这个目录中。
一般系统手工创建的单元文件建议存放在/etc/system/system/目录下。
1. 首先编译提前配置好的后门文件。
2. 在/etc/目录下创建demo.local(名称),里面写入直接执行后门文件。
3. 修改权限。
4. 在/etc/system/system/目录下创建一个demo.service文件。
5. 设置启动链接。
6. 重启获得shell。
1.2.1.2二进制文件感染
基本流程
完成可用空间的后门代码(添加区段);
劫持执行流程;
注入后门代码;
恢复执行流程。
第一步:需要找到可用空间。
如何在pe文件中选择合适的空间来插入后门代码非常重要, 这将影响到后门被检测到的风险系数。
借助于一个名为cminer的工具,很容易枚举二进制文件的所有代码洞。
./cminer putty.exe 300 命令枚举code caves大于300字节。
在这种情况下,有5个好的code caves可以使用。起始地址给出了caves的虚拟内存地址(vma)。这是caves的地址,当pe文件加载到内存中时,文件偏移量是以字节为单位的pe文件内的caves地址。
由此可见大部分caves都在数据段内,因为数据段没有执行特权段标志, 这里需要更改。后门代码大概400-500字节左右,所以5个caves是足够的。caves的起始地址应该被保存,在将段特权更改为r/w/e后,第一步的后门过程就完成了。
第二步:通过修改目标可执行文件的指令,将执行流重定向到后门代码。
这里有一个关于选择将被修改的指令重要细节, 所有二进制指令具有字节大小,为了跳转到后门代码地址,将使用5或6字节的长跳跃。因此,当修补二进制时,将被修补的指令需要与长跳转指令的大小相同,否则上一条或下一条指令将被破坏。
在putty启动后的界面中, 点击 “open” 按钮会启动一个检查ip地址是否有效的功能。
如果ip地址字段值不为空并且有效,则它启动尝试连接给定ip地址的连接功能。如果客户端成功创建ssh会话,将弹出一个新窗口并请求凭据。
此处是重定向发生的点,因为av产品不能够复制这种复杂的环境,植入的后门将不会被自动化沙盒和动态分析机制检测到。
使用基本的逆向方法,搜索下面的字符串和字符串引用,不难找到连接函数的地址,方法如下:客户端建立与给定ip的连接后,有一个字符串 “login as:” 打印到出现的窗口。这个字符串可以帮助我们找到连接函数的地址,ida pro在这方面做得很好。
为了找到 “login as:” 字符串, 在ida上依次打开 views->open subviews->strings
找到字符串后,双击转到所在位置,在数据节内部ida查找所有对字符串的交叉引用,按 “ctrl x”,显示所有交叉引用,并这个引用在打印 “login as:” 字符串的函数内部。
这里是要修补的指令。在进行任何更改之前,请注意上下文的指令。
执行后门代码后指令将再次使用。
通过将push 467c7c指令改为jmp 0x47a478,完成后门过程的重定向阶段。需要注意的是下一个指令地址。它将在执行后门代码后用作返回地址。
第三步:后门代码注入。
首先在执行后门之前保存寄存器中的内容。寄存器中的每个值对于程序的执行都是非常重要的。通过在代码的oep(程序入口点)放置pushed和pushed指令,把所有寄存器内的值和寄存器标志都存储在堆栈中。这些值将在执行完后门代码之后弹出,以便程序可以继续执行不出错。
使用的后门代码是meterpreter反向tcp shellcode。但是在shellcode中需要做少量修改。通常反向tcp shellcode会有尝试连接到处理程序的次数或时间限定,如果连接失败,则通过调用exitprocess api调用关闭进程。
这里是问题所在,如果连接到处理程序失败,putty客户端的执行将停止。改变几行shellcode使其每次连接失败时shellcode重试连接处理器,这样也会相应的减少shellcode的体积。
在汇编代码中进行更改后,使用nasm -f bin stager_reverse_tcp_nx.asm命令进行编译。现在反向的tcp shellcode已经可以使用了,但是它不会被直接放置。我们的目标是在新线程上执行shellcode。
为了创建一个新的线程实例,需要另一个shellcode,使createthreadapi调用指向反向tcp shellcode。这里使用metasploit项目中创建线程的shellcode。
将 createthread.asm 文件中的代码转换为十六进制格式的shellcode,使用nasm -f bin createthread.asm命令进行编译。在这里,shellcode准备插入到caves中,但在插入shellcode之前应该对其编码,以便绕过av产品的静态/特征分析机制。因为metasploit项目中的所有编码器被大多数av产品所知,所以强烈建议使用自定义编码器。
在正确编码shellcode之后,就可以把它插入code caves。选择在pushfd下的指令,然后在免调试器上按下 “ctrl e”,shellcode将以十六进制格式粘贴。
使用xxd -ps createthread命令,以十六进制格式打印编码创建线程的shellcode或使用十六进制编辑器打开shellcode并复制十六进制值。当将十六进制值粘贴到调试器时,需要注意字节限制,因为这些修补操作是用免试器进行的,免调试器在粘贴到编辑代码窗口时有一个字节限制。粘贴的shellcode可能会有遗漏。当所有shellcode粘贴到code cave时后门代码就插入完成。
第四步:恢复执行流程。
在创建后门代码线程之后,程序需要恢复到其正常执行流程,这意味着eip应该跳回到将执行重定向到cave的函数。但是在跳回到该函数之前,应该检索所有保存的寄存器。
通过在shellcode的末尾放置popfd和popad指令,所有保存的寄存器都以相同的顺序从堆栈中弹出。在检索寄存器后,还有一件事要做,即执行被劫持的指令。
为了将程序的执行重定向到code cave, 我们将push 467c7c指令替换为了jmp 0x47a478。把push 467c7c指令放在最后,此时被劫持的指令也被检索。现在可以返回到通过插入jmp 0x41cb73指令将执行重定向到cave的函数的时候,结果代码应如下图所示。
最后选择所有修补和插入的指令,按右键单击并复制到可执行文件。此操作需要对已修改的每个指令执行。当所有指令被复制并保存到文件时,关闭调试器并测试可执行文件,如果可执行文件运行顺畅,则后门可以使用。
02 总结
随着对抗手段日益复杂化,持久化技术也将演变得更加隐蔽,同时也对防守方提出了一个独特的挑战,由于它们可以隐蔽执行后门代码,所以检测和分析过程就更加具有挑战性,需要采集大量的数据进行分析判别,如何在大量的日志中如何有效的进行检测,避免过度消耗资源,都是安全运营人员要面临的挑战。
后续将继续介绍隐蔽持久驻留的其他方法,敬请期待。
- 关键词标签:
- 天融信 检测与防护 持久化