首页 > 其他分享 >身份验证绕过漏洞简析

身份验证绕过漏洞简析

时间:2024-11-26 09:04:47浏览次数:10  
标签:zoo1 admin 2181 身份验证 漏洞 简析 security solr

在目前可得的描述中可以得出这个漏洞主要是因为使用 PKIAuthenticationPlugin 的 Solr 实例(在使用 Solr 身份验证时默认启用)容易受到身份验证绕过的影响,下来着重分析绕过数据的传递过程
前言
最近solr爆出了新的身份绕过漏洞,工作中要对该漏洞进行复现,正好将分析的过程记录一下

在通报中可以看到该漏洞的评级那是相当高,CVSS3直接高达9.8分,在描述中可以得出这个漏洞主要是因为使用 PKIAuthenticationPlugin 的 Solr 实例(在使用 Solr 身份验证时默认启用)容易受到身份验证绕过的影响
在这里插入图片描述
环境搭建
当我们初步了解了漏洞的基本信息之后,开始搭建环境,因为之前咱们说的PKIAuthenticationPlugi主要用于在分布式 SolrCloud 环境中,所以咱们要搭建一个SolrCloud集群环境

集群环境基本身份验证需要我们首先创建一个security.json文件,对于基本身份验证,security.json文件必须有一个authentication部分,它定义用于身份验证的类。可以在创建文件时添加用户名和密码(例如:sha256(password+salt) hash),或者可以稍后使用基本验证API添加。

下面的配置信息为:

1.启用基本身份验证和基于规则的授权插件。

2.参数 “blockUnknown”: true 表示不允许未经身份验证的请求通过。

3.已定义了一个名为 “solr” 的用户,其中有密码 “SolrRocks”。

4.“admin” 角色已定义,并且具有编辑安全设置的权限。

5.“solr” 用户已被定义为 “admin” 角色。

{
“authentication”: {
“class”: “solr.BasicAuthPlugin”,
“credentials”: {
“solr”: “IV0EHq1OnNrj6gvRCwvFwTrZ1+z1oBbnQdiVC3otuq0= Ndd7LKvVBAaZIF0QAVi1ekCfAJXr1GGfLtRUXhgrF8c=”
},
“blockUnknown”: false,
“”: {
“v”: 0
}
},
“authorization”: {
“class”: “solr.RuleBasedAuthorizationPlugin”,
“permissions”: [
{
“name”: “security-edit”,
“role”: “admin”
}
],
“user-role”: {
“solr”: “admin”
}
}
}
然后我们通过镜像来搭建集群环境

下面的配置文件docker-compose.yaml中首先要注意的就是把上面的权限配置设置复制到容器中,[your-local-path]security.json记得替换为自己的目录

然后在文件中我们也打开了5006的java远程调试端口

创建了一个solr的network网络

version: ‘3.7’
services:
solr1:
image: solr:9.6.0
container_name: solr1e
ports:
- “8983:8983”
- “5006:5006”
environment:
- ZK_HOST=zoo1:2181,zoo2:2181,zoo3:2181
- SOLR_OPTS=-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5006
volumes:
- [your-local-path]security.json:/var/solr/data/security.json
networks:
- solr
depends_on:
- zoo1
- zoo2
- zoo3

solr2:
image: solr:9.6.0
container_name: solr2
ports:
- “8982:8983”
environment:
- ZK_HOST=zoo1:2181,zoo2:2181,zoo3:2181
networks:
- solr
depends_on:
- zoo1
- zoo2
- zoo3

solr3:
image: solr:9.6.0
container_name: solr3
ports:
- “8981:8983”
environment:
- ZK_HOST=zoo1:2181,zoo2:2181,zoo3:2181
networks:
- solr
depends_on:
- zoo1
- zoo2
- zoo3

zoo1:
image: zookeeper:3.8
container_name: zoo1
restart: always
hostname: zoo1
ports:
- 2181:2181
- 7001:7000
environment:
ZOO_MY_ID: 1
ZOO_SERVERS: server.1=zoo1:2888:3888;2181 server.2=zoo2:2888:3888;2181 server.3=zoo3:2888:3888;2181
ZOO_4LW_COMMANDS_WHITELIST: mntr, conf, ruok
ZOO_CFG_EXTRA: “metricsProvider.className=org.apache.zookeeper.metrics.prometheus.PrometheusMetricsProvider metricsProvider.httpPort=7000 metricsProvider.exportJvmInfo=true”
networks:
- solr

