简介
7 月,Google 宣布了一项针对 Windows 上 Chrome 中存储的 Cookie 的新保护机制,称为应用程序绑定加密。毫无疑问,这种安全实施提高了标准,并直接影响了恶意软件生态系统。在使用了这项新功能几个月后,许多信息窃取者编写了新代码来绕过此保护措施(正如 Chrome 安全团队预测的那样),以便在市场上保持竞争力,并提供可靠地从 Chrome 浏览器检索 Cookie 数据的功能。
Elastic Security Labs 一直在跟踪此活动的子集,识别不同恶意软件家族用于规避应用程序绑定加密的多种技术。虽然生态系统仍在这一压力下不断发展,但我们的目标是分享技术细节,帮助组织了解并防御这些技术。在本文中,我们将介绍以下信息窃取者家族使用的不同方法
- STEALC/VIDAR
- METASTEALER
- PHEMEDRONE
- XENOSTEALER
- LUMMA
主要收获
- 最新版本的信息窃取者利用应用程序绑定加密,实施了绕过 Google 最近的 Cookie 保护功能的方法
- 技术包括集成攻击性安全工具 ChromeKatz、利用 COM 与 Chrome 服务交互并解密应用程序绑定加密密钥,以及使用 Chrome 中的远程调试功能
- 防御者应积极监控针对 Windows 上 Chrome 的不同 Cookie 绕过技术,以应对未来可能在中短期内出现的缓解措施和绕过措施
- Elastic Security 通过内存签名、行为规则和狩猎机会提供缓解措施,以便更快地识别和响应信息窃取活动
背景
一般而言,Web 应用程序使用 Cookie 在访问者用来访问该 Web 应用程序的浏览器中存储访问者信息。此信息可帮助 Web 应用程序跟踪该用户、他们的偏好以及从一个位置到另一个位置(甚至跨设备)的其他信息。
身份验证令牌是客户端数据存储结构的一种用途,它支持现代 Web 交互的许多工作方式。在用户成功通过 Web 应用程序身份验证后,浏览器会存储这些令牌。在用户名和密码之后,在通过一次性密码或生物识别进行多因素身份验证 (MFA) 之后,Web 应用程序会通过在每个后续 Web 请求中交换此令牌来“记住”您的浏览器是您。
可以访问有效身份验证令牌的恶意行为者可以重复使用它来冒充该 Web 服务的用户,从而能够接管帐户、窃取个人或财务信息,或执行其他操作,例如转移金融资产。
网络犯罪分子使用信息窃取者窃取此类信息并将其商品化以获取经济利益。
Google Chrome Cookie 安全性
Windows 上的旧版 Google Chrome 使用 Windows 本机数据保护 API (DPAPI) 加密 Cookie,并保护它们免受其他用户上下文的影响。这提供了针对多种攻击场景的充分保护,但以目标用户上下文运行的任何恶意软件都可以使用 DPAPI 方法直接解密这些 Cookie。不幸的是,这种上下文正是信息窃取者在进行社会工程以获取初始访问权限后经常发现自己所处的环境。DPAPI 方案现在对攻击者来说是众所周知的,有多种攻击途径:从使用 API 进行本地解密,到窃取主密钥并进行远程解密,再到在企业环境中滥用域范围的备份 DPAPI 密钥。
随着 2024 年 7 月 Chrome 127 的发布,Google 实施了浏览器数据的应用程序绑定加密。此机制直接解决了针对 Windows Chrome 浏览器数据(包括 Cookie)的许多常见 DPAPI 攻击。它通过将数据存储在加密数据文件中来实现此目的,并使用以 SYSTEM 身份运行的服务来验证任何解密尝试是否来自 Chrome 进程,然后再将密钥返回给该进程以解密存储的数据。
虽然我们认为这种加密方案并不是保护所有浏览器数据的灵丹妙药(正如 Chrome 安全团队在其版本中所承认的那样),但我们认为它已成功地推动恶意软件作者采用更明显恶意且更容易让防御者识别和响应的 TTP。
信息窃取者绕过技术,总结
以下部分将描述 Elastic 观察到的用于绕过 Google 应用程序绑定加密功能的特定信息窃取者技术。虽然这不是绕过方法的全盘编纂,并且这些家族的开发仍在进行中,但它们代表了信息窃取者领域内一个有趣的动态,展示了恶意软件开发人员如何响应 Google 最近更新的安全控制。我们的团队观察到的技术包括
- 通过 Chrome 的 DevTools 协议进行远程调试
- 读取 Chrome 网络服务进程的进程内存 (ChromeKatz 和
ReadProcessMemory
(RPM)) - 提升到
SYSTEM
,然后使用通过 COM 的GoogleChromeElevationService
的DecryptData
方法解密app_bound_encryption_key
STEALC/VIDAR
我们的团队在 9 月 20 日左右观察到引入 STEALC/VIDAR 的新代码,与围绕 Cookie 绕过技术有关。这些是非典型的样本,与以前的版本不同,并且实现为嵌入式 64 位 PE 文件以及条件检查。Chrome 存储其数据的 SQLite 数据库中的加密值现在以 v20 为前缀,表明这些值现在使用应用程序绑定加密进行加密。
STEALC 于 2023 年推出,其开发“深受”其他更成熟的信息窃取者(例如RACOON和VIDAR)的“启发”。STEALC 和 VIDAR 继续并行开发,并且在应用程序绑定加密绕过方面采用了相同的实现。
在从数据库中提取加密数据的过程中,恶意软件会检查此前缀。如果它以 v20
开头,则使用二进制文件的 .data
部分中的嵌入式 PE 文件生成子进程。此程序负责提取驻留在 Chrome 的一个子进程中的未加密 Cookie 值。
这个嵌入式二进制文件通过 OpenDesktopA
/ CreateDesktopA
创建一个隐藏的桌面,然后使用 CreateToolhelp32Snapshot
扫描并终止所有 chrome.exe
进程。 接着,使用新的桌面对象启动一个新的 chrome.exe
进程。根据 Chrome 的安装版本,恶意软件会为 Chromium 的 CookieMonster 功能(一个用于管理 Cookie 的内部组件)选择一个签名模式。
我们使用 签名模式 来跳转到为名为 ChromeKatz 的攻击性安全工具开发的现有代码。 目前,这些模式已从 ChromeKatz 存储库中删除,并替换为一种新技术。 根据我们的分析,恶意软件作者似乎在 STEALC 中重新实现了 ChromeKatz,以绕过应用程序绑定的加密保护功能。
一旦恶意软件识别出匹配的签名,它会枚举 Chrome 的子进程,以检查是否存在 --utility-sub-type=network.mojom.NetworkService
命令行标志。 此标志表示该进程是负责处理所有互联网通信的网络服务。 它成为了主要目标,因为它持有攻击者寻求的敏感数据,如 MDSec 的 文章 中所述。 然后它会返回该特定子进程的句柄。
接下来,它枚举网络服务子进程中的每个模块,以查找并检索加载到内存中的 chrome.dll
的基址和大小。STEALC 使用 CredentialKatz::FindDllPattern
和 CookieKatz::FindPattern
来定位 CookieMonster 实例。 对 CredentialKatz::FindDllPattern
进行了两次调用。
在第一次调用 CredentialKatz::FindDllPattern
时,它尝试在 chrome.dll
中查找其中一个签名模式(取决于受害者的 Chrome 版本)。 找到后,STEALC 现在拥有一个指向该内存位置的引用指针,该位置是字节序列开始的地方,即 net::CookieMonster::~CookieMonster
函数,CookieMonster
类的析构函数。
第二次调用 CredentialKatz::FindDllPattern
时,它将 net::CookieMonster::~CookieMonster(void)
的函数地址作为字节序列搜索的参数传递,从而使 STEALC 获得指向 CookieMonster
的虚拟函数指针结构的指针。
STEALC 使用的以下方法再次与 ChromeKatz 相同,它通过扫描 chrome.dll
模块中的内存块来定位 CookieMonster
实例,以查找引用 CookieMonster
vtable 的指针。 由于 vtable 对于给定类的所有对象都是常量,因此任何 CookieMonster
对象都将具有相同的 vtable 指针。 当识别出匹配项时,STEALC 会将该内存位置视为 CookieMonster
实例,并将其地址存储在数组中。
对于每个已识别的 CookieMonster
实例,STEALC 会访问位于偏移量为 +0x30
的内部 CookieMap
结构,它是一个二叉树。 此树中的每个节点都包含指向 CanonicalCookieChrome
结构的指针。CanonicalCookieChrome
结构保存未加密的 Cookie 数据,从而使其可以进行提取。 然后,STEALC 通过将第一个节点传递给专用的遍历函数来启动树遍历。
对于每个节点,它会调用 ReadProcessMemory
从目标进程的内存中访问 CanonicalCookieChrome
结构,然后在 jy::GenerateExfilString
中进一步处理。
STEALC 通过将到期日期转换为 UNIX 格式并验证是否存在 HttpOnly
和 Secure
标志来格式化提取的 Cookie 数据。 然后,它会将 Cookie 的名称、值、域、路径以及 HttpOnly
和 Secure
等详细信息附加到最终的字符串中,以便进行渗漏。 使用 OptimizedString
结构来代替字符串,因此字符串值可以是字符串本身,或者,如果字符串长度大于 23,它将指向存储字符串的地址。
METASTEALER
METASTEALER 于 2022 年首次被观察到,最近升级了其窃取 Chrome 数据的能力,绕过了 Google 的最新缓解措施。 9 月 30 日,恶意软件作者通过其 Telegram 频道宣布了此更新,强调了其增强的提取敏感信息(包括 Cookie)的能力,尽管 Chrome 的 129+
版本进行了安全更改。
我们的团队在野外观察到的 第一个样本 于 9 月 30 日被发现,同一天作者推广了该更新。 尽管声称该恶意软件在运行时不需要 管理员
权限,但我们的测试显示它确实需要提升的访问权限,因为它在执行期间尝试模拟 SYSTEM
令牌。
如上面的屏幕截图所示,get_decryption
方法现在包含一个新的布尔参数。 如果加密的数据(Cookie)以 v20
前缀开头,则此值设置为 TRUE
,表示 Cookie 是使用 Chrome 的最新加密方法加密的。 更新后的函数保留了向后兼容性,如果受感染的计算机上存在旧版本 Chrome 的 Cookie,仍然支持对其进行解密。
然后,恶意软件会尝试访问位于 Chrome 配置文件目录中的 Local State
或 LocalPrefs.json
文件。 这两个文件都是 JSON 格式,并存储旧版本 Chrome 的加密密钥(encrypted_key
)和新版本的 app_bound_encrypted_key
。 如果该标志设置为 TRUE
,则恶意软件会专门使用 app_bound_encrypted_key
来解密与更新后的 Chrome 加密方法一致的 Cookie。
在这种情况下,恶意软件首先使用新引入的名为 ContextSwitcher
的类来模拟 SYSTEM
令牌。
然后,它通过 COM 创建一个名为 GoogleChromeElevationService
的 Chrome 解密服务实例来解密密钥,该实例使用 CLSID 708860E0-F641-4611-8895-7D867DD3675B
。初始化后,它会调用 DecryptData
方法来解密 app_bound_encrypted_key
密钥,该密钥将用于解密加密的 cookie。
METASTEALER 采用了一种类似于 gist 中演示的技术,该技术于 9 月 27 日在 X 上分享,这可能是恶意软件作者的灵感来源。两种方法都利用类似的方法来绕过 Chrome 的加密机制并提取敏感数据。
PHEMEDRONE
这款 开源窃密器 今年早些时候因使用 Windows SmartScreen 漏洞(CVE-2023-36025)而引起了全世界的关注。虽然它仍在 Telegram 上进行开发,但我们的团队发现最近一个在 9 月底提交的 版本(2.3.2),其中包括针对 Chrome 的新 cookie 抓取功能。
该恶意软件首先枚举 Chrome 中的不同配置文件,然后使用函数 (BrowserHelpers.NewEncryption
) 执行浏览器检查,检查版本大于或等于 127
的 Chrome 浏览器。
如果条件匹配,PHEMEDRONE 会使用辅助函数的组合来提取 cookie。
通过查看 ChromeDevToolsWrapper
类及其不同的函数,我们可以看到 PHEMEDRONE 在 Chrome 中设置了一个远程调试会话以访问 cookie。默认端口 (9222
) 与窗口位置设置为 -2400
, -2400
一起使用,该位置设置为屏幕外,防止任何可见窗口提醒受害者。
接下来,该恶意软件建立与 Chrome 调试接口的 WebSocket 连接,使用已弃用的 Chrome DevTools 协议方法 (Network.getAllCookies
) 发出请求。
然后,cookie 以明文形式从之前的请求中返回,下面是一个显示此行为的网络捕获。
XENOSTEALER
XENOSTEALER 是一个托管在 GitHub 上的开源信息窃取器。它于 2024 年 7 月出现,在本文发布时正在积极开发中。值得注意的是,Chrome 绕过功能于 2024 年 9 月 26 日提交。
XENOSTEALER 采用的方法与 METASTEALER 类似。它首先解析给定 Chrome 配置文件下的 JSON 文件,以提取 app_bound_encrypted_key
。但是,解密过程在 Chrome 进程中进行。为了实现这一点,XENOSTEALER 启动一个 Chrome.exe
实例,然后使用名为 SharpInjector
的辅助类注入代码,并将加密密钥作为参数传递。
注入的代码随后调用 GoogleChromeElevationService
中的 DecryptData
方法以获取解密的密钥。
LUMMA
正如 @g0njxa 报道的那样,在 10 月中旬,最新版本的 LUMMA 实现了一种绕过 Chrome cookie 保护的新方法。
我们分析了 LUMMA 的最新版本,确认它成功地从最新版本的 Google Chrome (130.0.6723.70
) 中恢复了 cookie 数据。LUMMA 首先通过 Kernel32!CreateProcessW
创建一个可见的 Chrome 进程。
在调试器中,此活动之后是对 NtReadVirtualMemory
的多次调用,我们确定 LUMMA 在 Chrome 进程中搜索 chrome.dll
。
找到后,该恶意软件使用 NtReadVirtualMemory
将 chrome.dll
映像复制到其自己的进程内存中。与 ChromeKatz 技术类似,Lumma 利用模式扫描来定位 Chrome 的 CookieMonster
组件。
Lumma 使用模糊的签名模式来精确定位 CookieMonster
功能
3Rf5Zn7oFA2a????k4fAsdxx????l8xX5vJnm47AUJ8uXUv2bA0s34S6AfFA????kdamAY3?PdE????6G????L8v6D8MJ4uq????k70a?oAj7a3????????K3smA????maSd?3l4
以下是去模糊化后的 YARA 规则
rule lumma_stealer
{
meta:
author = "Elastic Security Labs"
strings:
$lumma_pattern = { 56 57 48 83 EC 28 89 D7 48 89 CE E8 ?? ?? ?? ?? 85 FF 74 08 48 89 F1 E8 ?? ?? ?? ?? 48 89 F0 48 83 C4 28 5F 5E C3 CC CC CC CC CC CC CC CC CC CC 56 57 48 83 EC 38 48 89 CE 48 8B 05 ?? ?? ?? ?? 48 31 E0 48 89 44 24 ?? 48 8D 79 ?? ?? ?? ?? 28 E8 ?? ?? ?? ?? 48 8B 46 20 48 8B 4E 28 48 8B 96 ?? ?? ?? ?? 4C 8D 44 24 ?? 49 89 10 48 C7 86 ?? ?? ?? ?? ?? ?? ?? ?? 48 89 FA FF 15 ?? ?? ?? ?? 48 8B 4C 24 ?? 48 31 E1}
condition:
all of them
}
在 chrome.dll
中解码和搜索模式后,这将引导到 CookieMonster
析构函数 (net::CookieMonster::~CookieMonster
)。
然后,在内存中识别 cookie,并从 Chrome 进程中以明文形式转储出来。
完成后,LUMMA 会将 cookie 和其他请求的数据作为多个 zip 文件(xor 加密和 base64 编码)发送到 C2 服务器。
检测
以下是可以用于识别信息窃取器所使用技术的行为检测
此外,以下查询可用于查找各种相关的异常行为
异常进程访问 Cookie
此查询使用文件打开事件和按进程聚合的访问,然后查找在唯一主机上观察到且总访问计数较低的访问。
FROM logs-endpoint.events.file-default*
| where event.category == "file" and event.action == "open" and file.name == "Cookies" and file.path like "*Chrome*"
| keep file.path, process.executable, agent.id
| eval process_path = replace(to_lower(process.executable), """c:\\users\\[a-zA-Z0-9\.\-\_\$]+\\""", "c:\\\\users\\\\user\\\\")
| stats agents_count = COUNT_DISTINCT(agent.id), access_count= count(*) by process_path
| where agents_count <= 2 and access_count <=2
以下是来自各种信息窃取器的匹配示例,包括具有新 Chrome cookie 窃取功能的更新版本
METASTEALER 的行为倾向于首先终止所有正在运行的 chrome 实例,然后调用 CoCreateInstance
来实例化 Google Chrome 提权服务,可以使用以下 EQL 查询来表达这一系列事件
sequence by host.id with maxspan=1s
[process where event.action == "end" and process.name == "chrome.exe"] with runs=5
[process where event.action == "start" and process.name == "elevation_service.exe"]
之前的搜索指示了可疑代理,但没有识别来源进程。通过在 Chrome 提权服务 CLSID 注册表项 {708860E0-F641-4611-8895-7D867DD3675B}
上启用事件 4663 的注册表对象访问审核,我们可以检测尝试访问该键的异常进程
FROM logs-system.security-default* | where event.code == "4663" and winlog.event_data.ObjectName == "\\REGISTRY\\MACHINE\\SOFTWARE\\Classes\\CLSID\\{708860E0-F641-4611-8895-7D867DD3675B}" and not winlog.event_data.ProcessName in ("C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe", "C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe") and not winlog.event_data.ProcessName like "C:\\\\Program Files\\\\Google\\\\Chrome\\\\Application\\\\*\\\\elevation_service.exe" | stats agents_count = COUNT_DISTINCT(agent.id), access_count= count(*) by winlog.event_data.ProcessName | where agents_count <= 2 and access_count <=2
以下是 METASTEALER 恶意软件调用 CoCreateInstance (CLSID_Elevator)
时的匹配示例
PHEMEDRONE 窃取器使用 已知 的浏览器调试方法,通过 Chromium API 收集 cookie,这可以在以下屏幕截图中观察到,其中我们可以看到 NodeJs 的实例通过端口 9222
与启用了调试的浏览器实例进行通信
以下 EQL 查询可用于查找执行类似行为的异常进程
sequence by host.id, destination.port with maxspan=5s
[network where event.action == "disconnect_received" and
network.direction == "ingress" and
process.executable in~ ("C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe",
"C:\\Program Files\\Microsoft\\Edge\\Application\\msedge.exe") and
source.address like "127.*" and destination.address like "127.*"]
[network where event.action == "disconnect_received" and network.direction == "egress" and not
process.executable in~ ("C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe",
"C:\\Program Files\\Microsoft\\Edge\\Application\\msedge.exe") and source.address like "127.*" and destination.address like "127.*"]
从异常父进程派生的 Chrome 浏览器
使用 ChromeKatz 实现的 STEALC 样本会派生一个 Google Chrome 实例来加载用户默认配置文件,同时查找正常的父可执行文件,结果发现它仅限于 Chrome 签名的父进程和 Explorer.exe,可以使用以下 ES|QL 查询来查找异常父进程
FROM logs-endpoint.events.process-*
| where event.category == "process" and event.type == "start" and to_lower(process.name) == "chrome.exe" and process.command_line like "*--profile-directory=Default*"
| eval process_parent_path = replace(to_lower(process.parent.executable), """c:\\users\\[a-zA-Z0-9\.\-\_\$]+\\""", "c:\\\\users\\\\user\\\\")
| stats agents_count = COUNT_DISTINCT(agent.id), total_executions = count(*) by process_parent_path
| where agents_count == 1 and total_executions <= 10
来自 Chrome 应用程序文件夹的不受信任的二进制文件
由于 Chrome 提权服务 信任 从 Chrome 程序文件
文件夹运行的二进制文件,因此可以使用以下查询来查找从此处执行或加载的未签名或不受信任的二进制文件
从 google chrome 应用程序文件夹加载的未签名 DLL
FROM logs-endpoint.events.library*
| where event.category == "library" and event.action == "load" and to_lower(dll.path) like "c:\\\\program files\\\\google\\\\chrome\\\\application\\\\*" and not (dll.code_signature.trusted == true)
| keep process.executable, dll.path, dll.hash.sha256, agent.id
| stats agents_count = COUNT_DISTINCT(agent.id), total_executions = count(*) by process.executable, dll.path, dll.hash.sha256
| where agents_count == 1 and total_executions <= 10
从 google chrome 应用程序文件夹启动的未签名可执行文件
FROM logs-endpoint.events.process*
| where event.category == "library" and event.type == "start" and (to_lower(process.executable) like "c:\\\\program files\\\\google\\\\chrome\\\\application\\\\*" or to_lower(process.executable) like "c:\\\\scoped_dir\\\\program files\\\\google\\\\chrome\\\\application\\\\*")
and not (process.code_signature.trusted == true and process.code_signature.subject_name == "Goole LLC")
| keep process.executable,process.hash.sha256, agent.id
| stats agents_count = COUNT_DISTINCT(agent.id), total_executions = count(*) by process.executable, process.hash.sha256
| where agents_count == 1 and total_executions <= 10
结论
谷歌在 Chrome 中实施了新的安全控制措施,以保护 Cookie 数据,这提高了安全标准。正如预期的那样,这导致恶意软件开发者开发或整合他们自己的绕过技术。我们希望谷歌能够继续创新,为用户数据提供更强大的保护。
组织和防御者应该持续监控不寻常的端点活动。虽然这些新技术可能成功,但它们也存在噪声,可以通过正确的安全工具、流程和人员进行检测。
窃密器绕过与 MITRE ATT&CK
Elastic 使用 MITRE ATT&CK 框架来记录威胁针对企业网络的常见战术、技术和程序。
战术
战术代表技术或子技术的原因。它是攻击者的战术目标:执行行动的原因。
技术
技术代表攻击者如何通过执行行动来实现战术目标。
YARA
Elastic Security 创建了 YARA 规则来识别此活动。
- Windows.Trojan.Stealc
- Windows.Infostealer.PhemedroneStealer
- Windows.Trojan.MetaStealer
- Windows.Trojan.Xeno
- Windows.Trojan.Lumma
- Windows.Infostealer.Generic
观察
所有可观测值也可在 下载 中以 ECS 和 STIX 格式提供。
本研究中讨论了以下可观测值。
可观测值 | 类型 | 名称 | 参考 |
---|---|---|---|
27e4a3627d7df2b22189dd4bebc559ae1986d49a8f4e35980b428fadb66cf23d | SHA-256 | num.exe | STEALC |
08d9d4e6489dc5b05a6caa434fc36ad6c1bd8c8eb08888f61cbed094eac6cb37 | SHA-256 | HardCoreCrack.exe | PHEMEDRONE |
43cb70d31daa43d24e5b063f4309281753176698ad2aba9c557d80cf710f9b1d | SHA-256 | Ranginess.exe | METASTEALER |
84033def9ffa70c7b77ce9a7f6008600c0145c28fe5ea0e56dfafd8474fb8176 | SHA-256 | LUMMA | |
b74733d68e95220ab0630a68ddf973b0c959fd421628e639c1b91e465ba9299b | SHA-256 | XenoStealer.exe | XENOSTEALER |
参考
以下是在上述研究中引用的内容