暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

从Reverse_HTTP浅析Metasploit的通信协议

启明星辰金睛安全研究团队 2020-07-06
2482
Metasploit是一个漏洞框架,简称叫做MSF。Metasploit作为全球最受欢迎的工具,不仅仅是因为它的方便性和强大性,更重要的是它的框架。它允许使用者开发自己的漏洞脚本,从而进行测试。至今为止,Framework版本已集成2038个Exp以及562 种payload。
接下来将从众多payload中的Reverse_HTTP分析MSF与受害机器之间的通信交互,如有错误之处,还请多多包涵。
MSF IP地址:192.168.8.129
靶机IP地址:192.168.8.128

流量分析:

在MSF控制台使用以下命令创建一个简单的Meterpreter/Reverse_HTTP payload,为方便测试直接将payload生成为exe文件。

启动MSF监听:

靶机启动抓包工具Wireshark,执行生成的exe文件Reverse_HTTP_Test.exe。
成功上线:

在Wireshark中可以看到靶机(192.168.8.128)与MSF(192.168.8.129)建立两次连接:

第一次连接使用URL:/5HHq2cxhrtZWbVdsCW1oFASMHKVEQwUtg3pXg729向MSF发起一个空的GET请求,MSF则返回一个PE文件。

第二次连接则使用固定的URL:/5HHq2cxhrtZWbVdsCW0V9Q_wv3zwzdOkgbyufQq/与MSF进行数据通信:

从流量侧,Reverse_HTTP的上线流程可简单总结为:靶机空GET请求->MSF回应PE文件->靶机与MSF建立长连接,进行C2通信交互。整个过程中需要关注三个地方:
  1. 两次连接中的URL有什么特殊意义?靶机与MSF之间是否使用URL进行数据通信?

  2. MSF返回的PE文件是什么?

  3. 第二次连接中靶机与MSF之间的通信数据是什么?


URL:

在生成的exe文件Reverse_HTTP_Test.exe中可以找到第一次连接的URL字符串,其被硬编码在exe文件中。可以确定该URL不会负责MSF的通信,唯一的意义可能是与GET请求组合表示向MSF请求PE文件:

第二次连接使用的URL虽然没有被硬编码,但URL的前半部分与第一次连接的URL重合,并且后续的HTTP请求使用的URL相同。那么,其大可能只是为了区分两次连接,表示当前已经请求完毕PE文件,进入第二阶段的C2通信。


Stager:

在分析MSF返回的PE文件之前,需要先了解MSF中Payloads的工作机制。在MSF中,生成的Payloads被称为Stager。
Stager功能单一,负责连接MSF请求真正的远控后门metsrv.DLL。请求的DLL文件并不会落地,而是保存在Stager申请的一块内存中。在metsrv.DLL接收完毕后,Stager跳转至该内存执行,跳转地址为metsrv.DLL的导出函数ReflectiveLoader()。导出函数则会使用反射式注入将该DLL映射至内存,而后跳转DLLMain执行。

metsrv.DLL加载执行后,将会接管Stager与MSF的通信,进入第二阶段的C2交互。在本例中,靶机与MSF建立的第一次连接,就是Stager(即Reverse_HTTP_Test.exe)在向MSF服务器请求metsrv.DLL,那么很明显MSF返回的PE文件便就是metsrv.DLL。
但是,MSF为什么要使用Stager呢?直接让metsrv.DLL在目标机器上执行不是更快,Stager先下载再执行会不会多此一举?
Stager在一些攻击行动中是很有必要的。因为在很多攻击成功利用漏洞后,对于能加载进内存并执行的数据大小存在严格限制,而Stager文件体积显要比metsrv.DLL 小的多,更加轻便。另外,当攻击被防御设备拦截时,暴露的是Stager文件而不会是核心文件 metsrv.DLL。即使仍然可以通过分析Stager文件来获取核心文件,但也给攻击者争取了反应时间,足够用来迁移或销毁其C2设施。

加密协议:

在开始第二阶段的正式C2通信之前,MSF服务器需要与靶机上的Meterpreter客户端(即metsrv.dll)进行密钥协商:
MSF服务器生成一个2048位的RSA密钥对(包括公钥和私钥)。
公钥被添加到TLV编码的数据结构中,然后与core_negotiate_tlv_encryption命令一起发送到Meterpreter客户端。
Meterpreter客户端接收数据包,解析并提取公钥
Meterpreter客户端随机生成256位AES密钥,然后使用服务端提供的公钥对AES密钥进行加密。
Meterpreter客户端用一个包含加密AES256密钥的包响应MSF。
密钥协商成功后,双方丢弃生成的RSA密钥对,使用协商的AES秘钥加密所有未来的数据包,并在数据包上设置加密标志。
在通信过程中,MSF服务器与Meterpreter客户端所有的通信数据都使用了严格的TLV编码并且使用XOR作为最外层加密,XORKey为每个数据包的首个4字节。最终的数据包结构如下:

会话ID:标识会话的GUID。双方未建立会话时,此GUID为空(所有null字节),在建立会话后会生成一个新的GUID ,并将其传递给Meterpreter客户端。
加密标志:DWORD标志集,用于指示此数据包是否加密及加密方式。如果为0,则从长度开始,数据包的结构与上相同。如果设置了该标志位,则会改变数据包的结构。例如:加密标志设置为AES256,即DWORD值为1,数据包结构将变更为:

16字节的初始化向量用于AES256解密,在这16个字节之后是完全加密的TLV有效负载。
使用前4个字节对MSF服务器返回的数据包进行解密:

由于密钥协商阶段会话ID为空,所以在TLV_Data_Values中写入一个临时的session ID。

当Meterpreter客户端解析出RSA公钥后,将随机生成AES256密钥,并使用RSA公钥加密回复MSF服务器:

MSF服务器解密出AES256密钥后,双方将会使用该密钥进行一次测试通信,以验证密钥的可行性。验证通过后,使用协商的AES密钥加密所有未来的数据包并设置标志位。


后续:

尽管MSF服务器与Meterpreter之间的通信使用三层加密保护措施,但是仍有办法对通信数据进行解密。
比如中间人攻击(MITM):在Meterpreter解析MSF服务器发送的RSA公钥前,将其替换为自己的公钥。Meterpreter无法确定RSA公钥是否来自MSF服务器,而会使用已被替换的RSA公钥对AES密钥加密。在MSF接收来自Meterpreter的AES密钥前,使用自己的RSA私钥解密提取AES密钥,接着用MSF提供的RSA公钥对AES密钥加密还原(确保MSF服务器能够正常解析到AES密钥),提取AES密钥后即可对通信数据进行解密。
最简单的实现方法,在动态调试Meterpreter的Payload时,设置网络收发函数的断点,修改接收和发送的数据,即可提取出AES密钥,从而对后续流量进行解密。
文章转载自启明星辰金睛安全研究团队,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论