恶意软件

凌晨 03∶37,一台域控被悄悄复制——BRICKSTORM 藏在 393 天的阴影里

五条 vCenter 日志记下了一台域控被复制、停留二十三分钟、随后消失的全过程,克隆机从未开机,揭开了管理面盲区;更广泛的 BRICKSTORM 报告提供跨案例的设备、身份与证据线索,却不能把它们续写成这名受害者的后续事件。

一幅暖纸三阶段 vCenter 序列:03:37,DC01 留在原位,带关机符号的临时轮廓副本出现;到 04:05,只有该副本从清单中消散。
文章导航

研究依据依据 GTIG 与 Mandiant 调查报告、vSphere 防御指南、Microsoft 审计文档,以及固定提交的 BRICKSTORM 扫描器源码完成事件重建

来源Google Threat Intelligence Group

1 凌晨 3:37,机房里多出了一台域控

2025 年 4 月 1 日 03:37:40 UTC,vCenter 收到了一项再普通不过的管理任务:VirtualMachine.clone。九秒后,下一条日志写出了源头和去向——位于 esxi01DC01 正在被复制到 esxi02,新机器叫 DC01-clone。03:42:07,复制完成。04:05:40,管理员要求销毁克隆机;七秒之后,它从清单里消失了。

这五条 VPXD 日志来自 Google 威胁情报团队公开的一起匿名事件。它们没有描写某段惊险的恶意代码,也没有触发一声刺耳的告警。执行操作的是本地 VSPHERE.LOCAL\Administrator 账户;vCenter 接受指令、搬运虚拟磁盘、报告成功,最后又按要求删除对象。若把每一行拆开看,几乎都像基础设施团队每天会做的正常工作。

真正不寻常的地方,是克隆机从头到尾都不必启动。它里面的杀毒软件没有运行,EDR 探针没有上线,Windows 也不会记录一次新的交互登录。对手不需要进入这台域控的操作系统,只需要从虚拟化管理层复制并挂载它的磁盘。对于域控,这可能把 Active Directory 数据库、系统注册表材料以及其他承载凭据的文件送到对手手里;如果被复制的是身份系统或密码保险库,具体文件会不同,道理却完全一样:先把整台机器悄悄搬走,再到一个不会唤醒机内防护的地方慢慢拆。

从复制完成到销毁,克隆对象在 vCenter 中又存活了大约二十三分钟。删除操作抹去了管理员最容易看见的那个东西——清单里名为 DC01-clone 的对象——却未必抹去整件事。任务有 task key,源机和目标机有对象标识,datastore 上出现过文件,主机和存储之间流动过数据,认证系统也见过发起操作的会话。调查从这里才真正开始:中间那台机器已经不在了,四周留下的记录还能不能重新拼到一起?

五条公开 VPXD 事件组成的时间线:03:37:40 发起克隆,03:37:49 开始复制,03:42:07 完成,04:05:40 发起销毁,04:05:47 移除对象。
图 2。五条日志很短,却足以重新打开整起事件。真正值得保存的是账户、任务键、事件键、源与目标对象、主机、datastore 和精确时间,而不只是那个很快被删除的克隆机名称。

1.1 客户机里一片安静,恰恰说明这条路走通了

许多安全体系习惯从操作系统内部向外看。进程启动、模块加载、用户登录、脚本执行、文件变化,安装在系统里的探针捕捉这些动作,再把遥测送到控制台。虚拟化平台把视角反了过来。vCenter 和 ESXi 可以在客户机毫不知情时复制、快照、挂载、迁移或改写一台虚拟机。谁拿到了管理层权限,谁就能站到所有终端探针的楼上一层。

所以,“DC01 没有报 EDR 告警”不能替这二十三分钟作证。DC01-clone 没有进程运行,因为对手根本不需要让它运行。真正该问的是:谁提交了克隆任务,哪个会话承载了操作,VMDK 被送到哪里,副本有没有注册或开机,存储路径在那几分钟内搬了多少数据,完成与删除之间又发生过什么。这里缺少客户机遥测不是“什么都没发生”的证据,而是这种手法成功时本来就会出现的样子。

这也改变了排查顺序。若分析人员先钻进被复制服务器的 Windows 日志,就等于从一间从未有人进门的房间开始找脚印。更合适的起点是 VPXD 任务与事件、vCenter SSO 审计、VAMI 访问、hostdvpxa、datastore 元数据以及管理地址的网络流量。随后再根据源虚拟机的用途,判断磁盘副本可能暴露哪些东西。即便克隆已经销毁,源机承担的业务角色仍会决定后续凭据轮换和影响排查的范围。

DC01-clone 这个名称直白得近乎慷慨,但名称从来不是可靠的锚点。管理员可以改名,自动化任务会复用标签,对手也可以故意套用备份命名。应当保存的是 vCenter 实例 UUID、VM managed object ID、VM instance UUID、任务键、事件键、源与目标主机标识、datastore 与文件夹标识、认证主体、会话以及采集时间。显示名消失之后,正是这些字段让不同系统里的记录还能认出彼此。

1.2 五条日志打开了一扇门,却不是一整本日记

开头这段克隆记录来自一个案例。GTIG 对 BRICKSTORM 的长篇报告则整理了 Mandiant 多次事件响应中反复出现的动作,并删去了客户细节。接下来会看到设备后门、vCenter 凭据、内存窃密组件、邮箱和代码仓库;它们共同解释了这种行动通常如何展开,却不意味着所有细节都在同一家公司、同一天按固定顺序发生。

这并不会削弱故事,反而让实际狩猎更准确。一台域控被异常克隆,是非常强的本地管理面证据;它自己不能证明 BRICKSTORM 或 UNC5221。反过来,没有出现 DC01-clone 这个名称,也不能让环境置身事外。Mandiant 至少在两个案例里看到对手复制敏感 Windows 服务器,还记录了其他获取凭据和资料的办法。真正应该寻找的是同一种行为:未经解释的管理权限,为一台承载长期秘密的系统制造短命、离线的完整副本。

五条日志还留下了第一个悬念。执行克隆的账户拥有足够高的 vSphere 权限,但这段记录没有解释权限从哪里来。要找到上一棒交接,调查必须从 vCenter 往回走:认证记录、短暂存在的本地账户、SSH 开启、来自设备网段的连接,以及可能泄露管理员凭据的系统。走不了多远,就会撞上这次行动最重要的数字——Mandiant 介入时,所调查入侵的平均驻留时间已经达到 393 天。

2 过了 393 天,案卷的第一页早已不见

三百九十三天,足够一张按年签发的证书过期,足够一个项目组换过成员,也足够常见安全平台轮转掉好几批原始日志。这个数字是 Mandiant 对所调查 BRICKSTORM 入侵计算出的平均驻留时间。在许多事件中,响应人员赶到时,手里的数据已经够不到最初那次进入。大家看得见对手仍在环境中活动,却再也翻不到他推门的那一页。

这种空白很容易被一个顺口的结论填满。BRICKSTORM 背后的活动集群长期关注面向互联网的设备;Mandiant 在至少一个案例中确认了零日漏洞利用,也在其他事件早期发现对手从若干远程接入设备上活动。但剩余证据并不能证明每一次入侵都由漏洞利用开始。有些入口不是被否定了,而是对应的日志已经过期。最有用的事实因此并不整齐:至少一次零日利用确实发生,对外服务与远程接入系统反复成为关键节点,而不少组织已经无法还原自己最初究竟从哪里失守。

这不是一句只配放在脚注里的谨慎措辞,它直接决定怎么修。如果团队认定某一个产品漏洞就是所有事件的入口,打完补丁便结案,就可能把另一台失陷设备、一个仍然有效的账户或 vCenter 里的植入留在原处。如果又把所有解释不了的边缘设备活动都叫作“已确认漏洞利用”,就会把时间浪费在现存材料根本无法证明的细节上。更可靠的处理方式,是同时做两件事:修补、隔离每一条合理的暴露路径;再沿着尚存的行为记录,确认权限实际上走过哪里。

入口消失,也解释了为什么凌晨 3:37 的克隆记录如此重要。初始攻击的痕迹往往很脆弱,一条利用请求也许只在反向代理日志里活几天,甚至从未被记录。一年后,vSphere 任务、历史备份、账户变更、邮箱审计或长期网络关系,反而可能是更可靠的证人。调查不能执着于第一页,只能从还看得见的中段同时往前、往后重建。

