Crypto wasted: BlueNoroff’s ghost mirage of funding and jobs
SAS 28 Oct 2025 51 minute read
目录
- 引言
- GhostCall活动
- 初始访问
- 多阶段执行链
- ZoomClutch/TeamsClutch:伪造的Zoom/Teams应用
- DownTroy v1 感染链
- CosmicDoor 感染链
- SilentSiphon:窃密工具套件
- RooTroy 感染链
- RealTimeTroy 感染链
- SneakMain 感染链
- DownTroy v2 感染链
- SysPhon 感染链
- 人工智能驱动的攻击策略
- GhostHire活动
- 初始访问
- 恶意Golang软件包
- 恶意TypeScript项目
- DownTroy:多平台下载器
- Windows平台的完整感染链
- 新的有效载荷投递方法
- UAC绕过
- Go语言编写的RooTroy.Windows
- Go语言编写的RealTimeTroy
- Go语言编写的CosmicDoor.Windows
- Rust语言编写的Bof加载器
- 受害者
- 归因
- 结论
- 危害指标
引言
BlueNoroff(又名Sapphire Sleet、APT38、Alluring Pisces、Stardust Chollima和TA444)自出现以来主要专注于经济利益,随着时间推移采用了新的渗透策略和恶意软件集,但其作为SnatchCrypto行动的一部分,仍以区块链开发者、Web3/区块链行业的C级高管和经理为目标。今年早些时候,我们研究了BlueNoroff在SnatchCrypto行动下的两项恶意活动,分别命名为GhostCall和GhostHire。
GhostCall主要通过Telegram等平台直接联系科技公司和风险投资领域的高管,并邀请潜在受害者加入与Zoom类似的钓鱼网站上的投资相关会议,从而严重针对这些高管的macOS设备。受害者会加入一个虚假通话,其中使用了该威胁行为者其他真实受害者的真实录像,而非深度伪造视频。通话顺利进行,然后诱使用户使用脚本来更新Zoom客户端。最终,该脚本会下载ZIP文件,导致在受感染主机上部署感染链。
在GhostHire活动中,BlueNoroff会接触Web3开发者,并诱骗他们在招聘过程中以技能评估为名下载并执行包含恶意软件的GitHub仓库。在初步接触和简短筛选后,“招聘人员"会将用户添加到一个Telegram机器人中。该机器人会发送一个ZIP文件或GitHub链接,并附带30分钟的时间限制来完成任务,同时向受害者施压,要求其快速运行恶意项目。一旦执行,该项目就会从外部服务器下载恶意有效载荷到用户系统。有效载荷是根据用户代理(User-Agent)选择的,该代理标识了受害者使用的操作系统。
我们观察到攻击者在攻击的各个方面利用人工智能(AI),这使他们能够提高生产力并精心完善攻击。GhostHire中观察到的感染方案在感染链结构上与GhostCall活动相似,并且在两者中都检测到了相同的恶意软件。
我们自2025年4月以来一直在跟踪这两项活动,特别是观察到GhostCall活动的受害者持续在X等平台上出现。我们希望我们的研究能有助于防止进一步的损害,并向所有自愿分享相关信息的人士表示感谢。
关于GhostCall的相关信息已被微软、Huntability、Huntress、Field Effect和SentinelOne披露。然而,我们涵盖了新发现的恶意软件链,并提供了更深入的见解。
GhostCall活动
GhostCall活动是一种复杂的攻击,攻击者伪装成虚假的企业家或投资者,利用虚假的在线通话来说服目标。GhostCall至少自2023年中开始活跃,可能是在RustBucket活动之后,该活动标志着BlueNoroff全面转向攻击macOS系统。该活动最初以Windows为重点;但很快转向macOS,以更好地适应目标主要使用macOS的环境,并利用欺骗性视频通话来最大化影响。
GhostCall活动采用复杂的虚假会议模板和虚假Zoom更新程序来欺骗目标。历史上,攻击者经常使用与IP访问控制相关的借口,但后来转向音频问题,以说服目标下载恶意的AppleScript代码来修复。最近,我们观察到攻击者试图将目标平台从Zoom转向Microsoft Teams。
在此次调查中,我们识别了七种不同的多组件感染链、一个窃密工具套件和一个键盘记录器。模块化的窃密工具套件从主机收集大量机密文件,包括有关加密货币钱包、钥匙串数据、包管理器(Package Managers)和基础设施设置的信息。它还捕获与云平台和DevOps相关的详细信息,以及笔记、OpenAI的API密钥、协作应用程序数据,以及存储在浏览器、即时通讯工具和Telegram消息应用程序中的凭据。
初始访问
攻击者通过在Telegram上冒充风险投资家来接触目标,在某些情况下会使用真实企业家和初创公司创始人的被入侵账户。在初始消息中,攻击者会宣传投资或合作机会。一旦与目标建立联系,他们会使用Calendly安排会议,然后通过模仿Zoom的域名分享会议链接。有时,他们可能直接通过Telegram消息发送虚假会议链接。攻击者偶尔也会使用Telegram的超链接功能来隐藏钓鱼URL,并将其伪装成合法URL。
访问虚假网站后,目标会看到一个精心设计的页面,模仿浏览器中Zoom的外观。该页面使用标准浏览器功能提示用户启用摄像头并输入姓名。一旦激活,JavaScript逻辑就开始录制,并每秒使用POST方法将视频片段发送到攻击者虚假Zoom域的/upload端点。
目标加入后,会出现一个类似于实际Zoom会议的屏幕,显示三个参与者的视频流,就像他们是真实会话的一部分。根据我们监控的OSINT,许多受害者最初认为他们遇到的视频是由深度伪造或AI技术生成的。然而,我们的研究表明,这些视频实际上是攻击者使用相同方法秘密录制的其他受害者的真实录像。他们的网络摄像头录像在不知情的情况下被录制,然后上传到攻击者控制的基础设施,并被重复使用以欺骗其他受害者,使他们相信他们正在参与真实的实时通话。当视频回放结束时,页面会平滑过渡到显示用户的个人资料图像,以维持实时通话的假象。
大约三到五秒后,参与者视频流下方会出现一条错误消息,指出系统运行不正常,并提示他们通过标记为"立即更新"的链接下载Zoom SDK更新文件。然而,该链接并非提供更新,而是在macOS上下载一个恶意的AppleScript文件,并在Windows上触发一个故障排除弹窗。
在macOS上,点击链接会直接从攻击者的域名下载一个名为Zoom SDK Update.scpt的AppleScript文件。还会显示一个小的"下载"标记,模仿真实的苹果反馈,巧妙地鼓励用户执行脚本。在Windows上,攻击使用ClickFix技术,弹出一个模态窗口,其中包含来自合法域名的看似无害的代码片段。然而,任何尝试复制代码的操作——通过复制按钮、右键单击复制或Ctrl+C——都会导致一个恶意的一行命令被放入剪贴板。
我们观察到攻击者在恶意网页中实施了信标活动,以跟踪受害者的交互。页面会向其后端基础设施报告——可能是为了评估目标攻击的成功或失败。这是通过受害者执行特定操作时自动触发的一系列HTTP GET请求实现的。
我们成功获取了攻击者声称解决问题所必需的AppleScript(Zoom SDK Update.scpt),这已通过大量研究作为攻击的入口点而广为人知。该脚本伪装成Zoom Meeting SDK的更新,包含近10000行空白行,以掩盖其恶意内容。执行后,它会使用curl命令从另一个虚假链接获取另一个AppleScript,该脚本充当下载器。存在许多此"故障排除"AppleScript的变体,文件名、用户代理和内容各不相同。
如果目标macOS版本为11(Monterey)或更高,下载器AppleScript会安装一个伪装成Zoom或Microsoft Teams的虚假应用程序到/private/tmp目录。该应用程序试图通过显示密码输入弹窗来模仿Zoom或Teams的合法更新。此外,它会下载一个下一阶段的AppleScript,我们将其命名为"DownTroy”。该脚本预计会检查存储的密码,并使用它们以root权限安装额外的恶意软件。
此外,下载器脚本包含一个收集函数,用于搜索与密码管理应用程序(如Bitwarden、LastPass、1Password和Dashlane)、默认笔记应用程序(group.com.apple.notes)、Evernote等笔记应用程序以及设备上安装的Telegram应用程序相关的文件。
该下载器脚本的另一个显著功能是绕过了TCC(Transparency, Consent, and Control),这是一个macOS系统,旨在管理用户访问敏感资源(如摄像头、麦克风、AppleEvents/自动化和受保护文件夹如Documents、Downloads和Desktop)的同意。该脚本的工作原理是重命名用户的com.apple.TCC目录,然后对TCC.db数据库进行离线编辑。具体来说,它会删除访问表中与要注册到TCC数据库中的客户端路径相关的任何现有条目,并执行INSERT OR REPLACE语句。此过程使脚本能够授予攻击者控制的客户端路径自动化和文件访问的AppleEvents权限。脚本会为TCC使用的服务标识符插入行,包括kTCCServiceAppleEvents、kTCCServiceSystemPolicyDocumentsFolder、kTCCServiceSystemPolicyDownloadsFolder和kTCCServiceSystemPolicyDesktopFolder,并在数据库中放置一个十六进制编码的代码签名Blob(csreq风格)以满足授予访问权限的要求。这个二进制Blob必须绑定到目标应用程序的代码签名,并在运行时进行评估。最后,脚本尝试将TCC目录重命名回其原始名称,并调用tccutil reset DeveloperTool。
在我们分析的样本中,客户端路径是~/Library/Google/Chrome Update——攻击者用于其植入程序的路径。简而言之,这允许植入程序控制其他应用程序,访问用户Documents、Downloads和Desktop文件夹中的数据,并执行AppleScripts——所有这些都无需提示用户同意。
多阶段执行链
根据我们的遥测和对攻击者基础设施的调查,DownTroy会从攻击者的集中式文件托管服务器下载包含各种独立感染链的ZIP文件。虽然我们尚未观察到SysPhon和SneakMain链是如何安装的,但我们推测它们也是以相同方式下载的。我们不仅从服务器识别了至少七个多阶段执行链,还识别了各种安装在受感染主机上的恶意软件家族,包括由CosmicDoor和RooTroy链下载的键盘记录器和窃密软件。
攻击者自2023年以来一直通过采用新的编程语言和开发新的组件来引入新的恶意软件链。在此之前,他们使用的是独立的恶意软件家族,但后来演变为由启动器、注入器、安装器、加载器和释放器组成的模块化结构。这种模块化方法使得恶意行为可以分成更小的组件,从而更容易绕过安全产品并规避检测。这些链中的大多数最终有效载荷都能够下载额外的AppleScript文件或执行命令来检索后续阶段的有效载荷。
有趣的是,攻击者最初偏爱使用Rust编写恶意软件,但最终转向了Nim语言。同时,其他编程语言如C++、Python、Go和Swift也被使用。C++语言用于开发注入器恶意软件以及注入器内的基础应用程序,但该应用程序后来用Swift重写。Go也曾用于开发恶意软件链的某些组件,例如安装器和释放器,但这些后来也切换到了Nim。
ZoomClutch/TeamsClutch:伪造的Zoom/Teams应用
在研究受害者机器上的macOS入侵时,我们发现一个可疑的应用程序类似于Zoom客户端,从一个非典型的可写路径/tmp/zoom.app/Contents/MacOS(而非标准的/Applications目录)执行。分析显示,该二进制文件不是官方的Zoom构建,而是一个自定义植入程序,使用Xcode 16 beta 2 (16C5032a) 针对macOS 15.2 SDK在macOS 14.5 (24F74)上编译。该应用程序是临时签名的,其捆绑包标识符硬编码为us.zoom.com以模仿合法客户端。
该植入程序使用Swift编写,并作为macOS凭据收集器,伪装成Zoom视频会议应用程序。它使用Swift的现代UI框架开发了一个完善的用户界面,紧密模仿了Zoom应用程序图标、苹果密码提示和其他真实元素。
ZoomClutch通过显示虚假的Zoom对话框来窃取macOS密码,然后将捕获的凭据发送到C2服务器。然而,在泄露数据之前,ZoomClutch首先使用苹果的Open Directory (OD)在本地验证凭据,以过滤掉拼写错误和不正确的条目,这模仿了macOS自身的身份验证流程。OD管理本地和外部目录的账户和身份验证过程。本地用户数据位于/var/db/dslocal/nodes/Default/users/,作为带有PBKDF2-SHA512哈希值的plist文件。恶意软件创建一个ODSession,然后通过kODNodeTypeLocalNodes (0x2200/8704)打开一个本地ODNode,将操作范围限定在/Local/Default。
随后,它调用verifyPassword:error:来检查密码,该函数使用存储的盐和迭代次数对输入的密码重新哈希,如果匹配则返回true。如果验证失败,ZoomClutch会重新提示用户,并很快显示一个带有抖动动画的"密码错误"弹窗。成功后,它会隐藏对话框,显示"Zoom Meeting SDK已更新成功"的消息,并且经过验证的凭据会秘密发送到C2服务器。
在提示框中输入的所有密码都会记录到~/Library/Logs/keybagd_events.log中。恶意软件随后在~/Library/Logs/<用户名>_auth.log创建一个文件,以明文形式存储验证后的密码。该文件随后使用curl上传到C2 URL。
伪装成合法Microsoft Teams的TeamsClutch恶意软件功能与ZoomClutch类似,但替换了其徽标和一些文本元素。
DownTroy v1 感染链
DownTroy v1链由启动器和释放器组成,最终加载用AppleScript编写的DownTroy.macOS恶意软件。
释放器以两种不同的模式运行:初始化模式和操作模式。当二进制文件以机器ID (mid) 作为唯一参数执行时,它进入初始化模式,并使用提供的mid更新位于~/Library/Assistant/CustomVocabulary/com.applet.safari/local_log的配置文件,并用RC4加密。然后,它不带任何参数地运行自身以切换到操作模式。如果二进制文件启动时没有任何参数,则直接进入操作模式。在此模式下,它会检索先前保存的配置,并使用RC4密钥NvZGluZz0iVVRGLTgiPz4KPCF解密。需要注意的是,mid值必须首先在初始化模式中包含在配置中,因为这对于后续操作至关重要。
然后,它对与DownTroy.macOS相关的硬编码、base64编码的字符串进行解码。该AppleScript包含一个占位符值%mail_id%,该值被配置中初始化的mid值替换。修改后的脚本被保存到配置中<BasePath>目录下名为local.lock的临时文件中,并应用0644权限,这意味着只有脚本所有者可以修改它。恶意软件然后使用osascript执行DownTroy.macOS,并设置Setpgid=1以隔离进程组。DownTroy.macOS负责从C2服务器下载额外的脚本,直到系统重启。
释放器实现了一个信号处理过程,以监控终止尝试。最初,它将整个trustd(自身)和watchdog二进制文件读入内存,在删除原始文件之前将它们存储在缓冲区中。当接收到表示进程应终止的SIGINT或SIGTERM信号时,恢复机制会被激活以保持持久性。
恢复机制首先以故意不安全的0777权限重新创建<BasePath>目录(意味着所有用户都有读、写和执行权限)。接下来,它从内存中将两个二进制文件写回磁盘,赋予它们可执行权限(0755),并创建一个plist文件以确保此进程链的自动重启。
plist文件的内容以base64编码的形式硬编码在释放器中。解码后,模板代表一个标准的macOS LaunchAgent plist,包含占位符令牌#path和#label。恶意软件会替换这些令牌以自定义模板。最终的plist配置通过将RunAtLoad设置为true(在登录时启动)、KeepAlive设置为true(如果终止则重新启动)以及LaunchOnlyOnce设置为true来确保启动器的自动执行。
#path被替换为复制的watchdog的路径#label被替换为com.applet.safari,伪装成合法的Safari相关组件
CosmicDoor 感染链
CosmicDoor链始于一个注入器恶意软件,我们将其命名为"GillyInjector",用C++编写。该恶意软件包含一个加密的baseApp和一个加密的恶意有效载荷。
注入器以两种模式运行:擦除模式和注入器模式。当使用--d标志执行时,GillyInjector会激活其破坏性功能。它首先枚举当前目录中的所有文件,并安全地删除每个文件。一旦目录中的所有文件都被不可恢复地擦除,GillyInjector会继续删除目录本身。当以文件名和密码执行时,GillyInjector作为进程注入器运行。它在当前目录中使用给定的文件名创建一个良性应用程序,并使用提供的密码派生AES解密密钥。
良性Mach-O应用程序及其嵌入的有效载荷使用定制的AES-256算法在ECB模式(虽然结构类似于OFB模式)下加密,然后进行base64编码。为了解密,编码字符串的前16个字节被提取作为盐,用于PBKDF2密钥派生过程。此过程使用10,000次迭代和用户提供的密码生成基于SHA-256的密钥。派生密钥随后用于解密后续的base64解码后的密文。
最终注入的有效载荷被识别为用Nim编写的CosmicDoor.macOS。CosmicDoor的主要特点是它使用WSS协议与C2服务器通信,并提供接收和执行命令等远程控制功能。
我们的遥测表明,到目前为止至少检测到三个版本的CosmicDoor.macOS,每个版本都使用不同的跨平台编程语言编写,包括Rust、Python和Nim。我们还发现CosmicDoor的Windows变体是用Go开发的,这表明自2023年以来,威胁行为者一直在Windows和macOS环境中积极使用这种恶意软件。根据我们的调查,CosmicDoor的开发可能遵循以下顺序:CosmicDoor.Windows in Go → CosmicDoor.macOS in Rust → CosmicDoor in Python → CosmicDoor.macOS in Nim。Nim版本是最近识别的,主要由于其更新的执行链而脱颖而出,包括使用了GillyInjector。
除了注入器的出现之外,Windows版本与其他版本之间的差异并不显著。在Windows上,所有RC4密钥值的第四到第六个字符初始化为123。此外,用Nim编写的CosmicDoor.macOS版本更新了COMMAND_KEY的值。
相同的命令方案仍在使用中,但其他版本仅实现了Windows上可用命令的一部分。值得注意的是,345、90和45等命令在CosmicDoor的Python实现中列出,但其实际代码并未实现。
SilentSiphon:窃密工具套件
在我们的调查中,我们发现CosmicDoor下载了一个由各种bash脚本组成的窃密工具套件,我们将其命名为"SilentSiphon"。在大多数观察到的感染中,在安装CosmicDoor后不久,受感染的主机上创建了多个bash shell脚本。这些脚本用于收集数据并将其泄露到攻击者的C2服务器。
名为upl.sh的文件充当协调启动器,它聚合了在受害者系统上识别的多个独立数据提取模块。
协调器首先使用命令who | tail -n1 | awk '{print $1}'来识别当前登录的macOS用户的用户名,从而确保所有后续文件路径都在正在进行的活动会话中解析——无论脚本是由另一个账户执行还是通过Launch Agents执行。但是,硬编码的C2服务器和用户名都可以分别用-h和-u标志修改,这一特性与本研究中分析的其他模块一致。协调器执行位于同一目录中的五个嵌入式模块,并在每个模块完成泄露后立即删除。
该窃密套件从被入侵主机收集数据如下:
upl.sh是协调器和苹果笔记窃密器。cpl.sh是浏览器扩展窃密模块。ubd.sh是浏览器凭据和macOS钥匙串窃密模块。secrets.sh是机密信息窃密模块。uad.sh是密码库窃密模块。utd.sh是Telegram窃密模块。
这些极其广泛的目标使得攻击者能够超越简单的凭据,涵盖受害者的整个基础设施。这包括可用于进一步攻击的Telegram账户、供应链配置详细信息,以及揭示与其他用户个人笔记和业务交互的协作工具。值得注意的是,攻击者甚至以.openai文件夹为目标,秘密地使用用户的账户来使用ChatGPT。
收集到的信息立即使用ditto -ck命令进行归档,并通过curl命令上传到初始化的C2服务器,方法与ZoomClutch中相同。
RooTroy 感染链
我们识别了一个从文件托管服务器下载的ZIP存档,其中包含一个三组件工具集。最终有效载荷RooTroy.macOS也在Huntress的博客中被记录过,但我们能够获取其完整链。该存档包含以下内容:
- 安装器:主要的安装器文件,名为"rtv4inst",用Go编写
- 加载器:一个辅助加载器文件,名为"st",被识别为Nimcore加载器,用Nim编写
- 注入器:一个注入器文件,名为"wt",被识别为GillyInjector,用C++编写
- 最终有效载荷:RooTroy.macOS,用Go编写
安装器执行后,立即检查其他组件的存在,如果缺少任何组件则终止。此外,它验证自己是否至少接受了两个命令行参数才能正常运行。
安装器首次启动时,会创建几个目录和文件,模仿合法的macOS组件。需要注意的是,这些路径仅用于伪装;没有一个是真实的系统位置。
安装器使用硬编码的密钥3DD226D0B700F33974F409142DEFB62A8CD172AE5F2EB9BEB7F5750EB1702E2A将其运行时参数序列化为RC4加密的Blob。生成的加密值作为.cfg写入/Library/Google/Cache/内部。
然后,安装器通过动态捆绑ID生成机制为plist命名,它扫描/Applications中的合法应用程序以创建令人信服的标识符。它枚举.app捆绑包,提取它们的名称,并将其与面向服务的术语(如"agent"、“webhelper”、“update”、“updater”、“startup”、“service”、“cloudd”、“daemon”、“keystone.agent”、“update.agent"或"installer”)组合以构建捆绑ID,例如"com.safari.update"或"com.chrome.service"。如果捆绑ID生成过程因任何原因失败,恶意软件将默认使用硬编码的回退标识符"com.apple.updatecheck"。
然后,安装器将ZIP解压目录中的辅助二进制文件部署到它们的最终系统位置。Nimcore加载器 (st) 被复制到/Library/Application Support/Logitechs/bin/Update Check。GillyInjector二进制文件在/Library/Storage/CPU路径中重命名为cpumons。这两个文件都获得0755权限以确保可执行性。
随后,通过macOS Launch Daemon plists实现持久性机制。plist模板包含四个占位符字段,在生成时填充:
Label字段接收动态生成的捆绑ID。SERVER_AUTH_KEY环境变量被填充为GillyInjector的路径/Library/Storage/CPU/cpumons,该路径使用硬编码密钥"yniERNUgGUHuAhgCzMAi"进行RC4加密,然后进行base64编码。CLIENT_AUTH_KEY环境变量接收硬编码值".."。Program字段指向已安装的Nimcore加载器的路径。
安装器通过使用合法的launchctl命令激活持久性机制来完成持久性设置,确保Nimcore加载器被执行。它首先对任何具有相同名称的现有plist运行"launchctl unload <bundle ID>.plist"以移除先前的实例,然后执行"launchctl load <bundle ID>.plist"以通过/bin/zsh -c激活新的持久性配置。
该执行链中的第二阶段是Nimcore加载器,由安装器部署并在plist文件的Program字段中指定。该加载器通过getenv()读取SERVER_AUTH_KEY环境变量,对值进行base64解码,并使用与安装器相同的RC4密钥解密。加载器能够检索必要的值,因为SERVER_AUTH_KEY和CLIENT_AUTH_KEY都在plist文件中提供并由安装器填充。解密后,它调用posix_spawn()来启动GillyInjector。
GillyInjector是RooTroy链中的第三个组件,其行为与CosmicDoor链中描述的行为相同。但是,在此实例中,用于生成的密码在组件内部硬编码为xy@bomb#。baseApp主要负责仅显示简单消息,并充当载体,在运行时将注入的最终有效载荷保留在内存中。
最终有效载荷被识别为用Go编写的RooTroy.macOS。初始化后,RooTroy.macOS从/Library/Google/Cache/.cfg(由主安装器创建的文件)读取其配置,并使用相同的RC4密钥3DD226D0B700F33974F409142DEFB62A8CD172AE5F2EB9BEB7F5750EB1702E2A通过RC4算法解密。如果无法读取配置文件,它会删除/Library/Google/Cache中的所有文件并退出。
由于通过plist设置在每次启动时执行有效载荷,它通过检查同一目录中的.pid文件来防止重复执行。如果在文件中找到进程ID,它会终止相应的进程并将当前进程ID写入文件。此外,它还将字符串{"rt": "4.0.0."}写入同一目录下的.version文件,以指示当前版本。该字符串使用密钥C4DB903322D17C8CBF1D1DB55124854C0B070D6ECE54162B6A4D06DF24C572DF通过RC4加密。
此后门逐行执行来自/Library/Google/Cache/.startup文件的命令。每一行通过/bin/zsh -c "[command]"在单独的进程中执行。它还监控用户的登录状态,并在用户注销后重新登录时重新执行命令。
接下来,RooTroy收集并列出所有已挂载的卷和正在运行的进程。然后它进入一个无限循环,反复重新枚举卷以检测任何变化(例如新连接的USB驱动器、网络共享或卸载的设备),并使用不同的函数来识别自上次迭代以来进程列表中的变化。它通过POST请求将收集到的信息发送到C2服务器的/update端点,并附带Content-Type: application/json。
来自C2服务器的响应中的data字段直接通过osascript -e使用AppleScript执行。当url和auth字段都存在时,RooTroy使用GET方法和Authorization头部连接到URL以检索其他文件。然后它休眠五秒并重复该过程。
附加文件的加载方式如下:
- 在临时目录中生成一个随机的10字符文件名:
/private/tmp/[随机字符]{10}.zip。 - 将下载的数据保存到该文件路径。
- 使用
ditto -xk /private/tmp/[随机字符]{10}.zip /private/tmp/[随机字符]{10}提取ZIP文件。 - 使用
chmod +x /private/tmp/[随机字符]{10}/install使文件可执行。 - 可能通过执行
/bin/zsh /private/tmp/[随机字符]{10}/install /private/tmp/[随机字符]{10} /private/tmp/[随机字符]{10}/.result来安装其他组件。 - 检查
.result文件中是否有字符串"success"。 - 将结果发送到
/report端点。 - 递增
cid字段并保存配置。 - 清理所有临时文件。
我们还观察到RooTroy后门将名为keyboardd的文件部署到/Library/keyboard目录,将airmond部署到/Library/airplay路径,这些文件被确认为键盘记录器和信息窃取器。
RealTimeTroy 感染链
我们最近从公共多扫描服务中发现了包含加密的RealTimeTroy.macOS有效载荷的GillyInjector。
RealTimeTroy是一个用Go编程语言编写的简单后门,使用WSS协议与C2服务器通信。我们获取了此恶意软件的两个版本。在第二个版本中,名为"ChromeUpdates"的baseApp应与注入器捆绑在一个ZIP文件中。虽然baseApp数据以与其他GillyInjector实例相同的方式包含在内,但实际上并未使用。相反,ChromeUpdates文件被复制到指定为第一个参数的路径,并作为注入的基础应用程序执行。
与Windows版本一样,它在收到命令16时注入有效载荷。但是,它使用类似于GillyInjector的功能来注入从C2接收的有效载荷。用于AES解密的密码和RealTimeTroy内部硬编码的baseApp已被确认为与现有的GillyInjector(MD5 76ACE3A6892C25512B17ED42AC2EBD05)相同。
此外,与Windows版本相比增加了两个新命令,专门用于通过伪终端处理命令。命令20和21分别用于生成和退出终端,该终端用于执行从命令8接收的命令。
我们在第二个版本的RealTimeTroy.macOS内部发现了vcs.time元数据,这暗示了此恶意软件的提交时间,该值设置为2025-05-29T12:22:09Z。
SneakMain 感染链
在对各种事件进行调查期间,我们能够在受害者的基础设施中识别出另一个涉及macOS版SneakMain的感染链。虽然我们无法获取安装器恶意软件,但考虑到其加载器的行为,它的运行方式可能与RooTroy链类似。
Nimcore加载器在执行时读取SERVER_AUTH_KEY和CLIENT_AUTH_KEY环境变量。考虑到RooTroy链的流程,我们可以假设这些值是通过安装器组件安装的plist文件提供的。接下来,对值进行base64解码,然后使用硬编码密钥vnoknknklfewRFRewfjkdlIJDKJDF通过RC4算法解密,该密钥在整个SneakMain链中一致使用。解密的SERVER_AUTH_KEY值应表示加载器要执行的下一个有效载荷的路径,而解密的CLIENT_AUTH_KEY值则保存到位于/private/var/tmp/cfg的配置文件中。
我们观察到,在所有恶意软件中,此加载器以最多的各种名称安装。
由Nimcore加载器加载的有效载荷被识别为用Nim编程语言编写的SneakMain.macOS。执行后,它从/private/var/tmp/cfg读取其配置,该文件可能由安装器创建。配置的原始内容通过使用相同密钥的RC4解密和base64解码来恢复。在配置中,C2 URL和机器ID (mid) 用管道字符("|")连接。然后SneakMain.macOS构造一个包含此信息以及附加字段(如恶意软件版本、当前时间和进程列表)的JSON对象,该对象随后被序列化并发送到C2服务器。请求包括头部Content-Type: application/json。
作为响应,恶意软件接收额外的AppleScript命令,并使用osascript -e命令执行它们。如果无法获取响应,它会每分钟尝试连接到默认的C2服务器。有两个URL硬编码到恶意软件中:hxxps://file-server[.]store/update 和 hxxps://cloud-server[.]store/update。
该链的一个有趣的外部组件是配置更新器。此更新器验证配置文件的存在,并将C2服务器地址更新为hxxps://flashserve[.]store/update,使用相同的加密方法,同时保留现有的mid值。更新成功后,它将更新后的配置输出到标准输出。
除了基于Nim的链,我们还识别了先前版本的SneakMain.macOS二进制文件,用Rust编写。此版本仅包含启动器和基于Rust的SneakMain。预计它会创建相应的plist以供常规执行,但尚未发现。Rust版本支持两种执行模式:
- 带参数:恶意软件使用C2服务器和
mid作为参数 - 不带参数:恶意软件加载位于
/Library/Scripts/Folder Actions/Check.plist的加密配置文件
此版本仅在执行的特定时间收集进程列表,而不检查新创建或终止的进程。然后,收集到的列表通过POST请求与当前时间 (uid) 和机器ID (mid) 一起发送到C2服务器hxxps://chkactive[.]online/update,使用Content-Type: application/json头部。类似地,它使用osascript -e命令执行从C2服务器接收的命令。
DownTroy v2 感染链
DownTroy.macOS v2感染链是最新的变体,由四个组件组成,有效载荷为AppleScript,其余部分用Nim编写。它已被SentinelOne以"NimDoor"的名称报道过。此链中的Nimcore加载器伪装成Google LLC,通过将"Google LLC"中的"l"(小写"L")替换为"I"(大写"i")来故意制造拼写错误。
安装器很可能是由先前的恶意脚本下载并启动的,作为此流程的入口点。释放器接收中断(SIGINT)或终止信号(SIGTERM),类似于DownTroy v1链,在磁盘上重新创建组件以恢复它们。值得注意的是,虽然先前描述的RooTroy和SneakMain链没有此恢复功能,但我们观察到它们配置了plist文件,以便在进程终止一小时后自动执行Nimcore加载器,并保留其他组件。这展示了攻击者如何战略性地利用DownTroy链来更隐秘地操作,突出了每条链之间的一些关键差异。
安装器应提供一个参数,如果执行时没有参数则会退出。然后它将./CoreKitAgent和./GoogIe LLC从当前位置复制到~/Library/CoreKit/CoreKitAgent和~/Library/Application Support/Google LLC/GoogIe LLC。安装器内部硬编码了com.google.update.plist(plist的名称)以建立持久性,随后释放器和加载器会引用此文件。然后,安装器将此值、给定的参数和释放器的文件名连接成一个单独的字符串,用管道("|")分隔。
此字符串使用具有硬编码密钥和IV的AES算法加密,然后将生成的加密数据保存到配置文件中。
- 密钥:
5B77F83ECEFA0E32BA922F61C9EFFF7F755BA51A010DB844CA7E8AD3DB28650A - IV:
2B499EB3865A7EF17264D15252B7F73E - 配置文件路径:
/private/tmp/.config
它通过最终执行位于~/Library/CoreKit/CoreKitAgent的已复制释放器来完成其功能。
DownTroy v2链中的释放器使用macOS的kqueue以及Nim的异步运行时来管理异步控制流,类似于CosmicDoor、RooTroy链中的Nimcore加载器以及SneakMain.macOS的Nim版本。释放器通过kqueue监视事件,当事件触发时,它通过Nim管理的状态机恢复相应的异步任务。主要功能在异步状态机的状态1中实现。
然后,释放器从/private/tmp/.config读取加密配置,并使用硬编码的密钥和IV通过AES算法解密,这些密钥和IV与安装器中使用的相同。通过用"|“分割解密后的数据,它提取加载器路径、plist路径和提供给安装器的参数。接下来,它读取自身和加载器的所有内容,并删除它们以及plist文件,以消除它们存在的任何痕迹。当释放器终止时,会触发一个处理函数,该函数使用先前读取的内容重新创建自身和加载器文件。此外,一个硬编码的十六进制字符串被解释为ASCII文本,解码后的内容被写入从配置中获得的pl