前所未有:微软 SQL Server 被黑客组织安上了后门 skip-2.0

安全公司 ESET 发布报告,说明了微软 SQL Server (MSSQL) 被黑客组织 Winnti Group 安后门的研究结果。原文来自ESET

ESET 一段时间以来都在追踪 Winnti Group 的攻击活动情况。Winnti Group 至少活跃于2012年并发动了多起高级别的针对视频游戏和软件行业的供应链攻击。最近,我们发现了针对微软 SQL (MSSQL) 的后门,可导致攻击者在受攻陷的组织机构内站稳脚跟。该后门和 Winnti Group 在2019年10月使用过的另外一款工具 PortReuse 后门之间存在很多相似之处,如使用了同样的自定义数据包和 VMProtected 启动器,这也是我们为什么认为该后门是 Winnti Group 安的原因所在。

今年年初,我们收到了作者开发的新后门 skip-2.0 的样本,它也是 Winnti Group 武器库的一部分。该后门针对的是 MSSQL Server 11 和12,可使攻击者通过使用一个魔力密码隐秘地连接至任何 MSSQL 账户,同时自动将这些连接对日志隐藏不可见。这类后门可导致攻击者隐秘地复制、修改或删除数据库内容。例如,该后门可用于操纵游戏币获取金钱利益。该黑客组织曾被指操纵游戏币数据库。就我们所知,skip-2.0 是首个公开记录的 MSSQL Server 后门。注意,即使MSSQL Server 11 和12 并非最新版本(分别发布于2012年和2014年),但根据 Censys 的数据可看出,这两个版本是最常用的版本。

最近,我们发布一份白皮书(见文末地址),说明了 Winnti Group 的武器库,其中暴露了此前从未公开过的一个后门 PortReuse。该后门使用的打包程序和ESET 公司在2019年3月在受攻陷视频游戏中内嵌的 payload 使用的打包程序一样。VMProtected 启动器释放 PortReuse 后门,还被用于启动最新的 ShadowPad 版本。在当时的上下文,我们找到了一款被开发人员命名为 skip.2-0 的新工具。它使用了相同的 VMProtected 启动器和 Winnti Group 的自定义打包程序并与该黑客组织工具集的其它样本之间存在很多相似之处。这也让我们认为 skip-2.0 属于该工具集。

本文主要讨论这个MSSQL Server 后门的技术详情和功能,同时说明 skip.2-0 和 Winnti Group 已知的武器库之间存在的技术相似之处,特别是与 PortReuse 后门和 ShadowPad之间存在的相似之处。

VMProtected 启动器

我们是在查找VMProtected 启动器时发现的 skip-2.0,它的payload 通常要么是 PortReuse 要么是 ShadowPad。

嵌入式payload

和加密的PortReuse 和 ShadowPad payload 一样,skip-2.0 也内嵌在 VMProtected 启动器的叠加层上,如下图1所示:

加密

该Payload 加密和其它VMProtected 启动器中使用的加密机制一样,都是RC5加密算法,由 VolumeID 派生的 key 和字符串 f@Ukd!rCto R$组成。

持久性

在PortReuse 和 ShadowPad 案例中,启动器很可能通过利用被安装在 C:\Windows\System32\TSVIPSrv.DLL  的一个 DLL 劫持漏洞实现持久性。结果,标准的 Windows SessionEnv 服务在系统启动时加载 DLL。

Winnti Group 的自定义打包程序

解密之后,内嵌的payload 实际上就是Winnti Group 的自定义打包程序。该打包程序用于打包 PortReuse 后门以及内嵌在受攻陷视频游戏中的 payload。

打包程序配置

该打包程序配置包含打包二进制的解密密钥以及其原始文件名称、大小以及执行类型(EXE 或 DLL)。该 payload 的打包程序配置如下表1所示:

从打包程序配置可看出,该 payload 被称为 Inner-Loader。Inner-Loader 是该黑客组织武器库中一款注入器的名称,用于将 PortReuses 后门注入到侦听某个特定端口的进程中。除了具有相同的名称外,通过分析这个 payload 得出,它是 Inner-Loader 注入器的另外一个变体。

Inner-Loader 注入器

这个Inner-Loader 的变体并没有查找侦听某个特定端口的进程(如注入 PortResuse 后门时的情况那样),而是查找 MSSQL Server 的一个常规进程名称 sqlserv.exe。如找到,则 Inner-Loader 将 payload 注入此进程中。而该 payload 也与自定义打包程序打包。Payload 的打包程序配置如下表2:

这个被注入的payload 的原始文件名称是 skip-2.0.dll。

Skip-2.0

由Inner-Loader 注入并启动后,skip-2.0首先检查它是否在 sqlserv.exe 进程中执行,如是,则检索由 sqlserv.exe 加载的 sqllang.dll 的处理程序。之后继续查找并从该 DLL 中钩出多个函数。如下图2说明的是skip-2.0 的攻陷链。