393 天的入侵跨度穿过常见的 30 天和 90 天日志窗口,入口记录已经过期,而管理事件、压缩索引与备份仍可能留存。
图 3。只有 30 或 90 天记忆的控制台,完全可能看见一场 393 天入侵的结尾,却看不见开始。长期索引、受保护备份和集中管理面日志,决定旧问题还能不能被回答。

2.1 日志保留不再只是成本问题,而是威胁模型的一部分

常见保留策略围绕日常运维设计:留下足够原始数据处理近期告警,时间一长便聚合或删除。BRICKSTORM 把保留期限本身变成了安全控制。如果一台设备能够承载一年以上的高权限驻留,组织至少要保留关于它的长期记忆:它是谁、当时运行什么版本、配置怎样、连过哪里、以什么身份访问过谁、历史文件状态还能从哪份备份恢复。

并非所有网络都需要保留一年完整流量包。更现实的办法,是让一小组索引活得足够久。对每台设备,保存稳定资产标识、管理面和数据面地址、产品与精确构建、负责人、生命周期状态、最近一次配置备份、允许访问的厂商目的地以及日志是否外送。网络侧保留目的地首次与最后出现时间、协议、字节数以及发起连接的接口或地址;身份侧保留账户、来源、目标、结果、会话或请求标识和权限变化;vSphere 侧保留任务键、事件键、对象标识、操作人、源、目标、结果和存储位置。

集中保存尤其重要,因为一台疑似被攻陷的在线设备,不能再被当成中立档案馆。拥有 root 权限的对手可以修改本机文件和日志,存在设备本地的配置备份也可能一起消失。记录应送往凭据和删除权限都与设备分离的存储。除了设备自己报告的时间,还要保留采集端收到数据的时间和时钟来源;否则,一只漂移或被改过的时钟就足以把原本相连的两件事拆开。

393 天也不是每家公司机械照抄的保留期限。它是已调查事件的平均值,不是对手会在第 394 天自动离开的承诺。它更像一道设计题:在可信的最长入侵周期里,组织还能不能回答谁控制过 Tier 0 设备、它连接过哪里、配置如何变化、哪些备份保存了更早状态?如果不能,“没有发现更早活动”的真实含义只是“我们的记忆从这里开始”。

2.2 找不到入口,就去找对手必须长期守住的落脚点

最初那次请求已经不在,仍可以寻找对手为了长期驻留不得不维持的东西。在 BRICKSTORM 案例中,这往往是一台基于 Linux 或 BSD 的网络设备。设备之所以诱人,不是因为它们天生神秘,而是许多组织无意间同时给了它们三种优势:靠近信任中心、缺少监控、服役时间很长。

VPN 集中器可能既认证用户,又能把流量送进内网;安全网关在被信任处理机密的同时还被允许访问互联网;虚拟化设备则掌握所有客户机。可这些系统很少支持笔记本和服务器上那套 EDR。一次 PoV 试用留下的盒子,项目负责人离职后仍可能连在生产网;一段管理地址可能从未进入终端资产检索;厂商镜像通过另一套流程升级,安全团队甚至没有可查询的软件清单。最有能力跨越信任区的系统,反而最容易从事件地图上缺席。

因此第一轮不该从哈希开始,而应从资产开始。列出防火墙、VPN 与远程接入设备、存储控制器、会议系统、门禁设备、虚拟化设备、管理服务器和厂商托管的试用系统。让每个管理 IP 对应到负责人和精确构建。标出哪些设备能主动连接内网、哪些可以访问互联网、哪些保存或中转凭据、哪些拥有受保护备份、哪些日志离开了本机。每一个空白格都不再只是运维欠账,而是下一次案卷第一页可能消失的地方。

资产表完成后,第二个问题才有办法回答:其中哪些设备曾经表现得像一台工作站或跳板机?查找管理地址主动发起 SSH、RDP、SMB、WinRM、LDAP、数据库或 vCenter 会话,而设备职责并不需要这些连接的情形。对外访问应与明确的厂商和业务目的清单比较;一句“基础设施可以上网”不能成为放行整个互联网的理由。关注上线很久后才第一次出现的目的地、持续很久的加密连接、直接 IP 服务、反常 DNS 模式以及维护窗口里仍未中断的通信。

公开报告说明 BRICKSTORM 带有 SOCKS 代理能力。一台不起眼的设备于是可以同时充当藏身处和通往下一台系统的路线。调查从已经消失的入口,终于走到一个终端工具从未覆盖过的落脚点。接下来要研究的是后门为何能保持安静,以及跨案例报告怎样把设备访问与后来进入 VMware 的权限联系起来;本地调查仍须为每一次交接寻找自己的证据。

3 后门住进了一台从未被当作终端管理的机器

BRICKSTORM 是一个用 Go 编写、内置 SOCKS 代理的后门。这句看似平淡的描述,刚好解释了它为什么适合这场行动。Go 程序通常能把大量依赖一起编进可执行文件,便于落到厂商各异的 Linux、BSD 设备上;SOCKS 代理则能把操作者的交互流量穿过失陷设备,让内网目标只看见一个熟悉的设备地址,互联网上那台陌生工作站仍躲在路线尽头。

Mandiant 从多家厂商的设备中恢复过 BRICKSTORM。虽然外部材料显示 Windows 变体可能存在,Mandiant 在自己处理的事件里没有见到它。这透露出一种清晰的选择:已知行动把精力放在传统终端监控最薄弱的地方。如果后门能住进没有受支持 EDR、缺少文件完整性监控、异常负载又常被当成“设备故障”的系统,它就不必天天和 Windows 防护正面较量。

样本还会贴着宿主改变外观。有些构建使用 Garble 混淆,有些带着更新的自定义 wssoft 库,文件名与部分功能也可能模仿设备上的正常组件。Mandiant 找到过一个特别耐心的样本:它把未来某一天写死在程序里,部署完成后继续沉默几个月,等日期到了才开始连接控制端。不同受害者之间没有观察到 C2 域名复用;已知基础设施还利用过 Cloudflare Workers、Heroku 应用,以及借助 sslip.ionip.io 直接解析到 IP 的域名。

跨案例调查图,把公开报告中分别出现的低监控设备、有效凭据、VAMI 与 vCenter 操作、离线 VM 克隆、邮箱和代码仓库证据放在同一张排查地图上。
图 4。这是跨案例调查图,不是凌晨 3:37 那起克隆案例的连续时间线。本地调查中,只有资产归属、地址转换、认证和 vSphere 记录能够接上时,管理 IP 才成为持久线索;这种连接比等待域名复用可靠。

3.1 每家受害者一套回连地址,昨天的封禁表今天就过期

原子指标当然仍有价值。公开报告给出了三个 SHA-256,分别对应 pg_updatespclistenvmp。环境里若直接命中,应立即保全文件并扩大排查。但同一份报告也说,Mandiant 没有观察到对手复用恶意样本,依赖精确指标很难找到更广泛的活动。这句话应该决定狩猎资源怎么分:哈希搜索是最快的第一遍,绝不是最后一遍。

应当围绕每个设备管理地址建立足够长的对外通信历史。DNS、防火墙、代理和流量记录按设备单独汇总,别让它们淹没在普通用户网段中。列清授权、升级、时间同步、厂商支持、遥测和业务功能真正需要的目的地,剩下的每一个例外都要有负责人和复核日期。一台 VPN 或虚拟化设备新出现的低流量 TLS 连接不必自动等同恶意,但也不能再被“基础设施允许访问互联网”这句笼统规则吞掉。

对手访问互联网服务时还使用过商业 VPN、代理,以及疑似由失陷小型办公或家庭路由器组成的专用混淆网络。出口地址变化太快,很难支撑长期的黑白名单。调查邮箱和应用会话时,更有价值的问题是“这段会话像不像它所代表的人或服务”:client ID 是否熟悉,来源是否属于预期运行环境,地理位置和 user agent 是否合理,目标邮箱是否符合业务,用途和时间是否说得通。一个新 IP 可能很无辜;一段不断换 IP、却持续盯着同一批异常目标的会话,则很难只用出差来解释。

3.2 代理真正值钱的地方,是设备本来就站在信任圈里

SOCKS 代理不会凭空产生权限,它改变的是操作者看起来从哪里来。流量穿过失陷设备后,内网侦察和管理操作都可以源自一个已经被放行的地址。只要网络策略允许设备广泛访问内部网段,对手就能探测服务、递交偷来的凭据、打开管理控制台,而防守方看到的来源仍然像一项基础设施。

Mandiant 多次看到这条路继续通向 VMware。在若干案例中,对手先把 BRICKSTORM 放到网络设备,随后横向进入 vCenter。进入时使用的是有效凭据,调查人员认为这些凭据很可能由设备上的恶意软件捕获。“有效”解释了为什么认证系统只记下一次成功登录,没有对应的漏洞攻击事件;“很可能被捕获”则要求响应人员检查管理员曾经经过哪些设备,不要只盯着目录里那个账户。

公开的一组 VAMI 访问记录朴素得几乎令人不安。来源先在 5480 端口请求 GET /,随后用 POST /rest/com/vmware/cis/session 建立会话,最后通过 PUT /rest/appliance/access/ssh 修改 SSH 状态。示例中三次请求均返回 HTTP 200。没有奇异报文,也不必利用内存漏洞;一段被正常接受的管理会话,借助产品原生接口打开了随后可直接进入的服务。

三次请求也为调查留下了很好的连接点:来源 IP、vCenter 地址、时间、user agent、referrer、认证主体、VAMI 会话,以及 SSH 修改前后的状态。顺着它们找到同一来源或相邻设备地址发起的第一次 SSH,继续连接到 sshd、PAM、sudo、可用的命令记录、文件创建和启动项变化。如果 SSH 后来又被关闭,关闭动作也应保留。一次很短的“管理窗口”,完全可能容纳整个植入过程。

3.3 防守方已经进场,对手仍在往更深处搬家

报告里有一个细节,让“它只是个忘在角落里、等日期到来才回连的程序”这种解释站不住脚。Mandiant 恢复过一份部署在内部 vCenter 上的 BRICKSTORM,而部署时间发生在受害组织已经开始事件响应之后。环境里不只是旧程序在按计划运行;有人正在观察防守压力,并迅速把持久化向管理层深处转移。

这也说明对手为什么会维持多个落脚点。Mandiant 描述的典型安排,是至少一台 BRICKSTORM 作为主要人工操作来源,另外两台或更多失陷设备用作备用。某一台设备重装后看起来干净,只能证明这台设备上的清理动作完成,不能证明对手已经离开。资产清单必须继续寻找同类设备、共享凭据、共同管理网段和它们之间解释不了的连接。

在这组公开案例中,线索一旦到达 vCenter,问题便从“找到一个后门”变成“找出设备权限曾在哪些地方兑换成管理权限”。其中一项公开调查找到了管理员每天使用的 Web 登录路径。对手在那里安装的东西,不需要改一份落盘配置,也不需要重启应用,就可以开始等待高价值凭据自己送上门。

4 对手没有唤醒那台机器,只把它整个偷走

在一台接受调查的 vCenter 上,Mandiant 找到一个运行在 Apache Tomcat Web 应用中的恶意 Java Servlet 过滤器。正常过滤器会在 HTTP 请求经过应用时检查或修改内容;这个被命名为 BRICKSTEAL 的组件盯着 vCenter 登录路径 /web/saml2/sso/*。一旦请求携带 HTTP Basic 认证头,它便解码其中内容,从而取得用户提交的用户名和密码。

安装办法和目标一样关键。常规情况下,新增 Servlet 过滤器需要修改配置并重启或重新加载应用。对手使用自定义 dropper,把恶意过滤器完全装进内存。没有必须出现的配置文件变化,也没有必然伴随的重启。窃密组件直接住进处理合法认证请求的进程,等真正的管理员把有价值的材料带到它面前。

许多组织让 vCenter 连接 Active Directory,而负责虚拟化的管理员在企业其他地方往往也拥有较高权限。一个被捕获的密码可能成为通向更广内网的桥,也可能在第一处落脚点被清理后帮助对手重新进入 vCenter。MFA 可以降低单独密码的价值,尤其当 vSphere 认证被设计成仅凭密码无法建立新会话时;但事件响应仍需检查现有会话、令牌、服务凭据,以及这个账户能够到达的所有下游系统。

4.1 一份凭据到了 vCenter,就获得了支配所有沉睡客户机的能力

虚拟化管理员无需登录 Windows 客户机,就能触碰它最重要的状态。管理层可以创建快照、复制 VM、挂载存储、改变启动介质、修改网络、在主机间迁移工作负载。这些能力对正常运维和灾难恢复不可或缺;落到错误会话里,也刚好绕过所有假设“客户机自己会为数据访问把关”的控制。

Mandiant 至少在两个案例中看到对手复制承载关键角色的 Windows Server:域控制器、SSO 身份提供者和秘密保险库。有了克隆,对手可以挂载文件系统,提取感兴趣的材料;公开报告以 Active Directory 的 ntds.dit 为例。密码库面对的提取过程不同,产品自身的保护依然有意义,但承载它的服务器必须被视为 Tier 0,因为操作系统或磁盘层访问可能暴露应用密钥、配置、受保护材料,甚至直接提供解密路径。

二十三分钟的窗口里藏着一个很容易踩中的陷阱。团队可能在“克隆”之后搜索“开机”,没有找到便降低优先级。这里恰恰相反:从不启动副本就是手法的一部分。需要重建的序列是发起克隆、传输数据、复制完成、可能的 datastore 或主机访问、随后删除。如果存储遥测显示大量读写而客户机始终关机,两者并不矛盾,说明真正工作的正是管理层。

4.2 删掉副本,只是删掉对象,不会替响应团队免除后果

克隆被销毁后会留下两种未知。第一,团队不一定知道二十三分钟内具体读了哪些数据;第二,也无法立刻知道由这些数据衍生的凭据后来去了哪里。如果非要等到每个秘密的提取都被逐项证明,才肯扩大轮换,对手可能早已握着能长期使用的权限。更安全的做法,是按照磁盘副本能够接触的内容来定处置范围。

若被复制的是域控,应假设目录数据和域凭据材料可能已经暴露,再依照组织的 Active Directory 恢复方案进行分阶段轮换。这远比改一个管理员密码复杂:服务账户、Kerberos 密钥、特权组、信任、证书以及嵌入凭据的系统都可能互相依赖。若是身份提供者,要检查签名与加密密钥、联合配置、管理员、连接器和已签发会话;若是秘密管理服务器,则要覆盖保存的凭据、应用加密材料、数据库访问、备份密钥,以及可在可疑时段检索秘密的账户。

轮换顺序尤其重要。在仍有植入或窃取会话能够看到新密码时直接改密,只是在给对手送一套更新鲜的凭据。应先保全材料、隔离收集点、吊销会话、移除未授权应用许可、收紧管理入口,再通过干净管理终端和可信通信渠道执行轮换。每个变更都要记录秘密、依赖系统、时间、执行人以及旧材料确实失效的验证结果。

4.3 跨案例目标包括邮件、源代码和夹在中间的秘密

已公开的行动目标远远超出基础设施。多起调查中,对手反复关注关键人员邮箱;有时目标是开发人员和系统管理员,有时是处理与中国经济或情报利益相关事务的人。Mandiant 观察到对手使用带有 Mail.Readfull_access_as_app 权限的 Microsoft Entra 企业应用读取邮件。这类权限的危险在于,它们能让一个应用触达大量邮箱,并不只代表某一位用户。

对手还用有效凭据登录内部代码平台,把仓库下载成 ZIP;另一些案例里,它通过 Windows UNC 路径浏览远程目录和文件。SaaS 与科技公司既掌握下游客户访问,也保存内部工程知识和可能用于寻找未来漏洞的代码;法律机构则持有涉及国家安全、国际贸易、谈判和客户的通信。这些公开观察说明了整组案例中的高价值目标,却不能证明凌晨 3:37 的克隆为后续邮件、代码或 UNC 访问提供了凭据。本地调查中,秘密库或域控被复制只会形成暴露假设,必须再用账户、令牌、会话、来源和目标系统审计来检验。

公开材料提供的是待检验的调查连接,不是沉睡克隆场景的连续后续。凌晨 3:37 的摘录证明控制面能够安静复制虚拟机;另一些调查分别记录了邮箱、代码、UNC 浏览、秘密库和下游目标。响应人员应检验本地身份材料能否把这些系统接起来,并明确写出证据停在哪里。也正因此,只盯哈希和回连域名远远不够:工具可以更换,资产、权限、会话和目标之间的关系却仍可验证,即使恶意文件早已被删除。

5 恶意文件已经不在,行为却比哈希活得更久

在若干案例中,响应人员没有从仍在线的失陷系统里找到 BRICKSTORM,因为对手已经删掉样本。Mandiant 最终通过检查历史备份,才在更早的系统状态中重新看见它。原本只负责恢复业务的备份,就这样成了一台时间机器:在线设备展示的是清理后的现在,受保护镜像则可能保留后门、启动项、账户和配置仍然存在时的过去。

这也让“扫描没有命中,我们是不是安全了”变成一个无法用是或否回答的问题。只有候选完整通过脚本实现的每一道关口并输出 MATCH: 时,文件级结论才是肯定的;没有 MATCH:,并不能证明每个已发现候选都被成功读取。扫描器不知道另一种构建上个月是否运行过,不知道二进制是否被删除,不知道拥有 root 权限的人有没有修改在线证据,也不知道对手是否在没有留下这份样本的情况下进入 vCenter。结果必须写成“完成了什么检查”,不能把一个阴性结果扩写成整个环境的健康证明。

为了帮助无法方便安装 YARA 的设备,Mandiant 发布了 shell 扫描器。上游历史中首次加入 find_brickstorm.sh 的是 2025 年 9 月 24 日的提交 68e66ae3c1ee2d7c3775b430c2aa9d2c814d1f37。SOSEC 早期源码复核使用了 03103ea6b651827407336e1e8529ba5f6094b7f8,但它只是 10 月 27 日较晚的 Photon OS xxd 兼容修订,并非扫描器的上游起点。本次复核固定在更晚的 fb2129cecd9561332608fbaac05884217c793a17;该状态包含面向 ESXi 的独立脚本,但两条路径仍围绕同一条公开规则 G_APT_Backdoor_BRICKSTORM_3 展开。

BRICKSTORM 通用扫描器的文件级路径:送入 check_file 的候选必须通过可读 ELF、完整字符串集和十六进制模式才输出 MATCH;没有 MATCH 时转入范围与失败复核、备份和行为排查。
图 5。扫描器设置的是一道“全部成立”的门,不做相似度打分。完整命中后保全文件并扩大事件范围。没有 MATCH: 本身不能结束任何更广泛的问题:先核对记录的输入方式、送入 check_file() 的候选,以及遍历、读取、超时或工具失败,再继续检查备份、持久化、进程、日志和网络行为。

5.1 扫描器连续问三个问题,三个答案都必须是“是”

通用 Bash 脚本对目录参数并非无边界遍历。每个目录参数都由 find 通过 -type f -size -10M 选择小于 10M 的普通文件,并硬编码排除四条路径正则:/proc/.*/tmp/[0-9]{10}/.*/var(/crash)?/nsproflog/newproflog.*/var(/crash)?/log/notice.log。显式传入的单个文件不经过这一步 find,会绕过当时的 10M 大小筛选和路径正则排除,直接加入候选清单并传给相同的 check_file()。因此,目录模式下没有 MATCH:,只描述通过这些发现条件并被送入 check_file() 的路径,不能证明每个路径都已成功读完全部关口。直接点名的文件即使不小于 10M 也可以尝试检查,但绕过发现筛选并不会绕过读取、超时和工具失败边界。

