简介
7 月份,谷歌宣布了一种针对 Windows 版 Chrome 中存储的 cookie 的新保护机制,称为应用程序绑定加密。毫无疑问,此次安全措施提高了标准并直接影响了恶意软件生态系统。在该新功能推出数月后,许多信息窃取者已经编写了新代码来绕过此保护(正如 Chrome 安全团队所预测的那样),以保持市场竞争力并提供可靠地从 Chrome 浏览器检索 cookie 数据的功能。
Elastic 安全实验室一直在跟踪此类活动的子集,发现不同恶意软件家族使用了多种技术来规避应用程序绑定加密。尽管生态系统仍在面对这种压力而不断发展,但我们的目标是分享技术细节,帮助组织理解和防御这些技术。在本文中,我们将介绍以下信息窃取程序家族所使用的不同方法:
- STEALC/维达
- METASTEALER
- 苯海拉明
- 异形窃贼
- LUMMA
关键要点
- 最新版本的信息窃取程序利用应用程序绑定加密绕过 Google 最近的 Cookie 保护功能
- 技术包括集成攻击性安全工具 ChromeKatz、利用 COM 与 Chrome 服务交互并解密应用程序绑定的加密密钥,以及使用 Chrome 中的远程调试功能
- 防御者应积极监控针对 Windows 上 Chrome 的不同 cookie 绕过技术,以防未来在近期至中期内出现缓解和绕过措施
- Elastic Security 通过内存签名、行为规则和搜索机会提供缓解措施,以便更快地识别和响应信息窃取者活动
背景
一般来说,网络应用程序使用 Cookie 将访问者信息存储在访问者用来访问该网络应用程序的浏览器中。这些信息可帮助 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 的 App-Bound 加密功能的特定信息窃取技术。虽然这并不是对绕过方法的详尽汇编,并且这些家族的开发仍在进行中,但它们代表了信息窃取领域内一个有趣的动态,展示了恶意软件开发人员如何响应谷歌最近更新的安全控制。我们的团队观察到的技术包括:
- 通过 Chrome 的 DevTools 协议进行远程调试
- 读取 Chrome 网络服务进程的进程内存(ChromeKatz 和
ReadProcessMemory
(RPM)) - 提升至
SYSTEM
,然后通过 COM 使用GoogleChromeElevationService
的DecryptData
方法解密app_bound_encryption_key
STEALC/维达
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
有 2 调用。
在第一次调用CredentialKatz::FindDllPattern
时,它会尝试在chrome.dll
中找到其中一个签名模式(取决于受害者的 Chrome 版本)。一旦找到,STEALC 现在有一个引用指针,指向字节序列开始的内存位置,即函数net::CookieMonster::~CookieMonster
, CookieMonster
类的析构函数。
第二次调用CredentialKatz::FindDllPattern
将net::CookieMonster::~CookieMonster(void)
的函数地址作为字节序列搜索的参数传入,导致 STEALC 具有指向CookieMonster
的虚函数指针结构的指针。
STEALC 使用的以下方法再次与 ChromeKatz 相同,它通过扫描chrome.dll
模块中的内存块来查找引用CookieMonster
vtable 的指针,从而定位CookieMonster
实例。由于 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 频道宣布了此更新,强调尽管 Chrome 版本129+
的安全性有所变化,但其提取敏感信息(包括 cookie)的能力有所增强。
我们的团队在野外观察到的第一个样本是在 9 月 30 日发现的,也就是作者推广更新的同一天。尽管声称该恶意软件不需要Administrator
权限即可运行,但我们的测试表明它确实需要提升访问权限,因为它会在执行期间尝试模仿SYSTEM
令牌。
如上面的屏幕截图所示, get_decryption
方法现在包含一个新的布尔参数。如果加密数据(cookie)以v20
前缀开头,则此值设置为TRUE
,表明该 cookie 是使用 Chrome 最新的加密方法加密的。更新后的功能保留了向后兼容性,如果受感染的机器上存在旧版 Chrome 的 cookie,则仍然支持解密。
然后,恶意软件会尝试访问位于 Chrome 配置文件目录中的Local State
或LocalPrefs.json
文件。这两个文件均为 JSON 格式,并存储旧版 Chrome 的加密密钥 ( encrypted_key
) 和新版 Chrome 的加密密钥app_bound_encrypted_key
。如果将标志设置为TRUE
,则恶意软件会专门使用app_bound_encrypted_key
根据更新的 Chrome 加密方法解密 cookie。
在这种情况下,恶意软件首先使用新引入的名为ContextSwitcher
的类来模拟SYSTEM
令牌。
然后,它通过使用 CLSID 708860E0-F641-4611-8895-7D867DD3675B
、通过负责解密的 Chrome 服务的 COM 创建名为GoogleChromeElevationService
的实例来解密密钥。一旦初始化,它会调用DecryptData
方法来解密app_bound_encrypted_key
密钥,该密钥将用于解密加密的 cookie。
METASTEALER 采用的技术与 9 月 27 日在 X 上 分享的 要点 中演示的技术类似,这可能为恶意软件作者提供了灵感。这两种方法都利用类似的方法来绕过 Chrome 的加密机制并提取敏感数据。
苯海拉明
今年早些时候,这款开源窃取程序利用了 Windows SmartScreen 漏洞 (CVE-2023-36025) 引起了全世界的关注。虽然它的开发仍在 Telegram 上进行,但我们的团队发现 9 月底提交的最新版本(2.3.2) 包含适用于 Chrome 的新 cookie 抓取功能。
该恶意软件首先枚举 Chrome 中的不同配置文件,然后使用函数( BrowserHelpers.NewEncryption
)执行浏览器检查,检查 Chrome 浏览器的版本是否大于或等于127
。
如果条件匹配,PHEMEDRONE 会使用辅助函数组合来提取 cookie。
通过查看ChromeDevToolsWrapper
类及其不同函数,我们可以看到 PHEMEDRONE 在 Chrome 中设置了一个远程调试会话来访问 Cookie。默认端口( 9222
)与设置为-2400
、 -2400
窗口位置一起使用,设置在屏幕外,以防止任何可见窗口提醒受害者。
接下来,恶意软件与 Chrome 的调试接口建立 WebSocket 连接,并使用已弃用的 Chrome DevTools 协议方法 ( Network.getAllCookies
) 发出请求。
然后以纯文本形式返回前一个请求的 cookie,下面是显示此行为的网络捕获:
异形窃贼
XENOSTEALER是一个托管在 GitHub 上的开源信息窃取程序。它于 2024 7 月问世,在本文发布时正在积极开发中。值得注意的是,Chrome 绕过功能已于 9 月26 2024提交。
XENOSTEALER 采用的方法与 METASTEALER 类似。它首先解析给定的 Chrome 配置文件下的 JSON 文件以提取app_bound_encrypted_key
。然而,解密过程发生在 Chrome 进程内。为了实现此目的,XENOSTEALER 启动Chrome.exe
的实例,然后使用名为SharpInjector
的辅助类注入代码,并将加密密钥作为参数传递。
注入的代码随后从GoogleChromeElevationService
调用DecryptData
方法来获取解密的密钥。
LUMMA
10 月中旬, LUMMA最新版本实现了一种绕过 Chrome cookie 保护的新方法,据@g0njxa报告。
我们分析了 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 服务器。
检测
以下是可用于识别信息窃取者使用的技术的行为检测:
此外,以下查询可用于搜寻各种相关的异常行为:
异常进程访问 Cookies
此查询使用文件打开事件并按进程聚合访问,然后查找在唯一主机中观察到的且总访问次数较少的事件:
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
以下是调用CoCreateInstance (CLSID_Elevator)
时 METASTEALER 恶意软件的匹配示例:
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 program files
文件夹运行的二进制文件,因此可以使用以下查询来搜寻从该文件夹执行或加载的未签名或不受信任的二进制文件:
从 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框架来记录威胁针对企业网络使用的常见策略、技术和程序。
战术
策略代表了技术或子技术的原因。 这是对手的战术目标:采取行动的原因。
技术
技术代表对手如何通过采取行动来实现战术目标。
雅拉
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 | 硬核破解程序 | 苯海拉明 |
43cb70d31daa43d24e5b063f4309281753176698ad2aba9c557d80cf710f9b1d | SHA-256 | 程序 | METASTEALER |
84033def9ffa70c7b77ce9a7f6008600c0145c28fe5ea0e56dfafd8474fb8176 | SHA-256 | LUMMA | |
b74733d68e95220ab0630a68ddf973b0c959fd421628e639c1b91e465ba9299b | SHA-256 | 异种窃取者 | 异形窃贼 |
参考资料
上述研究参考了以下内容: