引言
随着互联网架构的高速发展,信息安全越来越受到社会的关注,发展越来越标准化、流程化。在如今的渗透攻击和测试中,个人自身完成一整套渗透攻击链已变的越来越困难,于是,在各个阶段涌现出一批又一批的垂直化渗透工具,这些渗透工具不仅测试人员使用,黑客同样使用。所以,了解其实现原理以及特征就显得十分有必要了。
Metasploit 正是其中后渗透工具的翘楚。说起 Metasploit 这个词,可能大多数普通人不太了解,但对于搞渗透测试的人来说,它就犹如地之于豹,水之于鱼,天之于鹰,是当今安全专业人员免费提供的最有用的审计工具之一,同样地,黑客对其也是爱不释手。
Metasploit 是一个渗透测试开源软件,也是一个逐步发展成熟的漏洞研究与渗透测试代码开发平台。开源地址 Github:https://github.com/rapid7/metasploit-framework
Metasploit 结构
Metasploit 设计尽可能采用模块化的理念。大致由库文件、插件、接口、功能程序、模块等组成。
图 1 Metasploit V4 结构
模块是通过 Metasploit 框架所装载、集成并对外提供的最核心的渗透测试功能实现代码。分为辅助模块(Auxiliary)、渗透攻击模块(Exploits)、后渗透攻击模块(Post)、攻击载荷模块(payloads)、编码器模块(Encoders)、空指令模块(Nops)以及 V5 版本新增免杀模块(Evasion)。以下是模块的功能介绍:
- 辅助模块:通过对网络服务的扫描,收集登陆密码或者 Fuzz 测试发掘漏洞等方式取得目标系统丰富的情报信息,从而发起精准攻击。
- 渗透攻击模块:包括利用已发现的安全漏洞等方式对目标发起攻击,执行攻击载荷的主动攻击和利用伪造的 office 文档或浏览器等方式使目标上的用户自动触发执行攻击载荷的被动攻击。
- 空指令模块:跟随渗透攻击模块成功后的造成任何实质影响的空操作或者无关操作指令的无效植入代码,目的保证后面的攻击载荷能顺利执行。常见的在 x86 CPU 体系架构平台上的操作码是 0x90。
- 攻击载荷模块:跟随渗透攻击模块成功后在目标系统运行的有效植入代码,目标是建立连接,得到目标 shell。
- 编码器模块:同空指令模块作用相似,保证不会受到漏洞参数或者目标系统类型的限制导致无法顺利执行。
- 后渗透攻击模块:在获取到目标 shell 之后,进行后渗透攻击,比如获取信息,跳板甚至内网渗透。
- 免杀模块:作为 V5 版本新增的功能,只包含对 windows defender 类型。免杀方式较为简单,申请内存,拷贝攻击载荷,执行攻击载荷。
图 2 模块功能结构
由其功能可以看出,除了漏洞代码外,其构造攻击载荷的核心在于攻击载荷模块和编码区模块。以下将着重讲解其特征。
(一)攻击载荷模块
攻击载荷模块的功能是依据不同平台,不同通讯方式以及不同执行方式的需求构造生成不同的基础 payload。
1.1 分类
图 3 Metasploit 部分类型
攻击载荷模块在执行方式上分为独立 (Single)、传输器 (Stager)、传输体 (Stage),前者单独执行,后两种为共同执行的方式。
- single:独立载荷,可直接植入目标系统并执行相应的程序
- stager:传输器载荷,用于目标机与攻击机之间建立稳定的网络连接,与传输体载荷配合攻击。通常该种载荷体积都非常小,可以在漏洞利用后方便注入。
- stage:传输体载荷,如 shell、meterpreter 等。在 stager 建立好稳定的连接后,攻击机将 stage 传输给目标机,由 stagers 进行相应处理,将控制权转交给 stage。比如得到目标机的 shell,或者 meterpreter 控制程序运行。
图 4 火箭分离
其实 Single 等于 Stage 和 Stager 的集合,以下将着重讲解 Stage 和 Stager 的方式。Stage Stager 应用在攻击载荷的大小、运行条件有限制的环境,比如漏洞填充缓冲区的可用空间很小、Windows 7 等新型操作系统所引入的 NX (堆栈不可执行)、DEP (数据执行保护)等安全防御机制,就像火箭卫星一样,分阶段植入以达到目的,也跟 web 入侵里面的小马拉大马类似。
1.1.1 传输器载荷 (Stager)
结构
图 5 Stager 结构图
(1)清除标志位
使用 cld 清除标志位,避免前面的 nop 指令或者漏洞利用的代码等产生干扰,从而执行失败,然后跳转到执行远程连接行为,其中源码部分如下:
图 6 reverse_tcp 的源码
生成的样本部分:
图 7 IDA下stager 特征
(2)获取函数地址
Windows 系统下采用的方式是PEB寻址原理,Linux 下是采用 SysCall 系统调用号,这里阐释 Windows 的方式。如下图所示,在 NT 内核系统中 fs 寄存器指向 TEB 结构,TEB 0x30 处指向 PEB 结构,PEB 0x0c 处指向 PEB_LDR_DATA 结构,PEB_LDR_DATA 结构中包含本程序调用的 dll 链表,遍历链表,逐个遍历 dll 导出表的函数名称,算出其 Hash,对比传入的 Hash 相等即获取到函数地址。
图 8 获取函数地址结构图
此外,根据笔者也研究过 Cobalt Strike,其为获取函数地址所使用的寻址方式以及计算方式与 Metasploit 相同,所以函数 Hash 也相同,而且基于其兼容性问题,这些函数 Hash 短时间内也不会发生变化。
计算函数名称的 Hash 方法如下:
图 9 计算 Hash 函数(C )
常见的函数 Hash 如下:
Dll名称 | 函数名称 | Hash | 二进制(小尾) |
---|---|---|---|
kernel32.dll | LoadLibraryA | 0726774ch | 4C 77 26 07 |
Virtualalloc | e553a458h | 58 A4 53 E5 | |
Sleep | e035f044h | 44 F0 35 E0 | |
VirtualFree | 300f2f0bh | C2 DB 37 67 | |
CreateFileA | 4fdaf6dah | DA F6 DA 4F | |
ReadFile | bb5f9eadh | AD 9E 5F BB | |
wininet.dll | InternetOpenA | a779563ah | 3A 56 79 A7 |
InternetConnectA | c69f8957h | 57 89 9F C6 | |
HttpOpenRequestA | 3b2e55ebh | EB 55 2E 3B | |
HttpSendRequestA | 7b18062dh | 2D 06 18 7B | |
InternetReadFile | e2899612h | 12 96 89 E2 | |
InternetSetOptionA | 869e4675h | 75 46 9E 86 | |
crypt32.dll | CertGetCertificateContextProperty | c3a96e2dh | 2D 6E A9 C3 |
ws2_32 | WSAStartup | 006b8029h | 29 80 6B 00 |
WSASocketA | e0df0feah | EA 0F DF E0 | |
connect | 6174a599h | 99 A5 74 61 | |
recv | 5fc8d902h | 02 D9 C8 5F | |
bind | 6737dbc2h | C2 DB 37 67 | |
closesocket | 614d6e75h | 75 6E 4D 61 | |
send | 5f38ebc2h | C2 EB 38 5F | |
gethostbyname | 803428a9h | A9 28 34 80 | |
winhttp.dll | WinHttpOpen | bb9d1f04h | 04 1F 9D BB |
WinHttpConnect | c21e9b46h | 46 9B 1E C2 | |
WinHttpOpenRequest | 5bb31098h | 98 10 B3 5B | |
WinHttpSendRequest | 91bb5895h | 95 58 BB 91 | |
WinHttpGetIEProxyConfigForCurrentUser | 600ba721h | 21 A7 0B 60 | |
WinHttpReadData | 7e24296ch | 6C 29 24 7E | |
WinHttpSetCredentials | cea829ddh | DD 29 A8 CE | |
WinHttpQueryOption | 272f0478h | 78 04 2F 27 | |
WinHttpReceiveResponse | 709d8805h | 05 88 9D 70 | |
WinHttpGetProxyForUrl | 49eadddah | DA DD EA 49 | |
WinHttpSetOption | ce9d58d3h | D3 58 9D CE | |
… |
(3)执行网络连接
由于选择不同的连接方式会有不同的网络行为,从而会调用不同的函数,后面分析以 resever_tcp 为例,stager 通过 socket 连接指定的 IP 和 Port,建立连接后,申请内存,接收 stage 到申请的内存中,跳转到申请的内存地址首地址,然后开始执行 stage,完成交接。
图 10 函数调用顺序
Yara规则
根据 stager 的特征可以通过清楚标志位以及函数名称的生成 Hash 值来组合。流量以及生成的病毒文件均满足这种特征,以下为部分的 yara 规则:
图 11 stager 部分 yara 规则
静态提取信息
基于特定位置进行提取指定信息,包括 IP 和端口。
图 12 静态提取指定信息
1.1.2 传输体载荷(Stage)
原理
在漏洞利用成功后会发送第二阶段的 Stage,本质上是个 dll。上文提到 Stager 在内存中拷贝完 Stage 后就跳转到内存的首地址了,然后从 dll 的头部开始执行并运行此 dll。
了解过程序运行原理的都知道,程序运行需要一个加载器加载程序,先解析程序结构,然后 CPU 才执行代码。然而这种传输的方式在内存中,并没有加载器,那么如何做到 dll 运行呢?即采用 ReflectiveLoader 反射注入的方式。
图 13 Stage 汇编
原理上简单来说就是通过前面执行的汇编先调用 ReflectiveLoader 反射函数,该函数模拟加载器解析自身的结构,然后跳转到 DllMain 正常执行。但由于 PE 文件的种种限制,所以这种文件的注入方式的特点比较明显。
捕捉到明文传播 stager 的 pcap 包:
图 14 stage 流量捕获
Yara规则
根据其文件首部调用 ReflectiveLoader,以及调用的函数 Hash 作为特征识别。
图 15 Stage 部分 yara 规则
1.2 构造基础 payload
在 kail 中集成了 Metasploit 框架,有两种方式。
- 可以直接使用 Msfconsole 一体化集中控制台;
图 16 msfconsole 生成 stager
- 也可以使用 msfvenom 工具直接生成。
图 17 msfvenom 生成 stager
1.3 攻防演练案例
样本静态信息:
SHA256 | affca8567dc9e68ef8fd2afc9ee23d3f0b1d46c3088c212b9b96b24f4148ad9f |
---|---|
SHA1 | 85e50552b3927eaea7d05ef04d60dd8f4f9e1910 |
MD5 | e662d362d2ff3a4ceef3a4c84d21d655 |
样本大小 | 1684007 |
样本格式 | RAR archive data, v5 |
1.3.1 执行流程
图 18 样本流程
1.3.2 文件及流量特征
Shellcode 中的特征判断:
图 19 资源解密后的 shellcode
可以看到,该 Shellcode 就是 Metasploit 的 stager。使用相应的脚本可以直接解析出相应的 IP 和 Port。
捕获回传的 pcap,其特征也十分明显:
图 20 回传流量中的规则
回传的流量包中与 Metasploit 比较类似,经笔者分析,该回传包中为 Cobalt Strike 的 stager。如果此时进行流量检测,就可以进行精准拦截。
(二)编码器模块
上文提到 stager 和 stage 的特征十分明显,杀毒软件非常容易检测到,并且可能由于渗透目标的种种限制,导致生成的 payload 可能无法正常使用。所以 Metasploit 集成了许多编码类型(Encode)以应对不同要求。
图 21 Encode 类型
1)优点:使用编码生成的 payload 没有坏字符以及轻微免杀。
2)原理:基于异或的方式,但是方式不同,而且很多编码格式可以做到任意次多重编码或者多种编码格式混合编码,然而基于其实现的原理,每种编码格式又一定有相应的特征。这些特征就是识别解析的关键。
3)结构:异或循环结构 已异或的数据
图 22 一层异或结构
这种异或循环是如何实现的?根据异或解密三要素:异或值(key),长度 (length) 以及数据地址 (addr) 可知其原理:
1)首先要找到异或后的数据起始地址,最简单的是汇编(call $ 5)等获取当前地址等手段,再加上计算后的偏移得到数据起始地址;
2)其次数据的长度;
3)最后是异或密钥,可以是固定方式,也可以是与上一个密钥或揭秘内容有关的非固定方式。
以下将以 x86/shikata_ga_nai 编码为例,这种编码在 Metasploit 中最为实用和常用。
2.1 x86/shikata_ga_nai
使用 -e x86/shikata_ga_nai 选择编码格式为 x86/shikata_ga_nai,使用 -i 2 选择编码次数为 2 次,生成编码后 payload。
图 23 stager 编码前后比照(绿色框选的特征)
流量中抓取到的 stage:
图 24 stage 编码前后比照(绿色框选的特征)
编码后的 Stager 调试运行如下:
图 25 运行时 xor 还原解密
2.1.1 规则
发现该编码方式存在以下特征:
- fpu_instructions:fabs/ffree/fld1 等(最终作用获取当前地址,从而定位到解密位置)
- fnstenv(xd9x74x24xf4)
- Clear ecx; mov ecx, xxx 等
故其 yara 规则如下:
图 26 encode 部分 yara 规则
2.1.2 静态还原
基于这些特征,可以使用递归解密的方式还原为基础 payload 。现已支持任意编码次数以及混合编码方式的解密。
图 27 递归解密 shikata_ga_nai 类型
结语
总的来说,作为实际执行渗透攻击的急行军,Metasploit 生成的 payload 特征还是十分明显的,但是,一旦让其建立其稳定的连接,那么其之间的流量特征就会因加密而使识别变得异常困难。所以防微杜渐,才是关键。
以上,就是笔者今天带来的 Metasploit 的一些规律介绍,希望之后能带来更多有意义的分享。
━ ━ ━ ━ ━