通用脚本的 check_file() 先排除无法读取的文件,再读取开头字节,要求结果为 7f45——也就是所用转储命令输出的 ELF 魔数前两个字节。文档、图片、压缩包、脚本和其他非 ELF 文件到这里就会停止,不再进入成本更高的检查。这一步只是把候选限制在公开 YARA 所描述的可执行格式。

随后,函数搜索一组必需字符串,并同时接受 ASCII 与 UTF-16LE 表示。列表包括 regexmimedecompressMIMEHeaderResolveReference 和规则中的长数字常量。它们不是投票项;少任意一个,函数都会直接返回。一个文件哪怕碰巧包含几条常见 Go 库字符串,也不会因为“看起来有点像”就被报告。

只有前面这些较快的检查全部通过,脚本才把完整文件转换成连续十六进制流,再应用由 YARA 字节序列转换而来的模式。全文件处理最耗时,所以被放在最后。ELF、全部字符串和字节模式都成立之后,脚本才输出 MATCH: <路径>。通用脚本把文件发现与进度信息送到 stderrMATCH: 记录和收尾状态摘要仍在 stdout。通用脚本会丢弃 find 错误;不可读或单字节读取/超时失败会静默返回;头部、字符串或十六进制工具失败也可能与真实不匹配走同一返回路径。只要 foundHits 仍为 false,它就输出最终“未发现签名”消息,因此这不是经核验的完成状态。ESXi 脚本同样把周期进度送到 stderr,启动、目标与完成消息则留在 stdout。操作人员应同时保存两条流,并用 MATCH: 前缀明确识别命中。

源码提出的问题回答“是”能说明什么还不能说明什么
可读文件是否为 ELF 候选?文件格式可以继续接受这条规则检查。它是否恶意、是否属于 BRICKSTORM。
必需字符串是否全部存在?候选包含规则要求的完整字符串集合和允许编码。部分重合或普通库字符串是否具有恶意含义。
字节序列是否匹配?文件满足这条 YARA 规则的 shell 复现条件。谁部署了它、何时执行、后来到过哪些系统。
所有关口是否全部通过?扫描器得到一条值得保全和升级的文件线索。没有主机、时间、基础设施和访问记录时的行动归属。

5.2 ESXi 版本换掉了一些工具便利,却没有替调查人员省掉记录

后来的 find_brickstorm_esxi.sh 是为了解决 ESXi shell 与通用 Linux 的差异。那里没有同样的 Bash 环境和工具组合,所以脚本使用更克制的 sh 写法与设备可用命令。在本次固定提交中,它查找小于 50000k 的普通文件,只排除 EXCLUDE_DIRS 中配置的完整路径前缀;固定快照的默认值只是示例项 /root/excludeme。附近注释以 /proc/dev/sys 展示可选排除模式。若从 / 开始扫描,操作人员必须显式配置所需的伪文件系统排除。剩余候选随后被送入 ELF、完整字符串与字节模式三项关口。

没有 MATCH: 的一次运行,仅限于精确起始路径、当时的 EXCLUDE_DIRS<50000k 筛选,以及所有遍历、读取或必需工具失败。ESXi 路径没有通用脚本的一秒读取/超时关口;最终无条件输出的 Scan complete. 也不能证明每个发现路径都完成了全部检查。应原样记录起始路径、当时的排除项、脚本提交与哈希、主机和构建、文件系统或快照时间、失败情况、两条输出流和输出哈希。这样,“我们跑过扫描器”才变成另一个响应人员可以重复的工作。

若出现完整命中,应立即保全文件、开展静态分析、扩大主机排查,并寻找对应的执行、持久化、网络和凭据活动。在采集前不要把文件当场删除。时间戳可能伪造或被修改,仍值得与备份历史、包清单、启动脚本、账户变化和目的地首次出现时间比较。命中只是文件进入时间线的时刻,不是时间线结束的时刻。

5.3 没有 MATCH,故事便退回备份,再向行为记录展开

仓库 README 写得很直白:脚本找不全所有 BRICKSTORM 变体,不判断设备是否存在可利用漏洞,也不检查日志、进程和持久化;在线系统还可能已经被入侵者修改。这并不是一个专用扫描器做得不够,而是在告诉使用者接下来必须打开四条搜索线。

第一条回到受保护备份与快照,覆盖可疑时间段。利用设备标识和备份目录,挑选异常对外通信、账户创建、vCenter 访问或克隆事件前后的镜像。比较文件清单和哈希、启动路径、包清单、cron、服务定义、配置、SSH key、授权用户和异常可执行目录。Mandiant 观察到对手把持久化塞进 init.drc.localsystemd,有时直接用 sed 修改正常启动脚本。即便二进制没了,调用它的那一行仍可能留下。

第二条检查运行状态,但必须服从平台能力和响应方案。进程列表、开放套接字、映射的可执行文件、已删除却仍被进程打开的文件、加载模块、父子关系和内存采集,可能发现固定文件规则看不到的活动植入。BRICKSTEAL 已经证明,重要恶意状态可以只存在于内存。采集命令与工具也要被记录,因为任何检查都会在某种程度上改变被检查系统。