钩 sqllang.dll

Skip-2.0 使用的钩子程序和 NetAgent 使用的非常相似。NetAgent 是安装网络钩子的PortReuse模块。这个钩子库基于多个开源钩子框架所使用的 disorm 开源反汇编程序。具体而言,反汇编库用于正确地计算被钩的指令的大小。如下图3所示,NetAgent和skip-2.0 所使用的钩子程序几乎是一样的。

这是其中一处显著的不同之处:skip-2.0的钩子函数提取钩子的地址并安装为一个参数,而对于 NetAgent 而言,钩子安装的地址是硬编码的。产生不同的原因在于,skip-2.0必须钩出 sqllang.dll 中的多个函数才能正常运行,而 NetAgent 只是针对单个函数。

要定位每个被钩的sqllang.dll 函数,skip-2.0 首先通过解析 PE 头部信息马上检索被加载到内存中的 DLL 的大小(其真实大小)。之后需要在 sqllang.dll 中匹配的字节数组被初始化,如下图4所示。一旦找到第一个匹配该字节的地址,该钩子就会使用图3所示的程序。

随后,成功的钩子安装就会以明文形式记录在位于硬编码路径 C:\Windows\Temp\TS_2CE1.tmp 上的一个日志文件中,如下图5所示。

如果未找到目标函数,则钩子安装程序将使用一组不同的字节模式搜索后备函数。

使用匹配字节序列而非使用静态偏移量以定位目标函数的地址,加上使用备用字节序列,可使 skip-2.0 能够对 MSSQL 更新更具弹性并有可能针对多个 sqllang.dll 更新。

一个密码吃遍天

Skip-2.0所针对的函数和身份验证以及事件日志相关。目标函数包括:

  • CPwdPolicyManager::ValidatePwdForLogin
  • CSECAuthenticate::AuthenticateLoginIdentity
  • ReportLoginSuccess
  • IssueLoginSuccessReport
  • FExecuteLogonTriggers
  • XeSqlPkg::sql_statement_completed::Publish
  • XeSqlPkg::sql_batch_completed::Publish
  • SecAuditPkg::audit_event::Publish
  • XeSqlPkg::login::Publish
  • XeSqlPkg::ual_instrument_called::Publish

第一个函数(CPwdPolicyManager::ValidatePwdForLogin)最耐人寻味,它的作用是验证既定用户的密码。该函数的钩子检查用户提供的密码是否和魔力密码匹配,如不匹配,则原始函数不会被调用且钩子返回0,使得即使在未提供正确密码的情况下也能进行连接。然后设置一个全局标志,接受负责事件日志的其它钩子函数检查。对应的反汇编程序如图6所示。在设置全局标志的情况下,钩子日志函数将在不调用其相应的原始函数的情况下静默返回,因此该动作不会被记录。如提供的是其它密码,则会调用原始函数。

从硬编码密码来看,ESET 在此前发现的 SSH 后门中也使用了类似的后门技术。区别在于,skip-2.0 被安装在内存中,而SSH 后门中,sshd可执行文件在执行前遭修改。

另外,CSECAuthenticate::AuthenticateLoginIdentity 会被从钩子代码中调用但钩子总是返回0。如果使用了魔力密码登录,则钩子ReportLoginSucess 和 IssueLoginSuccessReport 不会调用原始函数。同样的行为也适用于FEExecuteLogonTriggers。其它的日志函数如 XeSqlPkg::sql_statement_completed::Publish或XeSqlPkg::sql_batch_completed::Publish 也会在用户使用魔力密码登录的情况下被禁用。多个审计事件也会遭禁用,包括SecAuditPkg::audit_event::Publish、XeSqlPkg::login::Publish 和XeSqlPkg::ual_instrument_called::Publish。

这一系列钩子使攻击者不仅能够通过使用一个特殊的密码在受害者 MSSQL Server 11 和12上获得持久性。为了查看某个特定的 sqllang.dll 版本是否遭 skip-2.0 攻击(即匹配字节模式),我们创建了一个 YARA 规则。

和 Winnti Group 的关联

我们看到 skip-2.0 和 Winnti Group 武器库其它工具之间的很多相似指出。Skip-2.0后门的 VMProtected 启动器、自定义打包程序、Inner-Laoder 注入器和钩子框架都是 Winnti Group 已知工具集的一部分。因此我们认为 skip-2.0 是Winnti Group 工具集的一部分。

结论

Skip-2.0后门是Winnti Group 武器库的一部分,和该组织已知的工具集之间存在很多相似之处,可使攻击者在 MSSQL Server 上实现持久性。鉴于安装这些钩子需要具备管理员权限,因此必须在已遭攻陷的 MSSQL Server 上安装 skip-2.0 才能实现持久性和隐秘性。