参考链接(官方文档):
- https://github.com/Cacti/cacti/security/advisories/GHSA-6p93-p743-35gf
- Cacti命令执行(CVE-2022-46169)漏洞分析
前言
RCE介绍:CE漏洞是安全领域中最危险的高危漏洞之一,攻击者能够通过漏洞在目标系统上远程执行任意代码,从而完全控制服务器或应用程序。
核心问题是应用程序未对用户输入进行严格过滤,导致攻击者注入恶意代码并让服务器执行。
典型场景:
1.用户输入直接拼接到系统命令(如os.command(input)
)。
2.反序列化不可信数据(如Java的readObject()
)。
3.文件上传未校验内容(如上传含恶意代码的PHP文件)。
然后上课讲了一个cacti的案例,这里最大的难题还是一些函数比较陌生,还有环境难搞。
一、漏洞简介
Cacti 是一款开源的网络监控与绘图工具,被广泛用于企业的基础设施监控中。2022 年末,研究人员披露了一个影响 Cacti 1.2.22 及以下版本的未授权远程命令执行漏洞(CVE-2022-46169)。
攻击者可在未授权的情况下,通过构造特定请求调用 Cacti 的 remote_agent.php 文件,从而远程执行任意系统命令。该漏洞的利用依赖于特定配置:启用了 SNMP 功能并存在至少一个线性数据模板。
二、影响范围
- 影响版本:Cacti 1.2.17 - 1.2.22
- 漏洞类型:未授权远程命令执行(RCE)
- 利用条件:
- 启用了 SNMP 接口
- 存在相关的数据采集模板(如 POLLER 类型)
- 可通过
X-Forwarded-For
伪造来源绕过身份认证
三、环境搭建
首先要把环境下好
在dockers容器里:
proxychains wget https://github.com/Cacti/cacti/archive/refs/tags/release/1.2.22.zip
下载完后再浏览器上打开,部署成功后,访问 http://<your-ip>:8080
,初始账号密码为 admin/admin
,按提示完成初始化。
打开网页后就输入用户名和密码(都是admin)然后下一步安装就行了
然后可以创建一个新图形,选device-uptime然后创建就行了,创建完之后就可以退出了,我们是要以访客的状态去测试的。
require(__DIR__ . '/include/global.php');
require_once($config['base_path'] . '/lib/api_device.php');
require_once($config['base_path'] . '/lib/api_data_source.php');
include_once($config['base_path'] . '/lib/data_query.php');
require_once($config['base_path'] . '/lib/api_graph.php');
require_once($config['base_path'] . '/lib/api_tree.php');
require_once($config['base_path'] . '/lib/data_query.php');
require_once($config['base_path'] . '/lib/html_form_template.php');
require_once($config['base_path'] . '/lib/ping.php');
require_once($config['base_path'] . '/lib/poller.php');
require_once($config['base_path'] . '/lib/rrd.php');
require_once($config['base_path'] . '/lib/snmp.php');
require_once($config['base_path'] . '/lib/sort.php');
require_once($config['base_path'] . '/lib/template.php');
require_once($config['base_path'] . '/lib/utility.php');
这个主要用于加载项目所需的各种库文件和全局配置。
查看数据库怎么存储值
docker ps -a
docker exec -it f87(这里是是一条命令结果中1.2.22的mysql的前缀) /bin/bash
mysql -uroot -p
然后输入密码
mysql> show databases;
然后进到cacti的数据库里
mysql> use cacti
mysql> show tables;
remote_agent.php这个代码,定义了一个鉴权函数
这段代码的核心逻辑是权限校验,具体解析如下: - remote_client_authorized() 是一个函数,推
测其作用是检查当前访问服务的远程客户端(如用户、设备等)是否已获得授权。
!remote_client_authorized() 表示对上述检查结果取反,即“如果远程客户端未被授权”。 - 若
满足“未授权”条件,则执行:print 'FATAL: You are not authorized to use this service' 意思是:输出错误信息,提示“致命错误:你未被授权使用此服务”。
$client_name代表的就是localhost,和$poller里面的hostname是相同的所以直接返回true,能返回ture,证明鉴权就绕过了
exit :终止程序运行,阻止未授权客户端继续访问服务。 整体来看,这段代码是服务端常见的安
全校验逻辑,用于拦截未授权访问,保护服务的安全性。
查poller-item:
mysql> select * from poller_item \G
安全建议:
升级 Cacti 至最新版本(>= 1.2.23)
禁用不必要的数据输入方法和 SNMP 功能
限制 remote_agent.php
的访问来源
在 Web 应用层增加认证机制与请求头校验逻辑
使用 Web 应用防火墙(WAF)对敏感参数行为检测