第三条看设备做过什么。管理接口建立异常互联网 TLS,设备主动 SSH 到 vCenter,它的地址出现在 Windows 网络登录里,一个本地账户在几分钟内创建又删除,一台敏感 VM 在工单之外被复制——不论恶意文件是否仍在,这些动作都很重要。它们需要和设备业务角色比较。一段脚本不知道存储控制器本来不该登录身份服务器,资产清单知道。

第四条核对暴露与配置,同时不要把它误写成恶意软件扫描。确认精确产品构建、厂商公告、管理接口可达性、认证配置、管理员账户、安装扩展、支持隧道与更新完整性。把所有合理入口及时修补,但在行为记录能够说明权限去过和没去过哪里之前,不要因为补丁成功就关闭事件。

走到这里,调查拥有许多证人,却没有一个全知视角。在线设备可能被改,备份也许相差一天;vCenter 知道有人提交任务,却不知道为什么;防火墙知道两个地址,却不知道凭据;Entra 知道一个应用会话,却不知道它的 secret 从哪里泄露。下一步是检验哪些残缺记录确实能够连接,同时不逼迫任何一条日志说出它没有看见的东西。

6 只用能够接上的证人,建立本地时间线

事件时间线常被画成一串按时间排序的记录。BRICKSTORM 真正困难的工作发生在排序之后:检验防火墙里的设备地址是否就是打开 VAMI 的来源,这段 VAMI 会话是否开启了供新建账户使用的 SSH,该 SSH 会话是否写入文件或改了启动项,以及本地材料能否把这组权限接到敏感虚拟机克隆或邮箱访问。公开报告把这些观察放在同一组行动里;只有本地连接键才能把它们放进同一条事件顺序。

先建一张一行只写一个动作的事件表,猜想另放一列。至少保留来源系统、设备报告的 UTC 时间、采集时间、操作人或账户、源和目标地址、会话或请求 ID、对象 ID、动作、结果、原始记录位置、采集人和时钟可信程度。再单独增加“如何相连”一列:同一 VAMI 会话、同一 vSphere 任务键、同一 VM moid、同一个 SSH 进程、同一 client ID 与 Session ID、同一文件哈希,或一条有记录的 NAT 转换。

可能的证据连接示意图,包括设备管理 IP、VAMI 会话、vCenter 主体、SSH 进程、vSphere 任务键、VM 对象 ID、datastore 文件和邮箱应用会话。
图 6。没有哪一份日志独占一项本地事件。只有每次被主张的交接都带着可核对的连接点——地址与转换、会话、主体、进程、任务键、对象 ID、datastore 路径、client ID 或邮箱会话——案件才站得住。

6.1 一个管理 IP,可能穿过四套彼此不认识的系统

回到资产盘点时出现的设备管理 IP。DNS 与防火墙里,它可能是异常外联的来源;VAMI 日志里,它可能请求了会话并开启 SSH;vCenter 或 ESXi 认证里,它可能带着一个本地或域账户出现;Windows Security 或 User Access Logging 中,它又可能成为一次已认证连接的源。这个地址之所以珍贵,是因为它能跨越不同产品,但前提是团队知道当时的地址归属和转换关系。

为每个地址保存静态或 DHCP 配置、NAT 规则、负载均衡、代理头、高可用集群归属、故障切换历史和时钟同步情况。高可用设备可能在节点间漂移地址,反向代理若未配置保留来源,也可能替换真实客户端。日志中的 IPv4 映射 IPv6 写法,例如 ::ffff:<地址>,还会让只做精确字符串匹配的检索漏掉同一个来源。检索时可以归一化,原始形式仍要保留。

然后判断来源行为是否符合设备职责。VPN 集中器为了验证登录,可能合理访问 LDAP,但未必有理由在 vCenter 上建立交互式 SSH;备份设备可能正常读取 datastore,但它使用的服务账户、计划、目标主机和克隆命名应与批准流程吻合。以角色为中心的复核可以减少噪声,却不会因为来源属于“基础设施网段”就给它永久通行证。

管理 IP 还可能暴露备用落脚点。若两台设备在不同时间联系同一批内部目标,共享一个解释不了的外部目的地,使用同一被盗账户,或者轮流成为 vCenter 管理来源,应把它们当作独立资产同时展开。Mandiant 描述过一个主要 BRICKSTORM 实例加多个备用设备的安排,来源变化可能意味着对手正在切换路线,并不一定是另一场无关事件。

6.2 克隆名字已经消失,vSphere 对象标识仍在继续说话

在 vSphere 中,使用最长可用 VPXD 记录搜索敏感虚拟机相关的克隆、快照、迁移、注册、注销、开关机、导出与销毁。Mandiant 提到对手经常在 01:00 至 10:00 UTC 之间活动,这个时段可以帮助排查排序,却不能把其他时间排除在外。每个候选操作都要与批准的备份、灾备、迁移、测试和管理员计划比较。

保存 vCenter 实例 UUID、datacenter、cluster、ESXi 主机标识、datastore 标识、VM moid、instance UUID、任务键、事件键、认证主体、会话、源对象、目标对象、目标文件夹、开机状态和结果。如果某条原始事件没有全部字段,可利用任务与事件链以及历史清单补齐。一个销毁事件若能通过同一任务或对象血缘接回早先克隆,比搜索名称里有没有“clone”可靠得多。

再去交叉检查涉及主机上的 hostdvpxa、datastore 浏览与存储审计、文件时间和大小、主机与存储之间的网络流量以及备份平台任务。公开的五条 VPXD 日志只告诉我们控制面认为复制已经完成;周边系统则能说明字节去了哪里、操作是否像组织平常的自动化。应在 vCenter 自己的保留和轮转清除这些材料前导出原始记录。

接着搜索任务四周的权限变化。Mandiant 还公开过另一段紧凑时间线:本地 Administrator 创建新 vCenter 用户,把它加入 AdministratorsSystemConfiguration.BashShellAdministrators,对手从一台失陷系统用该账户 SSH 登录,取得 root 会话,写入 BRICKSTORM,随后移出组并删除账户——全部发生在几分钟内。如果只查看现在的账户清单,这个人根本不存在。创建、授权、登录、提权、文件写入、撤权和删除必须作为独立事件保存。

读这条链时,可以把材料想成四位站在不同位置的目击者。vCenter 应用事件回答控制面接受了什么,例如 VmClonedEvent 记下克隆,HostSshEnabledEvent 记下 SSH 被打开;SSO 审计回答是谁获得或使用了权限,特别要看本地主体管理活动是否紧挨着一个短命账户;Linux auditd 回答权限怎样落到操作系统,execprivuseraddprivilegedperm_mod 这类规则键可以在进程经过 sudo 后仍保留最初的审计用户;放在 vCenter 之外的干净 AIDE 基线,则回答会话之后究竟多了或改了什么。四者任何一个都讲不完整,接起来才会从“Administrator 做过事”变成某个主体、某段会话、某个特权进程和某个被改对象。

/root/.bash_history 承担不了这样的证明责任。VCSA 上的 Bash 历史可能直到退出登录才写盘,操作者也可以关闭记录、清空文件或换一种不会进入历史的执行方式;常规远程日志配置还不会自动把这份文件变成异地副本。因此,有命令可以继续追,没有命令却不能反推“没有执行”。真正需要的是把内核审计和服务事件通过经过测试的 audisp 或 rsyslog 路径送到控制面之外,并验证本地缓存、队列积压、断线续传和远端落盘;只看配置文件里有没有一个服务器地址,远远不够。

最后一把接线针是时间,它坏起来往往没有声音。把 VCSA、ESXi、管理工作站、网络设备、身份服务、存储和采集器的 NTP 状态一并放入案件,原设备时间与采集时间都要保存。两分钟偏差足以让“创建账户”和“登录账户”的先后看起来颠倒;采集队列积压,又可能让调查启动后的事件看似早于触发它的入侵活动。可以在派生时间线上校正和解释,却不能改写原始事件的时间戳。否则后面每一个漂亮的箭头,都可能建立在被改过的地基上。

6.3 身份和邮箱记录,检验可疑权限究竟用在了哪里

