Microsoft 继续与合作伙伴和客户合作,以跟踪和扩展我们对我们称为 NOBELIUM 的威胁行为者的了解,该行为者是SUNBURST 后门、TEARDROP 恶意软件和相关组件的幕后黑手。正如我们之前所说,我们怀疑 NOBELIUM 可以利用其活动中经常展示的重要运营资源,包括定制的恶意软件和工具。2021 年 3 月,我们分析了 NOBELIUM 的GoldMax、GoldFinder 和 Sibot 恶意软件,它用于分层持久性。然后,我们在 5 月发布了另一篇文章,当时我们分析了演员的早期工具集,包括EnvyScout、BoomBox、NativeZone 和 VaporRage。
此博客是对新检测到的 NOBELIUM 恶意软件的另一项深入分析:Microsoft 威胁情报中心 (MSTIC) 将其称为FoggyWeb的一个后利用后门。如之前的博客所述,NOBELIUM 采用多种策略来进行凭据盗窃,目的是获得对 Active Directory 联合服务 ( AD FS ) 服务器的管理员级别访问权限。一旦 NOBELIUM 获得凭据并成功入侵服务器,攻击者就会依赖该访问权限来维持持久性并使用复杂的恶意软件和工具加深其渗透。NOBELIUM 使用 FoggyWeb 远程窃取受感染 AD FS 服务器的配置数据库、解密的令牌签名证书和令牌解密证书,以及下载和执行其他组件。早在 2021 年 4 月,就已经在野外观察到 FoggyWeb 的使用。
Microsoft 已通知所有被观察到成为此活动目标或受到威胁的客户。如果您认为您的组织已被入侵,我们建议您
Microsoft 安全产品已针对此恶意软件实施检测和保护。Azure Sentinel的危害指标 (IOC)、缓解指南、检测详细信息和搜寻查询微软 365在此分析结束时和产品门户中提供了 Defender 客户。Active Directory 联合身份验证服务 ( AD FS ) 服务器在本地运行,客户还可以遵循有关保护 AD FS 服务器免受攻击的详细指南。
FoggyWeb 是一种被动且具有高度针对性的后门,能够从受感染的 AD FS 服务器远程窃取敏感信息。它还可以从命令和控制 (C2) 服务器接收其他恶意组件,并在受感染的服务器上执行它们。
在破坏 AD FS 服务器后,观察到 NOBELIUM 在系统上删除了以下两个文件(需要管理员权限才能将这些文件写入下面列出的文件夹):
FoggyWeb 存储在加密文件Windows.Data.TimeZones.zh-PH.pri中,而恶意文件version.dll可以说是它的加载器。AD FS 服务可执行文件Microsoft.IdentityServer.ServiceHost.exe通过涉及核心公共语言运行时 (CLR) DLL 文件的DLL 搜索顺序劫持技术加载所述 DLL文件(在 FoggyWeb 加载程序部分中有详细描述)。该加载程序负责加载加密的 FoggyWeb 后门文件,并利用自定义的轻量级加密算法 (LEA) 例程来解密内存中的后门。
在对后门进行去混淆后,加载程序继续在 AD FS 应用程序的执行上下文中加载 FoggyWeb。加载程序是一个非托管应用程序,它利用 CLR 托管接口和 API 将后门程序(一个托管 DLL)加载到执行合法 AD FS 托管代码的同一应用程序域中。这将授予对 AD FS 代码库和资源的后门访问权限,包括 AD FS 配置数据库(因为它继承了访问配置数据库所需的 AD FS 服务帐户权限)。
加载 version.dll 后 Microsoft.IdentityServer.ServiceHost.exe 的结构示意图
加载后,FoggyWeb 后门(最初由其开发人员命名为Microsoft.IdentityServer.WebExtension.dll)充当被动且持久的后门,允许滥用安全断言标记语言 (SAML) 令牌。后门为参与者定义的 URI 配置 HTTP 侦听器,这些 URI 模仿目标的 AD FS 部署使用的合法 URI 的结构。自定义侦听器被动监视从 Intranet/Internet 发送到 AD FS 服务器的所有传入 HTTP GET 和 POST 请求,并拦截与参与者定义的自定义 URI 模式匹配的 HTTP 请求。此版本的 FoggyWeb 为以下硬编码 URI 模式(可能因目标而异)配置侦听器:
上面的每个 HTTP GET/POST URI 模式都对应一个 C2 命令:
下图说明了攻击者用来与位于受感染的面向 Internet 的 AD FS 服务器上的 FoggyWeb 后门通信的方法。
由于 FoggyWeb 在主 AD FS 进程的上下文中运行,因此它继承了访问 AD FS 配置数据库所需的 AD FS 服务帐户权限。这与必须在 AD FS 服务帐户的用户上下文下执行的工具(如ADFSDump)形成对比。此外,由于 FoggyWeb 与 AD FS 托管代码加载到相同的应用程序域中,因此它可以通过编程方式访问合法的 AD FS 类、方法、属性、字段、对象和组件,随后 FoggyWeb 会利用这些来促进其恶意操作. 例如,这允许 FoggyWeb 无需连接到 WID 命名管道或手动运行 SQL 查询来检索配置信息(例如,获取来自配置数据的EncryptedPfx blob)。FoggyWeb 也与 AD FS 版本无关;它不需要跟踪旧版与现代配置表名称和架构、命名管道名称以及 AD FS 的其他版本相关属性。
文件version.dll是一个恶意加载器,负责从文件系统中加载一个加密的后门文件,解密后门文件,并将其加载到内存中。此恶意 DLL 与位于*%WinDir%\System32*文件夹中的合法 Windows DLL 共享名称,旨在放置在 AD FS 主文件夹*%WinDir%\ADFS*中,AD FS 服务可执行Microsoft。IdentityServer.ServiceHost.exe位于(出于本节后面所述的原因)。
启动 AD FS 服务 ( adfssrv ) 后,将执行服务可执行文件Microsoft.IdentityServer.ServiceHost.exe。作为基于 .NET 的托管应用程序,Microsoft.IdentityServer.ServiceHost.exe导入名为mscoree.dll的非托管 Windows DLL 。
文件mscoree.dll动态加载另一个名为**mscoreei.dll的非托管 Windows/CLR DLL 。如下图,mscoreei.dll有一个名为**version.dll的延迟加载导入(Delay Import)。
观察到具有现有管理权限的 NOBELIUM在 AD FS 服务可执行文件Microsoft.IdentityServer.ServiceHost.exe所在的*%WinDir%\ADFS\文件夹中放置了一个名为version.dll的恶意加载程序。重新启动系统或 AD FS 服务后,Microsoft.IdentityServer.ServiceHost.exe会加载mscoree.dll,而后者又会加载mscoreei.dll。如上所述,mscoreei.dll有一个名为version.dll的延迟加载导入。一旦加载,而不是从%WinDir%\System32*文件夹*mscoreei.dll加载合法的version.dll加载攻击者在%WinDir%\ADFS*文件夹中植入的恶意version.dll(简称DLL搜索顺序劫持),如下调用栈所示。
恶意加载程序version.dll充当所有合法**version.dll导出函数调用的代理。如下所示,它导出了与version.dll的合法版本相同的 17 个函数名。
恶意version.dll的导出函数都是短存根,它们调用标记为TrampolineFunction的单个 trampoline 函数,如下面的屏幕截图所示。
下面是蹦床功能的伪代码。
此蹦床功能负责以下工作:
trampoline 函数通过保存某些 CPU 寄存器的值,从version.dll的合法版本中保留用于该函数的参数/寄存器的值。它首先将它们压入堆栈,然后调用上面的LoadDecryptExecuteBackdoor()函数,然后在将执行从version.dll的合法版本转移到函数之前恢复它们。
调用时,*LoadDecryptExecuteBackdoor()会尝试创建一个名为{2783c149-77a7-5e51-0d83-ac0566daff96}*的 Windows 事件,以确保只有一个加载程序副本在系统上主动运行。然后在一个新线程中检查是否存在以下文件(硬编码路径字符串):
C:\Windows\SystemResources\Windows.Data.TimeZones\pris\Windows.Data.TimeZones.zh-PH.pri
Windows.Data.TimeZones.zh-PH.pri是一个加密的后门文件,放置在上面的文件夹中。MSTIC 将这个后门文件称为 FoggyWeb,我们的分析在下一节。
Microsoft.IdentityServer.ServiceHost.exe本身是一个非托管 Windows 可执行文件,在编译高级 AD FS 托管代码时生成。执行时, Microsoft.IdentityServer.ServiceHost.exe中的非托管代码利用公共语言运行时 (CLR) 在虚拟运行时环境中运行托管 AD FS 代码。此虚拟运行时环境由一个或多个应用程序域组成,它们为运行时环境提供了一个隔离单元,并允许不同的应用程序在进程内的不同容器中运行。托管 AD FS 代码在虚拟运行时环境内的应用程序域内执行。
FoggyWeb 后门(也是托管 DLL)旨在与合法的 AD FS 代码一起运行(即,在同一应用程序域中)。这意味着 FoggyWeb 加载程序要在 AD FS 代码旁边加载后门,它需要获得对 AD FS 代码在其中执行的同一应用程序域的访问权限。由于 FoggyWeb 加载程序version.dll是非托管应用程序,因此它无法直接访问托管 AD FS 代码在其中执行的虚拟运行时环境。加载程序克服了这一限制,并通过利用 CLR 托管接口和 API 访问执行 AD FS 代码的虚拟运行时环境,将后门与 AD FS 代码一起加载。
加载程序执行以下高级操作:
解密每个 16 字节密码块后,加载程序使用以下 XOR 密钥对每个单独的解密/明文块进行解码:
这相当于首先 LEA 解密整个文件,然后对解密的数据进行 XOR 解码(而不是对每个单独的 16 字节块进行解密和 XOR 解码)。
在执行周期的这一点上,FoggyWeb DLL 被加载到一个或多个运行合法 AD FS 代码的应用程序域中。这意味着后门代码与 AD FS 代码一起运行,具有与 AD FS 应用程序相同的访问和权限。由于后门与 AD FS 代码加载在同一应用程序域中,因此它可以通过编程方式访问各种 AD FS 模块用来执行其合法功能的合法类、方法、属性、字段、对象和组件。这种访问允许 FoggyWeb 后门直接与 AD FS 代码库(即,不是外部磁盘驻留工具)交互,并有选择地调用促进其恶意操作所需的本机 AD FS 方法。
该恶意驻留内存 DLL(最初由其开发人员命名为Microsoft.IdentityServer.WebExtension.dll )用作针对 AD FS 的后门。它由主 AD FS 服务进程Microsoft.IdentityServer.ServiceHost.exe通过恶意加载程序组件加载。
加载后,后门会启动一个 HTTP 侦听器,该侦听器侦听包含以下 URI 模式的 HTTP GET 和 POST 请求:
如下所示,URI 模式在后门中进行了硬编码,并模仿了目标 AD FS 部署使用的合法 URI 的结构。
一旦后门接收到包含上述 URI 模式之一的 HTTP 请求,侦听器就会继续使用 HTTP GET 或 HTTP POST 回调/处理程序方法(分别为ProcessGetRequest()和ProcessGetRequest() )处理该请求。
包含 URI 模式*/adfs/portal/images/theme/light01/的传入 HTTP GET 请求由后门的ProcessGetRequest()*方法处理。
如果对文件扩展名为.webp的文件/资源发出传入的 HTTP GET 请求,则*ProcessGetRequest()*方法继续处理该请求。否则,该请求将被后门忽略。此外,如果请求的文件名与以下三个硬编码名称之一匹配,则后门将请求视为攻击者发出的 C2 命令。
以下 URL 模式被视为 C2 命令:
前两个 C2 命令profile.webp和background.webp(上面屏幕截图中的*UrlGetFileNames[0]和UrlGetFileNames[1])是通过调用后门的Service.GetCertificate()*方法来处理的。
顾名思义,此方法负责从 AD FS 服务配置数据库检索 AD FS 证书(令牌签名或令牌加密证书,取决于传递给该方法的certificateType参数的值)。
***分析师注释:*请参阅附录以深入分析Service.GetCertificate() 方法以及它如何获取和解密令牌签名或加密证书。
如上图所示,当 C2 命令profile.webp ( UrlGetFileNames[0] ) 被发送到后门时(通过对 URI /adfs/portal/images/theme/light01/profile.webp发出 HTTP GET 请求) ,后门检索受感染 AD FS 服务器的令牌签名证书***。类似地,当 C2 命令background.webp ( UrlGetFileNames[1] ) 被发送到后门时(通过对 URI /adfs/portal/images/theme/light01/background.webp发出 HTTP GET 请求),后门检索受感染的 AD FS 服务器的**令牌加密证书***。
第三个 C2 命令logo.webp ( UrlGetFileNames[2] ) 通过向以下 URI 发送 HTTP GET 请求来触发:*/adfs/portal/images/theme/light01/logo.webp。C2 命令通过调用后门的GetInfo()*方法来处理。
*GetInfo()*方法负责转储受感染服务器的 AD FS 服务配置数据。
如上所示,AD FS 服务配置数据是通过ServiceSettingsData属性获取的,该属性从 AD FS 服务配置数据库 Windows 内部数据库 (WID) 中检索数据。
在将 C2 命令的输出(即令牌签名证书、令牌加密证书或 AD FS 服务配置数据)在 HTTP 200 响应中返回给 C2 之前,后门首先通过调用其方法来混淆输出命名为*GetWebpImage()*。
GetWebpImage *()*方法负责将 C2 命令的输出伪装成合法的 WebP 文件(通过添加适当的 RIFF/WebP 文件头魔术/字段)并对生成的 WebP 文件进行编码。
*GetWebpImage()*使用以下辅助方法来创建和编码包含 C2 命令输出的虚假 WebP 文件:
为了压缩数据,*GetFrame()调用Common.Compress()*方法,该方法用于通过利用 C# GZipStream 压缩类来压缩数据。
出于演示目的,假设 C2 命令产生以下数据(一个 256 字节的伪随机生成的字节数组)。
给定上述数据(即示例 C2 命令输出),*GetFrame()*返回以下字节数组。
上面的数组变量包含以下 32 字节硬编码 RIFF/WebP 标头字节。
如果传递给*GetWebpHeader()的数组大小(由GetFrame()*返回)超过 8,192 字节,则标头字节的索引 26 和 28 处的字节(最初设置为 0x00)将替换为 0x80。否则,索引 26 和 28 处的字节将替换为 0x40,如下所示。
*GetWebpHeader()然后将上面的自定义 RIFF/WebP 标头返回给GetWebpImage()*。
GetWebpImage()调用后门的Common.ProtectData()方法对新数组中包含压缩字节的部分进行编码(即,它不编码自定义 RIFF/WebP 标头)。作为第二个参数,GetWebpImage()将第一个压缩字节的偏移量传递给ProtectData()(如上表所示,在这种情况下,0x20 或 32 是第一个压缩字节的偏移量)。ProtectData()使用动态XOR 密钥和自定义 XOR 方法对压缩数据进行 XOR 编码。
最初,12 字节硬编码 XOR 密钥数组包含以下(种子)字节。
如上面的屏幕截图所示,压缩数据的每个字节都与 XOR 密钥数组中的一个字节进行异或。压缩数据的第一个字节 (0x17) 与位于密钥数组 (0x77) 偏移量 8 处的 XOR 密钥字节进行异或运算。
在将压缩数据的第一个字节与位于密钥数组偏移量 8 处的 XOR 密钥字节进行异或运算后,XOR 密钥字节本身会被新值覆盖。
例如,位于 XOR 密钥数组 (0x77) 偏移 8 处的 XOR 密钥字节通过以下操作被 0xEE 覆盖。
压缩数据的第二个字节 (0x01) 与位于密钥数组偏移量 9 处的 XOR 密钥字节 ( 33 % 12 = 9 ) 进行异或运算,依此类推,直到密钥滚动到 XOR 数组的第一个字节 (如上所述,XOR 密钥字节在每次编码操作后被覆盖)。下面是样本压缩数组的 XOR 编码版本。
在上述步骤之后,*GetWebpImage()*将以下示例数据返回给调用它的方法,以混淆和隐藏每个 C2 命令 ( ProcessGetRequest() ) 的输出。
如前所述,*ProcessGetRequest()*在 HTTP 200 响应中将上面生成的假 RIFF/WebP 文件(包含被盗的令牌签名证书、令牌加密证书或 AD FS 服务配置数据)返回给 C2。
如果后门无法成功执行 C2 命令,则改为向 C2 返回 HTTP 404 响应。
与 URI 模式*/adfs/services/trust/2005/samlmixed/upload匹配的传入 HTTP POST 请求由ProcessPostRequest()*方法处理。
此方法确保传入的 HTTP POST 请求的ContentType值以“xml”(不区分大小写)结尾,并且 HTTP POST 数据包含名为X509Certificate和SignatureValue的两个 XML 元素(例如,以字符串“ < X509Certificate> ”并以字符串“ ”结尾)。
如果 XML 数据包含这两个元素,则后门会执行以下操作:
UprotectData ()方法将 Base64 解码值的前两个字节视为两个字节的 XOR 密钥。它对其余数据(即第三个字节)调用Common.ProtectData()方法(在上一节中介绍),然后使用两字节 XOR 密钥对**Common.ProtectData( ) . 换句话说,*UprotectData()利用Common.ProtectData()*删除第一层 XOR 编码,然后另一个 XOR 例程删除应用于数据的第二层 XOR 编码。
在一个新线程中,*Service.ExecuteAssembly()调用Service.ExecuteAssemblyRoutine()*方法来处理数据。
如果解码后的X509Certificate值不以 MZ 开头,则后门将解码后的X509Certificate值视为基于 C# 的有效载荷的源代码,并调用其*Service.ExecuteSource()*方法在内存中动态编译和执行有效载荷。
在处理包含 XML 元素X509Certificate和SignatureValue的 HTTP POST 请求后,后门使用 HTTP 204 响应代码响应请求。如果 HTTP POST 没有上述元素,后门会使用 HTTP 404 响应码响应请求。
顾名思义,Service.GetCertificate()方法负责从 AD FS 服务检索 AD FS 证书(令牌签名或令牌加密证书,取决于传递给该方法的certificateType参数的值)配置数据库。
该方法执行以下操作来检索所需的证书:
AdministrationServiceState类/对象包含执行和处理客户端请求所需的配置信息。*_state字段用于维护AdministrationServiceState类/对象的当前状态(来自Microsoft.IdentityServer.Service.dll*的屏幕截图)。
AdministrationServiceState对象(存储在*_state字段中)包含另一个名为_certificateProtector*的字段。
_certificateProtector字段存储用于分布式密钥管理 (DKM)的 Data Protector 类DkmDataProtector的实例。DkmDataProtector类实现了一个名为Unprotect()的方法,**该方法最终调用了DKM/IDKM的Unprotect()方法(来自**Microsoft.IdentityServer.dll的屏幕截图)。
DKM Unprotect()方法从 Microsoft.IdentityServer.Dkm.DKMBase 继承了一个名为Unprotect ()的方法(来自Microsoft.IdentityServer.Dkm.dll的屏幕截图)。
Microsoft.IdentityServer.Dkm.DKMBase中的Unprotect()方法(如上所示)提供了解密存储在EncryptedPfx blob 中的加密证书(PKCS12 对象)的功能。
了解可通过*_certificateProtector字段访问的**Unprotect()方法的可用性后,后门会调用Unprotect()方法来解密存储在所需证书类型的EncryptedPfx* blob 中的加密证书(AD FS 令牌签名或加密证书)。
本附录中描述的技术变体由 Douglas Bienstock 和 Austin Baker 在 2019 年的 TROOPERS 会议上公开展示(我是 AD FS,你也可以:攻击 Active Directory 联合服务)。但是,FoggyWeb 使用的方法与公开提供的方法不同,因为 FoggyWeb 利用AdministrationServiceState类/对象中的**_state和*_certificateProtector字段来促进对 Data Protector 类DkmDataProtector的访问(用于访问和调用Unprotect()*方法)。
类型 | 威胁名称 | 威胁类型 | 指标 |
---|---|---|---|
MD5 | 雾网 | 装载机 | 5d5a1b4fafaf0451151d552d8eeb73ec |
SHA-1 | 雾网 | 装载机 | c896ece073dd01191cbc1d462bc2f47161828a83 |
SHA-256 | 雾网 | 装载机 | 231b5517b583de102cde59630c3bf938155d17037162f663874e4662af2481b1 |
MD5 | 雾网 | 后门(加密) | 9ff9401315d0f7258a9fcde0cfdef02b |
SHA-1 | 雾网 | 后门(加密) | 4597431f26424cb814c917168fa8d74d01ab7cd1 |
SHA-256 | 雾网 | 后门(加密) | da0be762bb785085d36aec80ef1697e25fb15414514768b3bcaf798dd9c9b169 |
MD5 | 雾网 | 后门(已解密) | e9671d294ce41fe6dbb9637dc0157a88 |
SHA-1 | 雾网 | 后门(已解密) | 85cfeccbb48fd9f498d24711c66e458e0a80cc90 |
SHA-256 | 雾网 | 后门(已解密) | 568392bd815de9b677788addfc4fa4b0a5847464b9208d2093a8623bbecd81e6 |
客户应检查其 AD FS 服务器配置并实施更改以保护这些系统免受攻击:
我们强烈建议组织通过以下最佳实践强化和保护 AD FS 部署:
保护 AD FS 服务器是缓解 NOBELIUM 攻击的关键。在 AD FS 服务器上检测和阻止恶意软件、攻击者活动和其他恶意工件可能会破坏已知 NOBELIUM 攻击链中的关键步骤。Microsoft Defender 防病毒软件将本博客中讨论的新 NOBELIUM 组件检测为以下恶意软件:
Microsoft Defender for Endpoint 中的终结点检测和响应 (EDR) 功能可检测与此恶意软件相关的恶意行为,这些恶意行为显示为具有以下标题的警报:
也可以使用 Azure AD 身份保护在云中检测到这种攻击。建议您监视“令牌颁发者异常”检测的Azure AD 身份保护风险检测报告。此检测会查找呈现给 Azure AD 租户的 SAML 令牌中的异常情况。
要查找相关活动,请在微软 365后卫:
DeviceImageLoadEvents| where FolderPath has @"C:\Windows\ADFS"| where FileName has @"version.dll"
Azure Sentinel 客户可以使用以下检测查询来查找此活动:
检测查询:https://github.com/Azure/Azure-Sentinel/blob/master/Detections/MultipleDataSources/Nobelium_FoggyWeb.yaml
IOC 文件:https://github.com/Azure/Azure-Sentinel/tree/master/Sample Data/Feeds/FoggyWebIOC.csv
近期阅读文章
,质量尚可的,大部分较新,但也可能有老文章。开卷有益,不求甚解
,不需面面俱到,能学到一个小技巧就赚了。译文仅供参考
,具体内容表达以及含义, 以原文为准
(译文来自自动翻译)尽量阅读原文
。(点击原文跳转)每日早读
基本自动化发布(不定期删除),这是一项测试
最新动态: Follow Me
微信/微博:
red4blue
公众号/知乎:
blueteams