前言
近期准备编写系列文章多维度的记录几个应用广泛且功能成熟的开源远控框架,系列文章内容包括基本执行流程、加解密技术剖析、入侵检测(流量、主机两类)。将QuasarRAT作为第一个分析对象,一是有源代码且更新频繁,逆向分析困难时可以有源码参考,二是其常被各类APT组织广泛应用,修改、编译后作为最终远控载荷用于网络攻击活动。
此篇是QuasarRAT系列的第一篇文章,记录了远控客户端木马的基本执行流程,受益匪浅。
文章很长,附一个目录,让读者了解文章大致结构。
背景
QuasarRAT是一款基于C#的开源远控工具,目前最新的版本为1.4.1。从GitHub数据显示该工具受众人数很大,且维护人员多、更新较为频繁。在2023各厂商的年度APT报告中,QuasarRAT 多次出现,被诸多APT组织用于网络攻击活动。接下来就进入正题。
简单应用示例
下载解压后首次运行,将出现一个证书创建窗口,用于创建保护服务器和客户端之间通信所需的服务器证书,可以创建或导入证书。
点击Create再保存,备份创建的quasar.p12证书文件,如果没有有效的证书备份,现有客户端将无法连接到服务器。
[Subject]
CN=Quasar Server CA
[Issuer]
CN=Quasar Server CA
[Serial Number]
008E92AF0296D813D6804DB771DA8881
[Not Before]
2024/2/28 10:58:17
[Not After]
9999/12/31 23:59:59
[Thumbprint]
2DFA8B63C594E51820CA27FFD133454ED8ED4558
“setting”栏配置服务端监听端口。
“builder”栏配置远控客户端。
-
basic settings,客户端标签、进程互斥体、无人值守模式。 -
connection setting,客户端回连目标IP:PORT、重连延迟。 -
installation setting,客户端安装位置、自启动。 -
Assembly icon,修改客户端文件图标。 -
Monitoring settings,键盘记录设置。详细配置可见官方文档放入可互通的测试机器即可上线。
逆向分析
一、混淆去除
用dnspy打开生成的客户端,发现是带混淆的,需要做去混淆操作,可以使用NETReactorSlayer。
解混淆后就利索了。
二、执行流程分析
1.函数入口
定位到函数入口点如下图。函数定义了安全协议(TLS1.2)、异常处理方式和窗体样式,然后启动了窗体应用程序的主运行循环。
main函数在末尾调用了Application.Run(new GForm0()),可见程序是一个窗体应用程序(WinForms框架),运行一个名为 GForm0 的窗体,这是应用程序的主窗体类。
2.部署初始化
程序做密钥派生、字符串解码等、文件管理、互斥体等执行初始化。
2.1 密钥派生
基于服务端创建时的初始指纹,通过密钥派生函数(PBKDF2)以及固定盐值(byte_2)生成两个密钥,一个长度为 32 字节,另一个长度为 64 字节。固定盐值硬编码在样本中。生成密钥。
初始指纹
4BA2202F1BD044C65B203861C65923A0B912D63D
固定盐值
BFEB1E56FBCD973BB219022430A57843003D5644D21E62B9D4F180E7E6C33941
2.2 字符解码
通过AES解密算法解密经过Base64编码的字符串。解密外连IP和端口号。解密公钥证书文件,证书有效期到1万年。依次解密字符、文件等入下
客户端标识,Office01
RAT版本信息,1.4.1
外连IP:port
文件路径名,SubDir
文件名,Client.exe
客户端唯一标识,a1b41ba4-4cfe-48a7-9f59-c3575aa6b70d
启动项名称,Quasar Client Startup
日志文件路径名,Logs
公钥证书文件。
2.3 初始化相关路径
设置下载文件存储路径及日志路径,路径是在生成模块配置修改的。C:UsersqianlanAppDataRoamingLogs C:UsersqianlanAppDataRoamingSubDirClient.exe
2.4 公钥HASH校验
对证书指纹byte流做SHA256运算,对比已知HASH校验公钥。如果比对失败则退出程序 第二个参数为2.16.840.1.101.3.4.2.1,应该是哈希算法的名称或OID。
2.5 互斥体创建
检查是否已经有相同互斥体的进程在运行,确保只有一个实例在运行。如果已经有相同互斥体的进程在运行,当前实例退出。
这里验证的是唯一标识。(在客户端生成时定义的)。
2.6 删除文件区域标识
清除当前文件的 “Zone.Identifier” 数据流,这样可以避免一些安全策略导致的问题,尤其是当文件被从不受信任的区域运行时。
2.7 启动项、文件属性等设置
创建了一个类的实例化对象,这个类包括开机启动项、文件管理以及隐藏等属性设置。这会根据在生成PE载荷时的配置是否执行。
2.8 任务栏图标
出始化和配置系统托盘图标。
3. 通讯初始化
创建了QuasarClient类实例化对象,参数包括外连IP:PORT,服务端公钥(证书)。创建化消息处理器对象,以处理服务器下发的各种功能指令。
3.1 判断客户端连接状态
设定一个变量用于标识客户端是否已经完成身份验证,并在连接或者断开的状态切换变量对应值。
3.2 心跳线程初始化
创建了心跳包实例。同时定义了部分HTTP参数。
BUFFER_SIZE 0x00004000
Connected false
HEADER_SIZE 0x00000004
KEEP_ALIVE_INTERVAL 0x000061A8
KEEP_ALIVE_TIME 0x000061A8
MAX_MESSAGE_SIZE 0x00500000
ProxyClients {GClass9[0x00000000]}
3.3 创建新线程连接服务端
创建一个新线程循环连接客户端。
3.3.1 首次TCP连接建立
判断当前连接状态,若没有连接则解析之前解密的外连地址。执行连接请求模块。
在建立新连接之前,断开当前连接。随后创建一个新的 Socket 实例,连接到指定的 IP 地址和端口,完成TCP三次握手,建立TCP链接。如果连接成功 (socket.Connected),则进行以下操作:
-
创建一个新的 SslStream 实例,用于在安全通道上进行通信。 -
在客户端模式下进行身份验证,使用 TLS 1.2 协议,不验证服务器证书。 -
异步开始读取数据,调用 method_1 处理连接建立成功的逻辑。 -
修改连接状态。
TLS交互通讯数据包如下。如果连接不成功,则释放 Socket 实例。随后断开TCP链接。
3.3.2 二次TCP连接建立,发送上线信息
初次链接断开后,程序会重新执行三次握手、TLS1.2加密流程,和首次通讯不同的是,客户端异步执行“ GClass31_ClientState”搜集系统基本信息,包括包括操作系统版本、用户名,地理位置等等。作为上线信息。TLS1.2加密流量数据如下。
可以看看服务端,经过解析后像用户展示上线信息。
3.3.3 循环接收服务端下发指令并执行
在服务端下发一个dir指令获取当前路径的文件信息。
在异步接收函数中断点,接收数据后,将返回收的字节数赋值给num,再定义数组array接收指令。
查看对应内存空间可见是dir指令。调用初始化的消息处理器(Message Processor)集合,在 Execute 方法中,它首先检查收到的消息是否为 DoShellExecute 类型。如果是,就调用 Execute 方法进行处理。在 Execute 方法内部,通过判断输入的命令内容,决定是创建一个新的 Shell 实例还是使用现有的实例,并调用 ExecuteCommand 方法执行相应的Shell命令。
客户端调用功能函数执行获取文件信息。逐行发送。通讯流量如下。
执行结束后恢复等待“ClientRead”事件再次触发,循环接收指令并调用功能函数处理。
这就是客户端执行的基本流程了,部分指令执行结果的发送还比较折腾,但是挺有研究价值。
下一篇将对该木马样本的加解密技术做剖析,包括内存中的加解密行为,以及通讯流量的解密。
感谢师傅有耐心读完,点个赞吧~
原文始发于微信公众号(帅仔回忆录):Quasar RAT客户端木马执行流程逆向分析