基础设施记录说明能到哪里,身份记录说明权限如何被使用。对路径上每一个 vCenter、设备、秘密库、代码平台、Windows 和云账户,收集成功与失败认证、来源、目标、认证方式、MFA 结果、会话、令牌或应用 ID、角色变化、凭据变化和管理动作。哪些记录因为过期或从未采集而缺失,也应明确留在时间线上,不能无声地变成“没有活动”。

Windows User Access Logging 在某些服务器角色上,可能比普通事件日志保留更久的认证使用痕迹。Security、Terminal Services、EDR、文件服务器审计与 UAL 各自观察不同层面。来自设备地址的一条 UAL 记录不能证明具体执行了哪条命令,却可以把账户、来源、目标和角色放进同一个时间段。Shellbags 有时保留资源管理器浏览过的目录,包括 UNC 路径和凭据相关位置;解析结果应回到原始采集物和用户上下文中复核。

Microsoft 365 侧,先枚举能够广泛读取邮件的应用,再按 client ID 搜索审计数据。在租户审计和保留配置允许时,MailItemsAccessed 可以提供邮箱用户、客户端地址、客户端信息、Session ID 与访问类型。判断之前先按应用和会话分组,不要围绕单个 IP 下结论。商业 VPN 和失陷路由器出口可以变化;一段会话连续数日集中关注开发、管理员、法律事项或少数高管,往往比一个陌生地址更有说明力。

邮箱时间线最好从应用内部向外展开。先确认 service principal、当前与历史权限、所有者、凭据或证书变更,再按 Session ID、邮箱、访问类型和时间切分记录。一次同步型访问可能在少量事件里代表许多邮件,bind 型访问又会呈现另一种密度;只数日志行,会把一种会话夸大、把另一种会话藏掉。随后把 client ID 和会话接回令牌签发、consent、正常自动化来源、历史源地址与设备时间线。假如一台承载管理员秘密的虚拟机被克隆后,同一应用突然开始读取过去从未触碰的开发、法务和高管邮箱,即使每次认证都成功,这个时间关系也值得调查;只有本地账户、令牌、会话、来源或目标记录把两边接上时,它才成为一项关系。

同样的原则也适用于代码平台。不要只搜“大量下载”,而要先描述正常机器人一天会访问哪些仓库、从什么网络来、使用哪类令牌、是否伴随构建任务,再看异常会话改变了哪一项。一个真实账户从设备网段调用归档接口,先枚举组织,再连续下载互不相关的仓库,随后更换 deploy key;单个请求可能都合法,整段会话却可能异常。保存 HTTP 请求 ID、令牌标识、仓库、对象数、字节数、来源和对应工单,才能区分一次临时发布与一次有方向的收集。

公开报告里的邮件、源代码与 UNC 路径来自多起经过脱敏的调查,不应被揉成一个不存在的受害者故事。真正应该借用的是提问方式:被复制的系统可能保存了哪些权限,这些权限通向什么,目标系统又留下了哪些独立记录。本地证据能证明邮件访问,就写邮件;只能证明仓库令牌被使用,就停在仓库;尚未接上的一段就明确缺哪一把键。这样写出的时间线也许不够戏剧化,却不会为了填满凌晨 4 点到 5 点而凭空增加一个动作。

仍然在场的证人应当保留的字段它能回答的问题
设备与网络稳定资产 ID、管理 IP、地址转换、目的地、首次/最后出现、字节数、配置版本哪台被忽视的设备成了路线,它后来连到哪里?
VAMI、SSO、SSH来源、主体、会话、HTTP 请求、服务状态、进程 ID、PAM 与 sudo 会话有效权限如何变成管理设备上的 shell?
VPXD、ESXi、存储任务/事件键、VM 对象 ID、主机、datastore、开机状态、文件路径、大小、结果哪台机器被复制,磁盘去了哪里,副本是否启动?
身份、邮箱、代码账户、MFA、client ID、Session ID、邮箱或仓库、来源、动作、数据量本地证据能否把可疑权限接到某项下游活动;能接到哪一步?
备份设备 ID、快照时间、备份链、文件清单、配置、完整性与访问记录在线系统被清理或改写之前,哪些东西曾经存在?

时间线完成时,团队应该能用一句由原始记录托住的话描述每次已确认交接:这个设备地址打开了这段 VAMI 会话;这个主体开启 SSH;这个进程和账户写入文件;这项 vSphere 任务把这个对象复制到这个 datastore;这个应用会话读取了这些邮箱。无法证明的交接,应说明缺了什么,同时处置现有材料已经显示的可达风险。时间线不是为了写出文学意义上的全知真相,而是为了决定接下来该保全、隔离、轮换、重建和持续观察什么。

7 真正的驱逐,必须比这场入侵活得更久

走到这一步,响应团队会面对一个很不舒服的事实:清除对手所依赖的系统,正是信任已经受到质疑的系统。设备上的在线证据可能被修改,vCenter 进程里可能住着内存窃密组件,管理员密码可能早已泄露,备份链里既可能藏着最后一个干净版本,也可能藏着后门。贸然重装会毁掉时间线,慢慢调查又可能给对手留下继续转移的时间。

协调本身也要经过干净渠道和可信管理终端。若对手已经能看内部邮箱、工单或 vCenter,日常响应通信就可能提前暴露计划。无需因此制造神秘气氛,只需承认一个朴素原则:已经出现在事件路径上的系统,不能成为响应方案唯一的存放和沟通地点。

协同响应闭环让两条并行处置线汇合:一条保全证据,另一条收缩设备与管理访问;随后共同推进权限吊销与轮换、可信介质重建、遥测验证和备用落脚点搜索。
图 7。证据保全和访问收缩同时开始。只有重建系统、新凭据、管理限制、受保护日志和备用设备排查彼此一致,恢复才算真正通过验收。
  1. 先冻住正在消失的记录。在例行轮转继续改变现场前,导出易失状态、管理事件、身份日志、网络遥测,以及夹住首次异常活动的备份点。
  2. 在仍能观察时收窄路线。分步限制设备、vCenter、ESXi 和管理员路径,保存每次规则变化,并从被拒重试中寻找备用落脚点。
  3. 把响应移到干净路径。先准备确认可信的特权工作站与独立沟通方式,再让任何替换密码、密钥、证书或令牌进入环境。
  4. 按依赖顺序让旧权限失效。吊销会话,轮换设备与克隆磁盘能够触到的身份、应用授权、密码库秘密和高权限目录材料。
  5. 重建的是信任,不只是服务。从可信介质恢复,只带回逐项复核的配置,先建异地日志与受限管理,再接回业务依赖。
  6. 让新系统自己证明恢复完成。受控执行一次克隆、SSH 状态变化、邮箱会话和设备外联;每个动作都带着连接键进入受保护监控,验收才算结束。

7.1 一边保住正在消失的材料,一边关掉对手熟悉的路线

改变可疑设备之前,先用厂商支持或取证方案允许的方法,记录精确产品、构建、序列号或稳定身份、管理地址、运行时间、时钟、接口、路由、连接、进程、挂载、用户、密钥、服务、启动配置、包状态、文件元数据、日志和当前配置。平台能力、专业人员和业务风险允许时,再采集易失内存。上游 DNS、防火墙、代理、流量、认证与管理记录也应尽快导出,因为它们自己的保留窗口仍在继续转动。

相关备份要立即进入保护状态。保存快照时间、链关系、存储位置、完整性信息、访问记录以及谁能删除或过期它们;暂停例行轮转,避免覆盖异常外联首次出现、账户创建、vCenter 访问或虚拟机克隆前后的镜像。最关键材料应复制到使用独立凭据的案件存储。一份仍能被失陷设备改写的备份,还不能算可靠证人。

备份点要选成一段胶片,孤零零的一张“最后已知干净”照片不够。至少保留最早异常网络活动之前、每次关键身份或管理动作附近、五条克隆日志之后,以及响应人员首次采集时的状态。记录它们的父子链,确认 synthetic full、去重、压缩或后续合并是否改变过底层块;对导出的文件与清单计算哈希,保存恢复任务日志,并在隔离工作区实际挂载一份副本。如果历史镜像命中扫描器而在线设备没有,两份结果都要留下:差异可能说明样本被删,也可能只是构建变化、排除路径或采集不完整,不能让期待替代复核。