zoo2:
image: zookeeper:3.8
container_name: zoo2
restart: always
hostname: zoo2
ports:
- 2182:2181
- 7002:7000
environment:
ZOO_MY_ID: 2
ZOO_SERVERS: server.1=zoo1:2888:3888;2181 server.2=zoo2:2888:3888;2181 server.3=zoo3:2888:3888;2181
ZOO_4LW_COMMANDS_WHITELIST: mntr, conf, ruok
ZOO_CFG_EXTRA: “metricsProvider.className=org.apache.zookeeper.metrics.prometheus.PrometheusMetricsProvider metricsProvider.httpPort=7000 metricsProvider.exportJvmInfo=true”
networks:
- solr

zoo3:
image: zookeeper:3.8
container_name: zoo3
restart: always
hostname: zoo3
ports:
- 2183:2181
- 7003:7000
environment:
ZOO_MY_ID: 3
ZOO_SERVERS: server.1=zoo1:2888:3888;2181 server.2=zoo2:2888:3888;2181 server.3=zoo3:2888:3888;2181
ZOO_4LW_COMMANDS_WHITELIST: mntr, conf, ruok
ZOO_CFG_EXTRA: “metricsProvider.className=org.apache.zookeeper.metrics.prometheus.PrometheusMetricsProvider metricsProvider.httpPort=7000 metricsProvider.exportJvmInfo=true”
networks:
- solr

networks:
solr:

在环境搭建之后,进入到solr1e的容器内部执行命令,这是因为在SolrCloude模式中必须上传security.json到ZooKeeper

solr zk cp /var/solr/data/security.json zk:/security.json -z zoo1:2181,zoo2:2181,zoo3:2181
通过账号 solr/SolrRocks登录上之后,因为咱们之前的blockUnknown设置的是false,所以需要手动开一下禁止未经身份验证的请求通过
在这里插入图片描述
漏洞分析
前期分析
在茫茫大海中搜寻,找到了当时的issues,该issues被创建于2024-8-21
在这里插入图片描述
在描述中我们可以看到作者是这样描述的

By using “:/admin/info/key” at the end of the URL, the PKIAuthenticationPlugin can be bypassed, so that non-authorized users can access protected APIs.

通过这个我们找到了代码修复位置

https://issues.apache.org/jira/secure/attachment/13071024/SOLR-17417.patch

在描述中我们可以看到作者是这样描述的

By using “:/admin/info/key” at the end of the URL, the PKIAuthenticationPlugin can be bypassed, so that non-authorized users can access protected APIs.

通过这个我们找到了代码修复位置

https://issues.apache.org/jira/secure/attachment/13071024/SOLR-17417.patch

在这里插入图片描述
在这里插入图片描述
我们在dofilter过滤链中的身份验证哪里进行断点开始调试

运行到SolrDispatchFilter.java的authenticateRequest方法时,刚开始authenticationPlugin还是BasicAuthPlugin
在这里插入图片描述
当继续运行后,在下面会对是否为PKIAuthenticationPlugin进行验证,当程序检测到我们呢请求头中的SolrAuth: aaaa时,就会把当前的验证authenticationPlugin更换为PKIAuthenticationPlugin
在这里插入图片描述
在这里插入图片描述
在最后根据authenticationPlugin的值执行不同身份验证插件的authenticate方法
在这里插入图片描述
我们在这里就进入到了漏洞代码处,也就是PKIAuthenticationPlugin.java的doAuthenticate方法
在这里插入图片描述
在下面的153行代码以后才是PKIAuthenticationPlugin的decipherHeader方法对于SolrAuth的提取以及有效性验证,在最后如果验证全部通过之后会返回return ture
在这里插入图片描述
我们着重查看142行-151行的这部分代码,如果if语句符合条件,然后顺利执行完就能返回true,绕过了下来的验证部分。

这里先是提取出来了requesturI,然后检测requesturI是否是以PublicKeyHandler.PATH结尾

在这里插入图片描述
然后通过filterChain.doFilter(request, response)将当前请求和响应传递给过滤器链中的下一个过滤器进行处理。

当前只是探索出了绕过的第一步,就是在结尾加上/admin/info/key,我们接着代码往下一个Filter过滤器分析

在下一个filter过滤器中,经过了dispatch()---->call()---->init(),直到init()方法中我们可以看到有一点微妙
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在init()方法中我们可以看到代码会对我们请求的url进行操作,从“:”开始截断,只获取“:”之前的路径,然后进入到cores.getRequestHandler对path进行检查
在这里插入图片描述
在这里插入图片描述
在getRequestHandler方法中我们可以看到会对我们传入的path,也就是handlerName进行检查,我们需要保证handler的值不能为空,如果是空的话,在上面的代码init方法中我们就无法进入if代码块,从而执行以下代码获得admin权限了:

