继续描述图 6 中的流程 - 第 8 步...... MokInstaller UEFI应用程序继续为BlackLotus UEFI bootkit设置持久性并覆盖利用的轨迹:
·内核驱动负责
o部署链的下一个组件——HTTP下载器。
o在终止的情况下保持加载程序活动。
o保护 bootkit文件不被从ESP中删除。
o执行额外的内核有效负载,如果HTTP下载程序如此指示。
o卸载 bootkit,如果HTTP下载程序如此指示。
·HTTP下载器负责:
o与其C&C通信。
o执行从C&C接收到的命令。
o下载并执行从C&C接收到的有效载荷(支持内核有效载荷和用户模式有效载荷)。
从安装程序到HTTP下载程序的完整执行流程(简化)如图 13 所示。我们将在下一节中更详细地描述这些单独的步骤。
图 13. 显示 BlackLotus UEFI bootkit 执行的图表
执行步骤如下(这些步骤如图 13 所示):
1.作为第一步,UEFI固件执行默认的Windows引导选项,该文件通常存储在EFIMicrosoftBootbootmgfw.efi中。正如我们之前描述的(Bootkit 持久性部分,8.a),MokInstaller二进制文件用合法签名的shim替换了这个文件。
2.执行shim时,它会读取MokList NVRAM变量,并使用攻击者先前存储在其中的证书来验证第二阶段引导加载程序——位于EFIMicrosoftBootgrubx64.efi中的自签名 BlackLotus UEFI bootkit .
3.验证后,shim将执行 bootkit。
4.bootkit从创建 Boot-only VbsPolicyDisable NVRAM变量开始。如此处所述,此变量在启动期间由 Windows操作系统加载程序评估,如果已定义,则不会初始化核心 VBS 功能,例如 HVCI 和 Credential Guard。
5.在以下步骤 (5.a–e) 中,bootkit继续使用 UEFI bootkit使用的通用模式。它拦截典型 Windows启动流程中包含的组件的执行,例如Windows启动管理器、Windows操作系统加载程序和 Windows操作系统内核,并在内存中挂钩它们的一些功能。作为奖励,它还尝试通过修补其某些驱动程序来禁用Windows Defender。所有这些都是为了在操作系统启动过程的早期阶段实现其有效负载的执行,并避免被发现。以下功能已挂钩或修补:
a.bootmgfw.ef或bootmgr.efi中的ImgArchStartBootApplication:此函数通常被bootkits 挂钩,以捕捉Windows操作系统加载程序 ( winload.efi ) 加载到内存但仍未执行的时刻 - 这是正确的时刻执行更多的内存修补。
b.winload.efi中的BlImgAllocateImageBuffer:用于为恶意内核驱动程序分配额外的内存缓冲区。
c.winload.efi中的OslArchTransferToKernel:钩住操作系统内核和一些系统驱动程序已经加载到内存中但仍未执行的时刻 - 这是执行更多内存中修补的完美时刻。下面提到的驱动程序在此挂钩中进行了修补。来自此挂钩的代码负责在内存中查找合适的驱动程序,如图 14 所示。
d.WdBoot.sys和WdFilter.sys: BlackLotus 修补了WdBoot.sys和WdFilter.sys的入口点——分别是 Windows Defender ELAM 驱动程序和 Windows Defender 文件系统过滤驱动程序——以立即返回。
e.disk.sys: bootkit 挂钩disk.sys驱动程序 的入口点,以在系统初始化的早期阶段执行 BlackLotus 内核驱动程序。
图 14. OslArchTransferToKernel挂钩的 Hex-Rays 反编译代码——修补 Windows Defender 驱动程序并搜索disk.sys入口点
内核驱动程序负责四个主要任务:
·将 HTTP 下载程序注入winlogon.exe并在线程终止时重新注入它。
·保护部署在 ESP 上的 bootkit 文件不被删除。
·解除用户模式 Windows Defender 进程MsMpEngine.exe。
·与 HTTP 下载程序通信,并在必要时执行任何命令。
让我们一一看看。
内核驱动程序负责部署HTTP 下载程序。当驱动程序启动时,它会等到名为winlogon.exe的进程启动,然后再执行任何其他操作。进程启动后,驱动程序会解密 HTTP 下载程序二进制文件,将其注入winlogon.exe的地址空间,并在新线程中执行。然后,驱动程序会定期检查线程是否仍在运行,并在必要时重复注入。如果驱动程序检测到内核调试器,则不会部署 HTTP 下载器。
为了保护位于ESP 上的 bootkit 文件,内核驱动程序使用了一个简单的技巧。它打开它想要保护的所有文件,复制并保存它们的句柄,并使用ObSetHandleAttributes内核函数将HandleFlags ( OBJECT_HANDLE_FLAG_INFORMATION )参数中的ProtectFromClose标志指定为 1——从而保护句柄不被任何其他进程关闭。这将阻止任何删除或修改受保护文件的尝试。以下文件受到保护:
·ESP:EFIMicrosoftBootwinload.efi
·ESP:EFIMicrosoftBootbootmgfw.efi
·ESP:EFIMicrosoftBootgrubx64.efi
如果用户尝试删除这些受保护的文件,将会发生如图15 所示的情况。
图15. 尝试删除受 BlackLotus 驱动程序保护的文件
作为另一层保护,以防用户或安全软件能够取消设置保护标志并关闭句柄,内核驱动程序会持续监视它们,如果有任何句柄,则通过调用 KeBugCheck(INVALID_KERNEL_HANDLE) 函数导致BSOD不存在了。
内核驱动程序还尝试解除主 Windows Defender 进程——MsMpEng.exe。它通过为每个进程设置SE_PRIVILEGE_REMOVED属性来删除所有进程的令牌特权。因此,Defender 进程应该无法正常执行其工作(例如扫描文件)。但是,由于此功能实现不佳,可以通过重新启动MsMpEng.exe进程使其失效。
内核驱动程序能够通过使用命名的事件和部分与HTTP 下载程序进行通信。使用的命名对象的名称是根据受害者的网络适配器 MAC 地址(以太网)生成的。如果八位位组的值小于 16,则向其添加 16。生成的对象名称的格式可能因样本不同而不同。例如,在我们分析的一个样本中,对于 MAC 地址00-1c-0b-cd-ef-34,生成的名称将是:
·BaseNamedObjects101c1b:用于命名部分(仅使用 MAC 的前三个八位字节)
·BaseNamedObjects Z 01c1b:对于命名事件——与 Section 相同,但 MAC 地址的第一位数字被替换为Z
如果HTTP 下载器想要将一些命令传递给内核驱动程序,它只需创建一个命名部分,在其中写入一个带有相关数据的命令,然后通过创建一个命名事件等待驱动程序处理该命令并等待直到驱动程序触发(或发出信号)它。
驱动程序支持以下不言自明的命令:
·安装内核驱动
·卸载黑莲花
细心的读者可能会注意到这里的BlackLotus 弱点——即使 bootkit 保护其组件不被删除,内核驱动程序也可以通过创建上述命名对象并向其发送卸载命令来欺骗以完全卸载 bootkit。
最后一个组件负责与C&C 服务器通信并执行从它接收到的任何 C&C 命令。我们能够发现的所有有效载荷都包含三个命令。这些命令非常简单,正如部分名称所暗示的那样,它主要是关于使用各种技术下载和执行额外的有效负载。
为了与其C&C 通信,HTTP 加载程序使用 HTTPS 协议。通信所需的所有信息都直接嵌入到下载程序二进制文件中——包括 C&C 域和使用的 HTTP 资源路径。与 C&C 服务器通信的默认间隔设置为一分钟,但可以根据来自 C&C 的数据进行更改。与 C&C 的每个通信会话都以向其发送信标 HTTP POST 消息开始。在我们分析的示例中,可以在 HTTP POST 标头中指定以下 HTTP 资源路径:
·/network/API/hpb_gate[.]php
·/API/hpb_gate[.]php
·/gate[.]php
·/hpb_gate[.]php
信标消息数据以checkin = string 为前缀,包含有关受感染机器的基本信息——包括自定义机器标识符(称为HWID)、UEFI 安全启动状态、各种硬件信息,以及一个似乎是 BlackLotus 的值内部版本号。HWID由机器 MAC 地址(以太网)和系统卷序列号生成。加密前的消息格式如下所示
"HWID":"%s",
"Session":"%lu",
"Owner":"%s",
"IP":"%s",
"OS":"%s",
"Edition":"%s",
"CPU":"%s",
"GPU":"%s",
"RAM":"%lu",
"Integrity":"%lu",
"SecureBoot":"%i",
"Build":"%lu"
}
在将消息发送到C&C 之前,首先使用嵌入式 RSA 密钥对数据进行加密,然后进行 URL 安全的base64 编码。在分析过程中,我们发现样本中使用了两个不同的 RSA 密钥。图 17 显示了此类 HTTP 信标请求的示例。
图17. 信标 HTTP POST 消息示例(由来自 VirusTotal 的示例生成——具有本地 IP 而不是真实 C&C 地址的示例)
作为对信标消息的响应,从C&C 接收的数据应以两字节的魔法值 HP 开头;否则,不会进一步处理响应。如果magic值正确,则以上述HWID字符串为密钥,使用CBC模式的256位AES对magic值后面的数据进行解密。
解密后的消息类似于信标,是一个JSON格式的字符串,并指定了一个命令标识符(简称Type)和各种附加参数,例如:
·C&C通信间隔
·使用的执行方法
·负载文件名
·基于文件扩展名的负载类型(支持.sys、.exe或.dll )
·应该用于请求下载有效负载数据的身份验证令牌
·用于解密有效负载数据的 AES 密钥
表2 中列出了所有受支持的命令及其说明。
|
|
|
|
|
|
|
|
在这些命令中,C&C可以指定有效载荷是应该在执行之前先放到磁盘上,还是直接在内存中执行。在涉及将文件拖放到磁盘的情况下,操作系统卷上的ProgramData文件夹用作目标文件夹,文件名和扩展名由C&C服务器指定。在直接在内存中执行文件的情况下,svchost.exe被用作注入目标。当 C&C 发送要求内核驱动程序协作的命令,或者操作员想要在内核模式下执行代码时,将使用与 HTTP 下载程序通信部分中描述的机制。
为了更难检测和分析这种恶意软件,它的作者试图将标准文件工件(例如文本字符串、导入或其他未加密的嵌入式数据)的可见性限制在最低限度。以下是所用技术的总结。
·字符串和数据加密
o示例中使用的所有字符串都使用简单的密码进行加密。
o所有嵌入文件均使用 CBC 模式的 256 位 AES 加密。
o单个文件的加密密钥可能因样本而异。
o除了 AES 加密之外,一些文件还使用 LZMS 进行压缩。
·仅运行时 API 解析
o在所有示例中(如果适用),Windows API 始终在运行时以独占方式解析,并且函数哈希而不是函数名称用于在内存中查找所需的 API 函数地址。
o在某些情况下,直接系统调用指令调用用于调用所需的系统功能。
·网络通讯
o使用 HTTPS 进行通信。
oHTTP 下载程序发送到 C&C 的所有消息都使用嵌入式 RSA 公钥加密。
o从 C&C 发送到 HTTP 下载器的所有消息都使用从受害者机器环境派生的密钥或使用 C&C 提供的 AES 密钥进行加密。
·反调试和反 VM 技巧——如果使用的话,通常放在入口点的开头。仅使用随意的沙箱或调试器检测技巧。
·首先,当然,必须让系统及其安全产品保持最新状态 – 以增加威胁在开始时就被阻止的机会,然后才能实现预操作系统持久性。
·然后,为防止使用已知易受攻击的 UEFI 二进制文件绕过 UEFI 安全启动而需要采取的关键步骤是在 UEFI 吊销数据库 (dbx) 中吊销它们——在Windows 系统上,dbx更新应使用 Windows 更新分发。
·问题在于,广泛使用的 Windows UEFI 二进制文件的撤销可能导致数以千计的过时系统、恢复映像或备份无法启动——因此,撤销通常需要很长时间。
·请注意,吊销 BlackLotus 使用的 Windows 应用程序会阻止安装 bootkit,但由于安装程序会将受害者的引导加载程序替换为已吊销的引导加载程序,这可能会使系统无法启动。要在这种情况下进行恢复,重新安装操作系统或仅进行 ESP 恢复即可解决问题。
·如果在设置 BlackLotus 持久性之后发生撤销,bootkit 将保持功能,因为它使用带有自定义 MOK 密钥的合法填充程序来实现持久性。在这种情况下,最安全的缓解解决方案是重新安装 Windows 并使用 mokutil 实用程序删除攻击者注册的 MOK 密钥(由于在启动期间用户必须与 MOK 管理器交互,因此需要物理存在才能执行此操作)。
原文始发于微信公众号(山石网科安全技术研究院):首个可绕过Win11安全启动保护UEFI恶意软件分析(下)
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论