对 vCenter 与 ESXi,导出 VPXD、VAMI、SSO 审计、sshd、PAM、sudohostdvpxa、任务、事件、清单、角色、账户、扩展、证书和 datastore 记录。若 BRICKSTEAL 或其他内存组件存在可能,应在重启服务前保存进程和应用状态。同时记录当前 SSH 状态、lockdown mode、execInstalledOnly、日志转发、身份源、本地用户、组成员和所有拥有管理权限的主体。

访问收缩可以从小而可观察的变更开始。把设备管理地址限制到真正需要的内部目标和厂商目的地,阻断解释不了的设备到 vCenter、设备到 Windows 以及广泛横向管理;让 vCenter 与 ESXi 只能通过专用、受监控、强认证的路径管理;关闭管理面不必要的互联网访问。每次防火墙变更前后都要保留状态并观察被拒连接。原本畅通的 BRICKSTORM 路线突然被挡住时,对手的重试反而可能让备用实例暴露。

吊销可疑云端与管理会话、令牌、应用凭据、SSH key、支持隧道和临时本地账户。如果某个会话在采集前无法安全中断,就提高监控并缩短等待。不要让内存过滤器或失陷设备看到替换密码;把改密操作转移到已知干净路径,随后从正常来源和曾经可疑的来源同时验证旧会话、旧凭据确实失效。

7.2 轮换和重建的范围,由那台克隆机能够触到什么来决定

轮换表应从前面完成的关系图生长出来。先处理失陷设备与 vSphere 使用的账户,再覆盖所有经过可疑登录路径的管理员、对手访问过的脚本或密码库中保存的凭据、克隆磁盘上的秘密、身份系统持有的证书与密钥、能够广泛读取邮箱或仓库的应用凭据,以及从这些系统继续可达的服务账户。变更前先标出依赖和安全顺序,避免恢复过程制造停机,最后又被迫回滚到不可信备份。

高权限目录材料需要分阶段的域恢复流程,临场改几个密码解决不了。Kerberos 密钥、特权身份、服务账户、信任、证书服务、联合配置、应急账户和系统内嵌凭据必须协调处理;平台要求时,密钥变化后还要吊销令牌与会话。秘密管理系统既要轮换所保存的秘密,也要轮换保护和检索它们的密钥与账户。Entra 应用则需要移除解释不了的授权,更换 secret 或证书,复核所有者与 consent,并确认旧凭据不再产生审计活动。

这批操作应从已知干净的特权访问工作站发起,走一条没有经过可疑设备、浏览器插件、支持隧道或跳板机的管理路径。平台允许时,让 PAM 注入短寿命凭据,管理员不在可能仍带有 BRICKSTEAL 的登录页面或 shell 里键入新秘密。日常 vSphere 身份与应急 vsphere.local 超级用户分开,BashShellAdministrators 成员尽量少;每次打开应急通道都要有另一套系统留下原因、批准人、开始和结束时间。轮换前若还无法说明密码库、工作站、浏览器和 vCenter 登录路径是否可信,就先解决这件事,否则改密会变成给对手递交一份更新后的钥匙串。

那台从未开机的克隆机,也改变了 Tier 0 虚拟机的保护方式。磁盘加密能降低 datastore 副本直接暴露内容的可能,但只有在密钥管理权与虚拟化管理权相互独立、恢复流程确实演练过时才有意义;否则拿下 vCenter 的人也许同时能要到解密钥匙。架构支持时对 vMotion 使用加密,把 Clone、Export、snapshot 和 datastore browse 从不需要它们的日常角色里拿掉。确有业务需要的操作,通过实名工单、窄时间窗、指定对象与事后复核临时开放。这样并不能让合法管理员天然可信,却能让普通管理凭据不再顺手复制整台身份系统。

失陷设备和管理服务器应从可验证的厂商介质重建,或恢复到能够证明完整性的状态。只删掉命中文件,仍然没有回答启动项修改、WebShell、内存植入、本地账户、SSH key、被改软件包和备用落脚点。重建时验证固件或镜像来源,应用当前修复,只恢复逐项审查过的配置,再与批准基线比较。如果厂商架构根本不支持有效取证或可信重建,就把限制写入记录,用分段、替换和更多外部遥测补偿。

系统重新上线的顺序要避免刚换的凭据再次被抓。先建立受限管理网络和集中日志,再引入干净身份与 MFA,恢复经过复核的配置,开启文件与配置监控,验证对外访问,最后才重新连接必需内部服务。普通管理操作恢复后,继续盯住旧管理 IP、旧目的地、账户名、client ID 和 vSphere 对象,观察是否有人尝试复用。

还要主动寻找 Mandiant 案例提示的备用落脚点。重新扫描同类设备和历史镜像,检查共享凭据或管理网段的系统,寻找交替出现的外联和管理来源。把 vCenter、ESXi、身份、秘密库、邮箱、代码以及法律或高管目标的时间线一直拉到首次已知失陷之后,尤其覆盖响应开始之后。报告中那次“响应启动后才部署到内部 vCenter”的事件说明,调查期间出现的新东西可能是对手的反应,并不意味着早先时间线写错。

8 下一次凌晨 3:37,不该再这样安静

开头的五条 VPXD 日志其实从未沉默。vCenter 记下了操作人、任务、源、目标、复制完成、销毁和移除。真正的安静发生在组织内部:单条事件看起来太像日常运维,客户机里没有终端告警,克隆很快从清单消失,周围系统又没有共享同一个调查标识和同一段记忆长度。

这也是 BRICKSTORM 故事里最值得利用的地方。后门选择终端防护看不到的位置,却仍然依赖组织可以掌控的关系。整组公开案例分别出现了设备外联、有效凭据进入管理控制台、SSH 状态变化、角色授予、文件写入、虚拟磁盘移动和应用读取邮箱;报告没有把它们证明为同一受害者的一条顺序。本地调查中,每项动作单看都可能普通,只有共同的资产、主体、会话、来源、对象 ID、时间与工单,才能把其中一些观察连接成有证据支撑的链。

8.1 把这次调查变成每天都能实际验证的控制

第一件事仍然是所有权。每台设备和管理平台都要有技术负责人、安全负责人、精确构建、生命周期状态、管理地址、所需对外和内部路线、凭据存储、备份位置、日志目的地与复核日期。新设备和试用设备在获得生产连接前先进入清单。无法安装代理的系统必须获得明确的外部观察,不能从终端数量里消失。

管理流量要窄,也要能解释。面向互联网的设备不应同时拥有不受限制的内部访问,管理接口不能因为位于基础设施网段就主动连接任何目标。vCenter 和 ESXi 只通过专用、强认证路径管理;平台支持时使用抗钓鱼 MFA,按业务采用合适的 vSphere lockdown 控制和 execInstalledOnly,限制 SSH,把日志转发到管理平台之外的存储。

对权限变化和敏感动作建立关联告警,同时附上业务上下文。一个本地用户在几分钟内被创建、加入 Bash shell 管理组、用于 SSH、随后删除,应该形成同一个案件;敏感 VM 被克隆、从未开机、又在没有工单的情况下移除,也应如此。能够广泛读信的企业应用需要负责人、预期来源、凭据到期时间和邮箱用途;设备管理 IP 第一次访问一个外部目的地,需要厂商或业务解释。

演练应测试证据是否接得起来,而不只是告警有没有响。在受控环境中,通过批准流程克隆一台非敏感 VM,验证 VPXD、主机、存储、身份和变更记录能否用任务与对象标识相连;切换测试管理设备的 SSH,确认来源、操作人、会话、状态变化和后续连接都被保存;让测试应用访问测试邮箱,确认 client ID、会话、来源和邮箱动作可检索;恢复一份设备备份,按固定提交重复扫描并保存路径与输出哈希。

把日志本身当作 Tier 0 系统来管理。维护 vCenter 的同一组人不应是唯一能修改其证据的人,同一份凭据也不应同时控制平台、采集器和归档删除。除了事件内容,还要持续记录每个来源最后收到时间、预期量级、解析失败、时钟漂移、队列深度、磁盘与保留消耗。每次升级、证书更换和采集规则变更后都做一笔小型端到端测试。管理面突然“很安静”只有在采集健康仍然有心跳时才值得放心。

8.2 保留足够长的记忆,才认得出对手第二次回来