requestType = RequestType.ADMIN;

action = ADMIN;

在这里插入图片描述
进入get方法,发现只是查看name也就是咱们截断后的路径在不在registry中
在这里插入图片描述
registry为:
在这里插入图片描述
整理后也就是下面的接口路径

[/admin/zookeeper, /admin/configs, /admin/info/key, /admin/collections, /admin/authorization, /admin/cores, /admin/info, /admin/zookeeper/status, /admin/authentication, /admin/metrics]
通过之后,我们继续看call()中init()后面的代码
在这里插入图片描述

在这其中我们着重看一下authorize()方法
在这里插入图片描述
我们先获取授权 authzPlugin = cores.getAuthorizationPlugin()

正常的authzPlugin数据为

在这里插入图片描述
然后进入 authzPlugin.authorize(context)进行操作,对权限进行了一次校验,但是因为我们之前已经得到了admin权限,很容易就通过了

在这里插入图片描述
在这里插入图片描述
接下来一路代码会默认的走,在最后返回的时候有一个checkPathPerm()方法,进入该方法

在这里插入图片描述
在这段代码中一直在传递的permissions,它的值为{“name”:“security-edit”,“role”:“admin”},这个其实就是咱们在刚开始的security.json中设置的admin权限

在这里插入图片描述
在这里插入图片描述
我们继续,下来就是一些对于权限和咱们请求之间的判断,一路走到getPermissionName()方法
在这里插入图片描述

在这里的话会对get请求和post请求两个区分开,如果是get请求的话,会返回security-read,post的话是返回security-edit,这里要记住,咱们之前在搭建环境的时候设置的就是admin权限为security-edit
在这里插入图片描述
在这里插入图片描述

随后会对咱们的security-edit和刚才获得的get请求的security-read进行了对比,得到applies为false
在这里插入图片描述那么返回到这里就是false,会跳转到return null进行返回

在这里插入图片描述
为null之后,checkPathPerm方法返回的就是rsp为200的一个返回值
在这里插入图片描述
最后返回到authorize方法,我们可以看到statusCode就是刚才rsp.statusCode,也就是200,然后一路跳过下面四个if判断,成功返回null
在这里插入图片描述
在这里插入图片描述
执行完成返回到call()方法,authzFailure经过一系列判断为null,走到下面因为admin权限进入handleAdminRequest()执行,成功绕过了身份验证这一段得到了执行
在这里插入图片描述
POST请求
上面的调试是GET请求进行的过程,但是我发现大家使用poc全都是止步于get请求,那么POST进行数据的修改可不可以呢,我们进行尝试

首先的话,接口肯定要挑咱们上面分析的registry支持的接口

整理后也就是下面的接口路径

[/admin/zookeeper, /admin/configs, /admin/info/key, /admin/collections, /admin/authorization, /admin/cores, /admin/info, /admin/zookeeper/status, /admin/authentication, /admin/metrics]
刚刚好,添加用户的接口/admin/authentication就在其中,咱们进行尝试,奇怪的是,竟然报了401
在这里插入图片描述
造成这样的原因是因为在上面的get与post请求进行区分的时候,POST获得的是PermissionNameProvider.Name.SECURITY_EDIT_PERM,即为security-edit
在这里插入图片描述
咱们的admin权限为security-edit,于是两个进行判断之后的applies值为true

在这里插入图片描述
在这里于是也因为if判断成功发生了变动,返回的是permission,并不是null
在这里插入图片描述
在这里并没有直接返回MatchStatus.NO_PERMISSIONS_FOUND,而是走到了下面determineIfPermissionPermitsPrincipal中进行了一次getUserPrincipal()

在这里并没有直接返回MatchStatus.NO_PERMISSIONS_FOUND,而是走到了下面determineIfPermissionPermitsPrincipal中进行了一次getUserPrincipal()

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里进行了一次对当前身份的检测,咱们因为是绕过走到这里的,当然没有,返回为null,于是喜提401
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
最后喜提401,“Authentication failed, Response code: 401”

那么,根本原因是在哪里的呢,就是这里,post请求的security-edit和咱们当前admin请求的对比

POST请求成功的条件
当我们修改最初的权限

将admin的security-edit权限删去之后

在这里插入图片描述
回到了perssions判断这里,因为之前get请求时,咱们的权限配置为{“name”:“security-edit”,“role”:“admin”},但是咱们这次将这些都删除了,所以在这里perssions自然为null

