CVE-2025-54424漏洞剖析:1Panel面板TLS客户端证书校验缺陷导致RCE

CVE-2025-54424漏洞剖析:1Panel面板TLS客户端证书校验缺陷导致RCE
1. 项目概述最近在安全圈里一个关于1Panel面板的漏洞引起了不小的讨论编号是CVE-2025-54424。简单来说这是一个因为TLS客户端证书校验逻辑存在缺陷导致攻击者可以绕过认证直接调用高权限接口最终实现远程命令执行的严重漏洞。1Panel作为一个新兴的、现代化的Linux服务器运维面板很多开发者和管理员都在用这个漏洞的影响面其实不小。我花了一些时间结合公开的漏洞通告和代码对这个漏洞的成因、利用方式以及影响范围做了个梳理并且写了一个一体化的检测与利用脚本。这篇文章我就来详细拆解一下这个漏洞的来龙去脉从原理分析到实战复现最后分享这个脚本的设计思路和使用方法希望能给从事安全研究、运维或者对1Panel感兴趣的朋友提供一个清晰的参考。1.1 漏洞核心一个被“放行”的假证件要理解这个漏洞我们得先搞明白1Panel在v2版本引入的“节点管理”架构。新版本里1Panel分成了Core端主控面板和Agent端被控节点。Core端要管理成千上万的服务器就需要在每个服务器上安装一个Agent代理程序。两者之间的通信自然要保证安全所以采用了HTTPS协议并且要求客户端Agent出示证书来证明自己的身份。问题就出在这个“证明身份”的环节上。根据漏洞通告和代码分析Agent端在启动HTTPS服务时配置的TLS客户端认证策略是tls.RequireAnyClientCert。这个策略的名字听起来有点绕我打个比方这就好比小区门卫的职责是“检查进门的人是否带了工作证”。tls.RequireAnyClientCert这个策略的意思就是“我只看你有没有带证件至于证件是真是假、是不是我们公司发的我不管。” 换句话说攻击者自己用工具随手伪造一个“工作证”只要上面印着“有证件”三个字门卫就会放行。在TLS握手中这表现为服务端只要求客户端提供一个证书但不会去验证这个证书是否由可信的证书颁发机构CA签发。任何自签名的证书都能通过TLS层的校验。然而漏洞的链条还没完。TLS握手通过后应用层1Panel的代码还有一个校验逻辑它会检查证书的“通用名称”字段也就是CN。它要求CN必须是panel_client。这个校验的本意是好的想进一步确认连接者的身份。但坏就坏在它只检查了CN没有检查证书的“签发者”。伪造一个CN为panel_client的自签名证书简直是轻而易举的事情。于是攻击者就可以拿着一份自己造的、CN为panel_client的“假证件”同时骗过了TLS层和应用层实现了未授权访问。1.2 影响范围与风险敞口那么这个漏洞影响有多大呢根据官方通告受影响的是1Panel v2.0.5及之前的所有版本。这意味着在2025年对应补丁发布前所有使用了节点管理功能的1Panel v2环境都暴露在风险之下。风险之所以被评定为“高危”乃至“严重”根本原因在于这个认证绕过所暴露的接口权限极高。一旦攻击者通过伪造证书建立了“合法”连接他就能访问到Agent端那些原本需要严格权限控制的WebSocket接口。这其中就包括进程管理接口(/process/ws)可以获取服务器上所有进程的详细信息包括PID、执行路径、命令行参数等这直接导致了敏感信息泄露。主机终端接口(/hosts/terminal)这是一个交互式Shell接口。攻击者可以通过它发送任意系统命令并在目标服务器上以运行Agent服务的用户权限通常是root或高权限用户执行实现真正的远程代码执行。容器终端接口(/containers/terminal)如果目标服务器上运行了Docker攻击者还可以通过此接口进入容器内部执行命令威胁容器环境的安全。文件下载进度接口(/files/wget/process)可以干涉文件下载操作。想象一下攻击者无需知道面板的登录密码只要发现目标服务器的9999端口1Panel Agent默认端口对外开放就能直接获得一个系统Shell。这对于将1Panel Agent部署在公网或者内网中其他不可信主机可以访问到的服务器来说无疑是打开了方便之门。很多管理员可能认为面板服务在内网就很安全但这个漏洞打破了这种假设内网横向移动变得异常简单。2. 漏洞原理深度剖析与代码审计视角光知道漏洞现象还不够我们得深入代码层面看看这个安全防线究竟是怎么被绕过的。这对于我们理解漏洞本质、提升代码审计能力至关重要。2.1 从路由到中间件漏洞的触发路径我们跟着一次攻击请求可能走过的路来分析。假设攻击者已经伪造了证书并向https://target:9999/api/v2/hosts/terminal发起了WebSocket连接请求。首先请求会进入Agent端定义的路由。我们查看agent/init/router/router.go文件中的Routers函数。可以发现在注册路由时很多路由组都使用了一个叫Certificate的中间件。这个中间件就是应用层校验的核心。// 示例性代码逻辑非原文件逐字拷贝 func Routers() *gin.Engine { router : gin.Default() apiGroup : router.Group(/api/v2) { // 使用了Certificate中间件进行校验 apiGroup.Use(middleware.Certificate()) apiGroup.GET(/dashboard/base/os, handler.GetBaseOS) apiGroup.GET(/hosts/terminal, handler.WsTerminal) // ... 其他路由 } return router }关键点在于Certificate这个中间件被应用在路由组级别意味着组内所有路由包括我们关注的/hosts/terminal都会先经过它的校验。2.2 脆弱的校验逻辑Certificate中间件详解接下来我们聚焦到agent/middleware/certificate.go文件中的Certificate函数。它的伪代码逻辑简化后如下func Certificate() gin.HandlerFunc { return func(c *gin.Context) { // 1. 检查是否完成了TLS握手 if c.Request.TLS nil || !c.Request.TLS.HandshakeComplete { c.AbortWithStatusJSON(http.StatusForbidden, gin.H{message: TLS handshake not complete}) return } // 2. 检查是否有对等证书客户端证书 if len(c.Request.TLS.PeerCertificates) 0 { c.AbortWithStatusJSON(http.StatusForbidden, gin.H{message: client certificate not provided}) return } // 3. 获取第一个客户端证书并检查其CN字段 clientCert : c.Request.TLS.PeerCertificates[0] if clientCert.Subject.CommonName ! panel_client { c.AbortWithStatusJSON(http.StatusForbidden, gin.H{message: invalid client certificate}) return } // 4. 校验通过放行请求 c.Next() } }从代码中我们可以清晰地看到漏洞链第一关检查c.Request.TLS.HandshakeComplete。这一关的“松紧度”取决于服务端TLS配置。在agent/server/server.go的Start函数中配置是tls.Config{ClientAuth: tls.RequireAnyClientCert}。正如之前所说这一关只要求有证书不验证真伪伪造证书轻松通过。第二关检查是否有证书 (len(c.Request.TLS.PeerCertificates) 0)。我们提供了伪造证书通过。第三关检查证书的CN是否为panel_client。我们伪造的证书CN正是这个通过。致命缺失整个校验过程中没有对证书的签发者Issuer进行任何验证也没有验证证书是否由可信CA签发。这就是认证绕过的根本原因。应用层完全信任了TLS层传递过来的、未经验证的客户端证书信息。2.3 WebSocket接口的未授权访问通过Certificate中间件后请求就抵达了具体的业务处理器。对于/hosts/terminal这是一个WebSocket端点用于建立交互式终端。由于认证已被绕过攻击者建立的WebSocket连接就被视为“已授权”的合法Agent连接。在WebSocket通信中客户端可以发送JSON格式的消息其中type字段为cmddata字段是经过Base64编码的系统命令。服务端会解码并执行这些命令然后将执行结果同样通过Base64编码后返回。这就构成了一个完整的、交互式的远程命令执行通道。注意这里有一个细节需要强调。在发送命令时data字段编码的字符串末尾必须包含换行符\n模拟用户在终端敲击回车的行为否则命令可能不会被执行。这是很多命令行交互接口的常见要求在编写利用工具时需要特别注意。3. 漏洞复现手动与自动化实践理解了原理我们动手来验证一下。复现环境可以自己搭建一个受影响的1Panel v2.0.5节点这里我们更关注攻击者的操作流程。3.1 手动复现使用OpenSSL与Burp Suite手动复现能帮助我们更深刻地理解漏洞利用的每一个环节。第一步生成伪造的客户端证书攻击者需要在本地生成一个自签名的证书关键是将CN字段设置为panel_client。openssl req -x509 -newkey rsa:2048 -keyout panel_client.key -out panel_client.crt -days 365 -nodes -subj /CNpanel_client这条命令会生成两个文件panel_client.key私钥和panel_client.crt证书。-subj /CNpanel_client参数直接指定了证书的主题其中CN就是panel_client。第二步配置Burp Suite进行中间人攻击测试虽然这是一个直接攻击Agent端的漏洞但我们可以用Burp来方便地加载客户端证书并构造WebSocket请求。打开Burp Suite进入Proxy - Options页面。找到TLS设置区域点击Client TLS Certificates下方的Add按钮。在配置规则中你可以选择针对特定主机如your-target-ip:9999或所有主机应用此证书。选择我们刚才生成的panel_client.crt和panel_client.key文件。配置完成后确保Burp的拦截是关闭的然后我们直接使用Repeater模块来构造WebSocket请求。第三步构造并发送WebSocket请求在Burp的Repeater中将请求方法改为GETURL填写wss://target-ip:9999/api/v2/hosts/terminal。需要手动添加一个HeaderConnection: Upgrade和Upgrade: websocket。不过Burp Repeater在检测到wss://协议和WebSocket相关头后通常会提供图形化的WebSocket交互界面。点击“Connect”建立WebSocket连接。如果漏洞存在且证书配置正确连接会成功建立。在WebSocket消息发送框内输入以下JSON格式的命令例如执行whoami{type: cmd, data: d2hvYW1pCg}其中d2hvYW1pCg是whoami\n的Base64编码注意包含换行符。发送后如果收到包含Base64编码输出的响应解码后就能看到命令执行结果。实操心得手动复现时最容易出错的地方就是证书加载和WebSocket握手。确保Burp的TLS客户端证书规则确实应用到了目标主机和端口。另外如果目标服务器防火墙或网络策略阻止了外部访问9999端口那一切都是徒劳。所以在真实测试中信息收集和端口发现是前置且关键的一步。3.2 自动化检测与利用脚本设计手动操作适合分析但不适合批量检测或实战利用。为此我编写了一个Python脚本CVE-2025-54424.py它集成了漏洞检测和交互式利用功能。脚本的核心设计思路如下动态证书生成脚本运行时会利用cryptography库在内存中动态生成CN为panel_client的自签名证书和私钥并保存为临时文件。任务结束后自动清理避免在测试机上留下痕迹。两级检测机制为了提高检测的准确性并减少误报脚本采用了两步验证法HTTP API预检首先尝试访问一个通常存在的API端点例如/api/v2/dashboard/base/os。使用伪造的证书发起HTTPS GET请求。如果返回200状态码说明TLS握手和应用层CN校验已通过目标可能存疑。WebSocket连接验证在HTTP预检成功后尝试建立到/api/v2/hosts/terminal的WebSocket连接。这一步是最终确认因为即使API能访问WebSocket端口也可能因配置问题未开启。只有WebSocket连接也成功建立才判定为漏洞确实存在。双模式运行扫描模式 (-f file)读取一个包含目标IP:PORT列表的文件使用多线程并发进行两级检测快速筛选出存在漏洞的目标并将结果保存。利用模式 (-u url)对单个目标进行检测确认存在漏洞后自动进入交互式Shell模式。在此模式下脚本会建立一个稳定的WebSocket连接将用户输入的命令发送到目标并实时显示命令输出模拟一个简单的远程终端。代理支持为了方便在特定网络环境或配合其他工具如Burp进行调试脚本支持通过--proxy参数设置HTTP/Socks5代理。健壮性处理包含了完整的异常捕获、超时控制、线程锁防止多线程打印混乱以及用户中断CtrlC的优雅处理。脚本的关键函数解析generate_self_signed_cert(): 负责证书的动态生成。它使用cryptography库创建RSA私钥和X.509证书确保证书主题CN为panel_client。check_target(): 执行针对单个目标的两步检测流程。它首先用requests库配置伪造证书和禁用验证进行HTTP预检然后用websocket-client库尝试建立WSS连接。run_exploit_mode(): 在利用模式下建立WebSocket连接后会启动一个单独的线程receive_thread()来持续接收服务端返回的数据命令执行结果主线程则负责读取用户输入并发送命令实现交互。4. 工具使用指南与实战演示下面我们来具体看看这个工具怎么用。确保你的Python环境已安装必要的依赖pip install websocket-client cryptography PySocks requests。4.1 批量扫描模式当你有一个目标列表例如从网络空间搜索引擎如Fofa、Shodan收集的开放9999端口的1Panel服务时使用扫描模式。将目标保存到一个文本文件中每行一个格式为IP:PORT或域名:PORT。例如targets.txt192.168.1.100:9999 10.0.0.5:9999 example.com:9999运行扫描命令python CVE-2025-54424.py -f targets.txt -o results.txt -t 30-f targets.txt: 指定目标文件。-o results.txt: 指定保存漏洞目标的结果文件。-t 30: 设置并发线程数为30可以根据网络状况调整。--proxy http://127.0.0.1:8080: 可选通过Burp等代理发送流量方便调试。脚本运行后会动态生成证书然后并发地对每个目标进行检测。控制台会实时输出每个目标的检测状态[]表示存在漏洞[-]表示不存在或无法连接。扫描结束后所有存在漏洞的目标地址会被写入results.txt。4.2 单目标利用模式当你已经确认某个目标存在漏洞或者想对单个目标进行深入测试时使用利用模式。运行利用命令python CVE-2025-54424.py -u 192.168.1.100:9999-u 192.168.1.100:9999: 指定单个目标。脚本会自动执行检测。如果检测到漏洞会输出类似下面的信息并进入交互式Shell---[ 进入单点利用模式: 192.168.1.100:9999 ]--- [*] 正在动态生成伪造的客户端证书... [] 证书已生成: /tmp/tmpxyz.crt, /tmp/tmpxyz.key [*] 192.168.1.100:9999 - HTTP 预检成功 (200 OK) [] 目标 192.168.1.100:9999 确认存在漏洞! [*] 正在尝试获取交互式 Shell... [] Shell 获取成功 [*] 输入 exit 或按下 CtrlC 退出。 --- $此时你可以像在本地终端一样输入命令例如whoami、id、pwd、ls -la等。命令的执行结果会回显在下方。输入exit即可退出Shell。注意事项这个交互式Shell运行在Agent服务的权限下通常是root。请务必在合法授权和可控的环境中进行测试你的每一个命令都会在目标服务器上真实执行。此外由于WebSocket连接的特性一些需要复杂终端交互的程序如vim,top等可能无法正常工作但执行大多数系统命令和上传下载文件是没问题的。4.3 网络空间测绘与漏洞影响面评估对于渗透测试人员或安全运维来说如何快速找到潜在目标这就需要用到网络空间测绘。根据漏洞特征我们可以构造特定的搜索语法Fofacert.subject_orgFIT2CLOUD port9999或cert.subject.suffixpanel_server。因为1Panel的证书通常包含组织名FIT2CLOUD而服务端证书的CN可能是panel_server。Huntercert.subject.orgFIT2CLOUD port9999 protocoltls。这些语法可以帮助我们快速定位在公网暴露了9999端口且使用了1Panel默认证书的服务器。需要严重警告的是未经授权对公网IP进行扫描和渗透测试是违法行为。这些信息仅用于企业自查自身资产风险或在获得明确授权的情况下进行安全评估。5. 漏洞修复与安全加固建议对于1Panel的用户或开发者了解如何修复和防范此类漏洞至关重要。官方修复方案1Panel官方在后续版本中修复了此漏洞。修复的核心是将Agent端的TLS客户端认证策略从tls.RequireAnyClientCert更改为tls.RequireAndVerifyClientCert并配置了正确的客户端CA证书池。这意味着服务端不仅要求客户端提供证书还会严格验证该证书是否由可信的CA签发。同时应用层校验也可能得到了加强。最直接有效的修复方法就是立即将1Panel升级到官方发布的最新安全版本。安全加固建议最小化网络暴露除非绝对必要不要将1Panel的Agent服务端口默认9999暴露在公网。通过防火墙策略严格限制访问来源IP只允许可信的Core端服务器IP访问。使用网络隔离将管理面板Core和受控节点Agent部署在独立的、安全的网络分区内遵循最小权限原则。定期更新与漏洞监控关注使用项目的官方安全公告和CVE信息建立及时的更新机制。对于自建或开源软件应定期进行安全审计或使用SCA工具检查依赖项漏洞。纵深防御不要仅仅依赖一个层面的认证。可以考虑在Agent主机上部署主机级防火墙、入侵检测系统并对关键命令执行行为进行日志审计和告警。证书管理规范化如果自行部署类似需要双向TLS认证的服务务必确保使用由内部或公共可信CA签发的证书并妥善保管私钥定期轮换证书。6. 防御视角下的思考与总结从防御者角度看CVE-2025-54424是一个典型的多层安全机制失效案例。TLS配置的疏忽RequireAnyClientCert为第一道防线撕开了口子而应用层校验的不完整只验CN不验签发者则让攻击者长驱直入。这提醒我们在设计安全认证流程时默认拒绝原则安全配置应该默认是最严格的任何放松都需要充分的理由和风险评估。完整链式校验不能假设上一层的安全机制是完备的。在TLS握手之后应用层应该进行独立的、完整的身份验证包括证书链验证、吊销状态检查等。权限最小化即使身份被冒用也应限制其权限。这个漏洞之所以危害巨大是因为认证后获得的权限过高。在设计API时应遵循最小权限原则即使是在“内部”通信中。对于安全研究人员和开发者这个漏洞的分析过程也展示了从漏洞公告到代码定位再到利用脚本开发的完整路径。理解通信协议如TLS、框架中间件机制如Gin的中间件和实际代码逻辑是进行有效安全审计的基础。最后再次强调本文所有技术细节、工具和脚本仅用于合法的安全研究、学习以及企业自身的安全防护测试。任何未经授权的攻击行为都是非法的必将受到法律制裁。