HOME

【vCenter】VCSA 6.0 suidcheck 安全告警排查:原厂基线巡检为何被识别为提权侦察

文章目录14 节

一、先说结论

一台 VCSA 6.0.0.20000 触发了安全告警:系统以 root 身份运行 /usr/bin/find / -perm -4000,行为被识别为本地提权前的 SUID 枚举。

我后来部署了同版本 VMware-VCSA-all-6.0.0-3634788 环境,对脚本内容、RPM 来源、文件哈希、定时任务调用链和实际输出进行了核对。最终确认:

本次告警是 VMware 原厂 vasecurity 安全加固组件部署的每周安全基线检查触发的行为误报。suidcheck 只枚举并记录已有的 SUID 文件,不会给文件添加 SUID 权限,不会修改或执行找到的文件,也不会直接实施提权。

不过,“这一次是正常巡检”不等于所有 find / -perm -4000 都可以放行。攻击者确实会用相同命令寻找本地提权入口,安全平台识别出的行为特征没有错;真正决定性质的是父进程、脚本路径、内容与哈希、执行时间和软件包来源。

本文保留实际版本、命令、输出特征和哈希,公开内容中的地址、资产名称和连接标识均已脱敏。

二、事件流程

整个事件可以概括为:

flowchart LR
    A["VMware 原厂 vasecurity<br/>虚拟设备安全加固组件"] --> B["部署每周安全检查脚本"]
    B --> C["/etc/cron.weekly/suidcheck"]
    D["/etc/crontab"] --> E["/usr/lib/cron/run-crons"]
    E -->|"每周以 root 身份调用"| C
    C --> F["/usr/bin/find / -perm -4000"]
    F --> G["枚举系统中的 SUID 文件"]
    G --> H["写入 /var/log/suidlist/"]
    F -. "命令也常用于提权前侦察" .-> I["安全平台行为告警"]

这条链路中要区分三个角色:

角色对应组件作用
安装来源vasecurity RPM提供并应用 VMware 虚拟设备安全加固规则
调度来源/etc/crontab/usr/lib/cron/run-crons判断周任务是否到期,并以 root 身份调用脚本
检查工具/etc/cron.weekly/suidcheck/usr/bin/find枚举 SUID 文件并把结果写入本地日志

vasecurity 并不是每周直接启动 find 的常驻服务。它主要在设备部署或加固阶段生成最终脚本;之后的周期执行由系统 cron 机制负责。

三、复现环境与证据边界

我用于核对的环境如下:

项目实测值
部署介质VMware-VCSA-all-6.0.0-3634788
VCSA 版本6.0.0.20000
Appliance 内部 BUILDNUMBER3634791
分支vsphere60u2
操作系统SUSE Linux Enterprise Server 11 SP3
内核3.0.101-0.47.71-default
加固包vasecurity-6.0.0.0-3588047

OVA 文件名中的 build 3634788、Appliance 内部 build 3634791 和部分组件 build 不完全相同。它们分别属于发布介质、Appliance 和组件构建编号,不能因为数字略有差异就直接判断介质被修改。

这次已经验证:

  • 四个 /etc/cron.weekly/ 脚本在全新同版本 VCSA 中真实存在。
  • 脚本的属主、权限、修改时间、内容和 SHA-256 已记录。
  • vasecurity 的 VMware 厂商元数据及加固源脚本的 RPM 归属可以对应。
  • /etc/crontab → run-crons → cron.weekly 调度关系可以对应。
  • 首次满足周任务条件后,四个日志目录均生成了带时间戳的结果。
  • 告警中 /usr/bin/find 的 SHA-256 与全新环境原厂文件一致。

这次没有验证业务 VCSA 上所有历史时期的脚本是否从未被改动。判断某一台业务主机时,仍应现场计算哈希并与可信基线比较,不能只凭文件名相同就认定安全。

四、四个脚本分别做什么

同版本环境中的四个脚本都是 root:root、权限 0700,修改时间为 2016-02-24。它们只负责检查和记录,不负责自动修复。

脚本实际检查输出目录作用
devcheck枚举块设备和字符设备节点/var/log/devicelist/建立设备节点基线,发现异常新增节点
rpmcheck校验已安装 RPM 文件/var/log/rpmcheck/发现文件缺失、摘要、权限、属主等变化
sgidcheck枚举设置 SGID 位的文件/var/log/sgidlist/建立组权限程序基线,辅助识别异常 SGID 文件
suidcheck枚举设置 SUID 位的文件/var/log/suidlist/建立高权限程序基线,辅助识别异常 SUID 文件

下面是全新环境中读取到的原始脚本内容。这里是证据摘录,不建议为了验证而手工执行这些全盘扫描命令