在这里插入图片描述
直接返回rep.statusCode=200,下来就直接运行成功了
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
账号添加成功
在这里插入图片描述
总结
这次solr的权限绕过漏洞主要还是下面的这部分代码造成的。而在漏洞的分析复现中也是发现get和post竟然不都是成功的,post请求的利用会更加苛刻一些,再此也是简单的分析了一遍,下来更期待大佬们的进一步拓展。

在这里插入图片描述

标签:zoo1,admin,2181,身份验证,漏洞,简析,security,solr
From: https://blog.csdn.net/Libao657/article/details/143874335

相关文章

  • VulnHub-Sick0s1.1解法二shellshock漏洞
    免责声明本博客提供的所有信息仅供学习和研究目的,旨在提高读者的网络安全意识和技术能力。请在合法合规的前提下使用本文中提供的任何技术、方法或工具。如果您选择使用本博客中的任何信息进行非法活动,您将独自承担全部法律责任。本博客明确表示不支持、不鼓励也不参与任何形式的......
  • pikachu平台XXE漏洞通关教程详解
    声明!学习视频来自B站up主泷羽sec有兴趣的师傅可以关注一下,如涉及侵权马上删除文章,笔记只是方便各位师傅的学习和探讨,文章所提到的网站以及内容,只做学习交流,其他均与本人以及泷羽sec团队无关,切勿触碰法律底线,否则后果自负!!!!工具在网盘,自取通过网盘分享的文件:phpstudy链......
  • 【网络安全渗透测试零基础入门】之cve漏洞实战案例解析(非常详细)
    一、前言这是我给粉丝盆友们整理的网络安全渗透测试入门阶段文件包含渗透与防御教程本文主要讲解漏洞丨实例分析cve2012-0158喜欢的朋友们,记得给我点赞支持和收藏一下,关注我,学习黑客技术。一、漏洞简介MicrosoftOffice2003sp3是2007年9月18日由微软公司创作的一个办......
  • 云原生周刊:K8s 严重漏洞
    开源项目推荐KitOpsKitOps是一款开源的DevOps工具,专为AI/ML项目的全生命周期管理而设计,通过将模型、数据集、代码和配置打包并版本化为符合OCI(开放容器标准)的工件,简化了AI/ML工作流的部署与管理。KitOps支持统一打包,将AI/ML模型、数据集和配置封装为便携式工件,同时提......
  • FastJson漏洞复现
    FastJson漏洞复现环境:vulhub/fastjson Fastjson是阿里巴巴公司开源的一个高性能的Java库,专门用于处理JSON数据格式。 它不仅能够将Java对象序列化为JSON格式的字符串,还能将JSON字符串反序列化为Java对象。漏洞发现出现json格式的地方,就可能使用FastJsson1.通过报错页面可......
  • 【PHP漏洞】PHPMyAdmin写shell的几种方式
    phpMyAdmin是一个以PHP为基础,以web方式架构在服务器上的MySQL的数据库管理工具。让管理者可以通过Web接口来管理MySQL数据库。查看phpmyadmin版本:/phpMyAdmin/README在高版本中无法写入一句话mysql新特性secure_file_priv会对读写文件产生影响,该参数用来限制导入导出查看该......
  • Fastadmin框架短视频知识付费系统存在任意文件读取漏洞
    免责声明:本文旨在提供有关特定漏洞的深入信息,帮助用户充分了解潜在的安全风险。发布此信息的目的在于提升网络安全意识和推动技术进步,未经授权访问系统、网络或应用程序,可能会导致法律责任或严重后果。因此,作者不对读者基于本文内容所采取的任何行为承担责任。读者在使用本......
  • msiscan:一款针对msi文件的漏洞检测与识别工具
    关于msiscanmsiscan是一款针对MicrosoftWindows*.msi安装程序文件的漏洞检测与识别工具,该工具基于Python开发,可以用于获取安装程序的概述并识别潜在的安全问题。需要注意的是,当前版本的msiscan正处于积极开发中,可能会存在假阳性和假阴性问题。工具要求Pythontermcolorm......
  • 【技术分析】UniV3 Pool 对 burnable 漏洞代币的防护机制
    代币漏洞攻击者可以通过transferFrom函数burn任意账户的Vul代币。因为本问涉及的漏洞可导致用户资产损失,所以不提供代币和Pool的地址,代币名称用Vul代币代替。利用方式在V2Pool场景下,针对burnable漏洞的利用方式购买少量Vul代币burn掉大量V2Pool中......
  • 漏洞应用脚本
    #!/usr/bin/python##findingtargets431337z:#gdb/usr/sbin/smbd`psauwx|grepsmbd|grep-vgrep|head-n1|awk'{print$2}'`<<<`echo-e"printsystem"`|grep'$1'#->togetsystem_libc_addr,ente......