长期保留不等于把所有原始日志永远堆在最贵的存储里。前几十天保留足以重放的高粒度记录,之后留下按日压缩、但仍能指回原始时间段的索引:某台设备联系过哪些目的地,哪个主体得到过角色,哪些敏感 VM 出现克隆或导出任务,哪个 client ID 读过哪些邮箱类别,哪个备份点包含哪些文件路径与哈希。索引、原始归档和备份之间定期抽样恢复;只有“搜得到摘要、取得到原文、验得过完整性”三件事同时成立,393 天后的分析人员才不会再面对一排已经失效的链接。

这些历史不应只在告警后使用。固件升级、vCenter 迁移、身份架构调整、新 SaaS 集成或厂商支持都可能引入新地址和凭据;把获批变化记录下来,未来出现的新东西才有可比较的解释。事件结束后,继续观察旧路线、账户、目的地、证书、client ID 和管理对象,覆盖足以抓住延迟回连或备用植入的时间。

最后,让每一个暂时回答不了的问题都拥有负责人。入口日志过期,就写明缺失时段以及覆盖可能路径的控制;设备无法成像,就列出由哪些外部材料补偿;克隆秘密系统导致部分凭据无法逐项枚举,就记录采取的恢复假设和分阶段轮换。一个无声的空格会慢慢变成放心的理由,一个被点名的问题才有机会在下一次之前缩小。

凌晨 3:37,公开案例中的对手利用了一个简单的不对称:vCenter 看得见克隆,而只盯着客户机的防守方看不见。解决办法不是等待一条更戏剧化的告警,而是让管理平台、网络设备、身份系统、存储层和云审计各自保留事件,时间长到足以识别由证据支持的连接。这样,04:05 消失的克隆机就再也带不走整个故事。

研究记录

9证据、对象与来源

下面保留本文实际使用的标识、时间和原始材料,便于继续调查。

9.1可检索观测值

来自引用材料或本次调查的值,并附有使用这些值所需的上下文。

类型说明操作
SHA-25690b760ed1d0dcb3ef0f2b6d6195c9d852bcb65eca293578982a8c4b64f51b035公开 BRICKSTORM 样本 pg_update
SHA-2562388ed7aee0b6b392778e8f9e98871c06499f476c9e7eae6ca0916f827fe65df公开 BRICKSTORM 样本 spclisten
SHA-256aa688682d44f0c6b0ed7f30b981a609100107f2d414a3a6e5808671b112d1878公开 BRICKSTORM 样本 vmp

9.2研究对象

报告涉及的产品、行为者、技术、受影响对象和控制点。

恶意软件BRICKSTORM

GTIG 报告的 Go 后门,带 SOCKS 代理能力

恶意软件BRICKSTEAL

在 vCenter Web 登录路径上观察到的内存 Java Servlet 过滤器

恶意软件SLAYSTYLE / BEEFLUSH

报告中部署于 vCenter 的 JSP WebShell

狩猎路径/web/saml2/sso/*

BRICKSTEAL 观察的 vCenter Web 登录路径

狩猎路径/rest/com/vmware/cis/session

公开 VAMI 访问序列中的会话端点

狩猎路径/rest/appliance/access/ssh

公开 VAMI 访问序列中的 SSH 状态端点

狩猎事件VirtualMachine.clone

复核敏感 VM 克隆任务及对象关系

狩猎事件VirtualMachine.destroy

把短命克隆销毁事件接回创建任务

云权限Mail.Read

复核拥有广泛邮箱访问的 Entra 应用

云权限full_access_as_app

复核拥有应用级邮箱访问的 Exchange 应用

9.3事件时间

  1. 克隆任务开始

    公开 VPXD 记录显示本地 vSphere Administrator 发起 VirtualMachine.clone。

  2. DC01 开始被复制

    记录写出源 DC01 与位于另一台 ESXi 上的目标 DC01-clone。

  3. 克隆完成

    vCenter 记录 DC01 已复制为 DC01-clone。

  4. 销毁任务开始

    本地 vSphere Administrator 请求销毁临时克隆。

  5. 克隆对象被移除

    VPXD 记录 DC01-Clone 从清单中移除。

  6. 上游首次加入 Bash 扫描器

    提交 68e66ae 向公开仓库加入 find_brickstorm.sh。

  7. 跨案例报告发布

    GTIG 与 Mandiant 发布 BRICKSTORM 活动周期、狩猎建议与 YARA 规则。

  8. SOSEC 首次复核快照增加 Photon OS 兼容

    SOSEC 早期源码复核使用的 03103ea,是较晚的 Photon OS xxd 兼容修订,并非上游起点。

  9. 增加 ESXi 扫描路径

    公开仓库增加适配 ESXi 环境的独立 shell 脚本。

  10. 调整扫描排除逻辑

    公开仓库更新路径排除;本次复核固定在 fb2129c。

  11. 当前扫描器与恢复测试完成对照

    SOSEC 固定当前扫描器,将跨平台发现接入调查路径,并给出可复现的恢复测试。

9.4来源与材料

  1. GTIG 与 Mandiant:Another BRICKSTORMhttps://cloud.google.com/blog/topics/threat-intelligence/brickstorm-espionage-campaign
  2. Mandiant 扫描器:首次加入 find_brickstorm.sh 的 68e66aehttps://github.com/mandiant/brickstorm-scanner/commit/68e66ae3c1ee2d7c3775b430c2aa9d2c814d1f37
  3. Mandiant 扫描器:Photon OS xxd 兼容提交 03103eahttps://github.com/mandiant/brickstorm-scanner/commit/03103ea6b651827407336e1e8529ba5f6094b7f8
  4. Mandiant BRICKSTORM 扫描器:固定提交 fb2129chttps://github.com/mandiant/brickstorm-scanner/tree/fb2129cecd9561332608fbaac05884217c793a17
  5. 扫描器 README 与已知限制https://github.com/mandiant/brickstorm-scanner/blob/fb2129cecd9561332608fbaac05884217c793a17/README.md
  6. 通用扫描器 check_file 实现https://github.com/mandiant/brickstorm-scanner/blob/fb2129cecd9561332608fbaac05884217c793a17/find_brickstorm.sh#L122
  7. 面向 ESXi 的扫描器实现https://github.com/mandiant/brickstorm-scanner/blob/fb2129cecd9561332608fbaac05884217c793a17/find_brickstorm_esxi.sh#L39
  8. Mandiant:Ivanti 入侵后的横向移动https://cloud.google.com/blog/topics/threat-intelligence/ivanti-post-exploitation-lateral-movement
  9. GTIG:中国背景活动利用 Ivanti 严重漏洞https://cloud.google.com/blog/topics/threat-intelligence/china-nexus-exploiting-critical-ivanti-vulnerability
  10. Mandiant:vSphere 与 BRICKSTORM 防守指南https://cloud.google.com/blog/topics/threat-intelligence/vsphere-brickstorm-defender-guide
  11. Mandiant:vSphere 防御与加固建议https://cloud.google.com/blog/topics/threat-intelligence/defending-vsphere-from-unc3944
  12. Microsoft:Windows User Access Logging 入门https://learn.microsoft.com/en-us/windows-server/administration/user-access-logging/get-started-with-user-access-logging
  13. Microsoft Purview:使用审计日志调查失陷账户https://learn.microsoft.com/en-us/purview/audit-log-investigate-accounts
  14. Microsoft Purview:MailItemsAccessed 审计https://learn.microsoft.com/en-us/purview/audit-log-investigate-accounts#the-mailitemsaccessed-mailbox-auditing-action
  15. Microsoft Security:防御失陷凭据https://techcommunity.microsoft.com/blog/microsoft-security-blog/defending-against-compromised-credentials/125678
  16. MITRE ATT&CK:BRICKSTORMhttps://attack.mitre.org/software/S9015/
  17. MITRE ATT&CK:NTDS 凭据材料https://attack.mitre.org/techniques/T1003/003/
  18. Broadcom:vCenter Server 日志位置https://knowledge.broadcom.com/external/article/312194/location-of-vcenter-server-log-files.html
  19. Broadcom:在 ESXi 上配置 syslog(文章 318939)https://knowledge.broadcom.com/external/article/318939/configuring-syslog-on-esxi.html
  20. VMware vSphere Security:lockdown modehttps://docs.vmware.com/en/VMware-vSphere/8.0/vsphere-security/GUID-94F0C54F-05F2-42F7-85AE-0D3C4E4B69C7.html