devcheck

/usr/bin/find / -type b -o -type c > /var/log/devicelist/device_list.$(date +%m%d%Y-%H%M%S)

rpmcheck

rpm -qVa | awk '$2!="c" {print $0}' > /var/log/rpmcheck/rpmcheck.$(date +%m%d%Y-%H%M%S)

sgidcheck

/usr/bin/find / -perm -2000 2>/dev/null > /var/log/sgidlist/sgid_list.$(date +%m%d%Y-%H%M%S)

suidcheck

/usr/bin/find / -perm -4000 2>/dev/null > /var/log/suidlist/suid_list.$(date +%m%d%Y-%H%M%S)

其中 rpmcheck 使用 rpm -qVa 将当前文件状态与 RPM 数据库记录比较,再排除标记为配置文件 c 的项目。它输出差异并不等于系统一定被入侵:补丁、正常配置、初始化和 VMware 加固过程本身都可能造成差异。

五、为什么 suidcheck 会触发告警

suidcheck 的核心行为是:

/usr/bin/find / -perm -4000

参数含义如下:

参数含义
/从根目录开始搜索
-perm -4000匹配已设置 SUID 权限位的文件
2>/dev/null丢弃扫描过程中的标准错误
> /var/log/suidlist/...将标准输出写入带时间戳的结果文件

SUID 可执行文件运行时可能获得文件所有者的有效身份。如果文件所有者是 root,这类程序就属于本地提权排查的重点。攻击者进入 Linux 主机后,经常先枚举 SUID 文件,寻找错误配置或存在漏洞的高权限程序。

因此安全平台看到下面的特征时触发告警是合理的:

用户身份:root
程序:/usr/bin/find
参数:/ -perm -4000
扫描范围:整个根文件系统

但这只能证明“发生了 SUID 枚举”,不能单独证明“发生了提权”。本次现场的关键区别是:命令由正常的 run-crons 周任务链启动,脚本与二进制哈希能够对应原厂基线,结果写入固定的安全检查目录,并且没有修改权限、执行 SUID 程序或建立网络连接。

六、怎样确认脚本来自 VMware 原厂

1. 查看 vasecurity 的 RPM 元数据

风险等级:INFO(只读)

作用: 在 VCSA Bash Shell 中查询已安装 vasecurity 软件包的名称、版本、厂商、构建时间和描述。 执行位置: VCSA;需要能够进入 Bash Shell。该命令只读取本机 RPM 数据库,不修改系统。 完成判断: 输出应显示本机实际安装的包版本和 Vendor: VMware, Inc.。不同 VCSA 补丁版本的 Release 可能不同,应以现场结果为准。

rpm -qi vasecurity

本次同版本环境的实际输出为:

Name        : vasecurity
Version     : 6.0.0.0
Release     : 3588047
Vendor      : VMware, Inc.
Build Date  : 2016-02-24
Summary     : VA Secutiry Hardening scripts for VMware
Description : Virtual Appliance Security Hardening for VMware.

Secutiry 是包内 Summary 原文的拼写,不是本文录入错误。

2. 查询加固源脚本的 RPM 归属

只看到 Vendor: VMware, Inc. 还不足以证明任意同名脚本都来自原厂。下一步需要把 vasecurity 包登记的加固源脚本与最终周期脚本对应起来。

风险等级:INFO(只读)

作用: 通过 RPM 数据库确认四个安全加固源路径属于哪个软件包。 执行位置: VCSA Bash Shell。即使安装后的加固流程已经移除源文件,RPM 数据库仍可能保留这些路径的归属记录。 完成判断: 四条查询均应返回现场安装的 vasecurity 包;如果返回归属不同或数据库错误,需要停止套用本文结论并继续调查。

rpm -qf /vasecurity/va_hardening/patches/government/GEN002260-device-list.sh
rpm -qf /vasecurity/va_hardening/patches/government/GEN002400-weekly-setuid-check.sh
rpm -qf /vasecurity/va_hardening/patches/government/GEN002460-all-suid-binaries-weekly.sh
rpm -qf /vasecurity/va_hardening/patches/government/GEN006565-audit-packages.sh

本次四条查询都对应:

vasecurity-6.0.0.0-3588047

对应关系为:

最终脚本vasecurity 包中的加固源路径
/etc/cron.weekly/devcheckGEN002260-device-list.sh
/etc/cron.weekly/sgidcheckGEN002400-weekly-setuid-check.sh
/etc/cron.weekly/suidcheckGEN002460-all-suid-binaries-weekly.sh
/etc/cron.weekly/rpmcheckGEN006565-audit-packages.sh

这里有一个容易误判的细节:

rpm -qf /etc/cron.weekly/suidcheck

可能返回“文件不属于任何软件包”。原因是 /etc/cron.weekly/suidcheck 是加固过程生成或部署的最终文件,不一定作为普通文件直接登记在 RPM 清单中;RPM 登记的是用于应用加固规则的源路径。因此不能只用最终文件的 rpm -qf 结果下结论。

另外,安装完成后 /vasecurity 下的部分源文件可能已经不存在,导致 rpm -V vasecurity 报告多个 missing。我在全新 Appliance 中也观察到了这种情况,它属于加固脚本应用后的安装状态,不能单凭这些 missing 判断系统遭到删除或入侵。

3. 核对最终脚本和 find 哈希

RPM 来源证明了生成链,文件哈希则用于判断业务主机上的当前文件是否仍与可信基线一致。

风险等级:INFO(只读)

作用: 计算四个周期脚本和 /usr/bin/find 的 SHA-256,供同版本基线比对。 执行位置: 待排查的 VCSA Bash Shell;读取系统文件通常需要 root。 注意事项: 只有版本、补丁级别和文件内容相同的主机才应直接比较本节基线。哈希不一致不等于一定恶意,但必须继续检查文件内容、RPM 校验结果和变更来源。

sha256sum \
  /etc/cron.weekly/devcheck \
  /etc/cron.weekly/rpmcheck \
  /etc/cron.weekly/sgidcheck \
  /etc/cron.weekly/suidcheck \
  /usr/bin/find

本次 VMware-VCSA-all-6.0.0-3634788 全新环境基线为:

文件SHA-256
devcheckd2f1c2b745e1f502df708d98bb02944ae2e4392af1579a2bbb3a8ef58564016a
rpmcheck5523812c1cf607e7a61580899adfa6a8dc9bb1d77fe0f15bf45b4074d7f75816
sgidchecka524298be8187b383ad957b3c79c88509d02aaff04d0e68cb87418e294144464
suidcheckd474c0491237745e356990927870d5ff4d6a1d2e24db93aefd3f7ae22d8573e0
/usr/bin/find8997b68e8900bb4ad2e73c479428b4b0d9e6e6247bd500c07b7732f8885e8058

/usr/bin/find 属于 findutils-4.4.0-38.26.1。本次告警记录中的 find 哈希与全新环境相同,这是确认告警二进制为原厂文件的重要证据。

七、脚本实际怎样被执行

/etc/crontab 每 15 分钟调用一次:

test -x /usr/lib/cron/run-crons && /usr/lib/cron/run-crons >/dev/null 2>&1

run-crons 并不是每 15 分钟执行一遍所有周任务,而是检查 /var/spool/cron/lastrun/cron.weekly 标记。标记不存在或距离上一次执行超过 10080 分钟时,才顺序执行 /etc/cron.weekly/ 下的脚本,并通过 nice -n 15 降低调度优先级。

所以“安装完 VCSA 就会立即跑一遍”并不准确。更严谨的说法是:

新部署 VCSA 在首次满足 cron.weekly 条件时通常会运行一次周任务。如果最后执行标记不存在或已经到期,下一次周期检查会触发执行;它不是由安装程序在完成按钮按下后直接同步执行。

直接观察 ps 也不是最可靠的验证方式。suidcheck 在本次环境中大约 2 秒就结束,很容易错过;而且 2>/dev/null 和输出文件重定向由 Shell 处理,通常不会完整出现在 find 进程自身的参数中。

更可靠的验证方法是同时查看脚本内容、周任务标记和输出文件时间。

风险等级:INFO(只读)

作用: 查看 suidcheck 的实际内容、周任务最后执行标记以及已经生成的 SUID 清单。 执行位置: VCSA Bash Shell;读取这些系统路径可能需要 root。 注意事项: 命令只读取现有文件,不会主动再次运行全盘扫描。日志可能暴露系统程序路径,对外分享前应检查并脱敏。 完成判断: 将安全告警时间、cron.weekly 标记时间和 suid_list.<时间戳> 文件时间进行对应。

sed -n '1,20p' /etc/cron.weekly/suidcheck
stat /var/spool/cron/lastrun/cron.weekly
ls -lht /var/log/suidlist/

如果只看到 /var/log/suidlist/ 下存在历史文件,只能证明脚本曾经运行过。要判断某条具体告警是否由正常周任务触发,还应对应:

  • 安全平台的告警时间;
  • 告警记录中的父进程和完整参数;
  • cron.weekly 标记的修改时间;
  • suid_list.<时间戳> 文件名和文件修改时间;
  • 脚本及 /usr/bin/find 的 SHA-256。

八、首次周任务的实际开销

我在全新环境中观察到四个脚本首次执行的结果如下:

脚本大约耗时输出规模
devcheck16 秒271 行,约 3.7 KB
rpmcheck32 秒1924 行,约 145 KB
sgidcheck2 秒5 行
suidcheck2 秒21 行
合计约 53 秒约 160 KB

suidcheck 找到的 21 个路径中包含 sudopasswdmountpingsu 等正常系统程序;sgidcheck 找到 5 个路径。清单里出现高权限程序并不等于这些程序恶意,真正需要关注的是相对可信基线新增、内容被替换或权限异常的项目。

这四个脚本存在两个运行层面的注意点:

  1. 多个 find 都从 / 开始,且没有使用 -xdev,可能进入其他已挂载文件系统并产生短时间磁盘读取。
  2. /var/log/devicelistrpmchecksgidlistsuidlist 使用带时间戳的新文件。我没有在该版本中找到这些目录的专用 logrotate 规则,长期运行可能造成日志缓慢累积。

这些属于性能和日志管理风险,不是恶意代码或直接提权风险。

九、风险判断

风险项判断依据
脚本恶意性低,未发现恶意证据VMware 加固包来源、同版本基线、正常 cron 调用链均可对应
直接提权只枚举 SUID/SGID 文件,不修改权限,不执行找到的程序
系统文件篡改四个脚本只把结果重定向到各自日志目录
网络行为脚本没有网络连接命令
脚本篡改面较低文件为 root:root、权限 0700,但仍应通过哈希验证当前内容
CPU、I/O 影响中等全盘 findrpm -qVa 会读取大量目录和软件包文件
日志累积低到中等带时间戳结果持续新增,未发现专用轮转规则
平台生命周期VCSA/vSphere 6.0 已属于老旧版本,脚本正常不能代表整个平台仍具备充分安全维护

因此不建议写成“这个脚本完全没有任何风险”。更准确的结论是:

未发现恶意行为和直接提权风险;脚本属于 VMware 原厂周期安全审计,但存在全盘读取产生的短时 I/O、跨挂载点扫描和日志累积风险。VCSA 6.0 本身的版本生命周期风险需要单独评估。

十、安全平台怎样设置例外才不会放得太宽

不能仅按照下面这个命令特征做全局白名单:

find / -perm -4000

攻击者也会执行完全相同的枚举。更稳妥的例外条件应同时限定:

父进程:/usr/lib/cron/run-crons
脚本路径:/etc/cron.weekly/suidcheck
脚本 SHA-256:d474c0491237745e356990927870d5ff4d6a1d2e24db93aefd3f7ae22d8573e0
子进程:/usr/bin/find
参数:/ -perm -4000
find SHA-256:8997b68e8900bb4ad2e73c479428b4b0d9e6e6247bd500c07b7732f8885e8058
执行时间:与 cron.weekly 标记及 suid_list 文件时间相符

如果出现以下任一情况,就不应直接套用例外:

  • 父进程不是 run-crons 或正常 Shell 调用链;
  • 脚本路径、内容、属主或权限发生变化;
  • 脚本或 /usr/bin/find 哈希与当前可信版本不一致;
  • 输出被发送到临时目录、网络位置或异常进程;
  • 命令后续继续执行发现的 SUID 程序;
  • 同一行为在非周任务时间大量重复出现。

十一、最终结论

这次排查最容易犯的错误有两个:一是看到 find / -perm -4000 就直接认定攻击;二是看到 Vendor: VMware, Inc. 就直接认定安全。

真正完整的判断依据应该是:

flowchart TD
    A["告警行为<br/>find 枚举 SUID"] --> B["核对父进程与执行时间"]
    B --> C["读取最终脚本内容与权限"]
    C --> D["查询 vasecurity RPM 元数据"]
    D --> E["确认加固源脚本的 RPM 归属"]
    E --> F["与同版本全新环境比较 SHA-256"]
    F --> G["对应 cron.weekly 标记和输出文件"]
    G --> H["确认原厂周巡检触发的行为误报"]

综合同版本环境实测,本次 suidcheck 告警属于 VMware VCSA 6.0 正常的每周安全基线巡检。脚本的任务是发现并记录 SUID 文件,而不是设置 SUID 或进行提权。安全平台命中了真实存在的双用途行为,但在这条确定的原厂调度链中,行为目的属于安全审计。

处置时可以针对完整执行上下文建立窄范围例外,同时继续保留对其他来源 find / -perm -4000 的检测。这样既能消除原厂巡检产生的重复误报,也不会把攻击者常用的提权侦察命令整体放行。

VMware vCenter VCSA Linux SUID 安全告警 故障排查