浅谈热部署工具 springboot-devtools 安全风险

(旧事
devtools是spring-boot的一个热部署工具,无需手动重启Spring Boot应用就能实现自动加载项目。在开发过程中,如果我们修改了某些java文件,我们可能需要重启下项目来观看修改后的结果,如果使用spring-boot-devtools,当classpath中有文件变动时候,devtools会自动帮你重启服务器(百度的介绍,这个可以根据自己的情况自定义路径)。

前言

其实在devtools中还有一个远程模块,如果要启用Remote DevTools 那就要配置remote属性

首先按照devtools的文档看devtools的配置信息

当配置是以下这种情况时

pom:

image.png

application.yml:

image.png

即表示项目启用了远程devtools,这时候会存在安全风险

下面分析一下为什么会产生风险,产生什么样的风险


0x01 分析

因为SpringBoot所有的自动配置都是由xxxAutoConfiguration来进行的,已知

orgspringframeworkbootspring-boot-devtools2.6.4spring-boot-devtools-2.6.4.jar!orgspringframeworkbootdevtoolsautoconfigureRemoteDevToolsAutoConfiguration.class

是devtools的自动配置类

上半部分是有关spring.devtools.remote.secret配置的实现

查看流程,首先是将SecretHeaderNameSecret的值传入到HttpHeaderAccessManager类进行处理

跟进HttpHeaderAccessManager

在该类中会获取请求头中的一个参数headerName做比对,如果headerName的值与expectedSecret不一致就会报403

回到RemoteDevToolsAutoConfiguration

跟进对应的DevToolsProperties类查看SecretHeaderNameSecret

orgspringframeworkbootspring-boot-devtools2.6.4spring-boot-devtools-2.6.4.jar!orgspringframeworkbootdevtoolsautoconfigureDevToolsProperties.class

跟进RemoteDevToolsProperties,在getSecretHeaderName方法中返回的是X-AUTH-TOKEN,即http的头部有一个X-AUTH-TOKEN

getSecret则是从配置文件中获取

回到remoteDevToolsAccessManager方法,那么HttpHeaderAccessManager对象返回的就是对X-AUTH-TOKEN: Secret校验结果

往下看下半部分

这部分属于RemoteRestartConfiguration静态类,该类是devtools开关配置实现类

查看remoteRestartHandlerMapper方法流程

首先查看该方法里的properties.getRemote(),跟进对应的DevToolsProperties

orgspringframeworkbootspring-boot-devtools2.6.4spring-boot-devtools-2.6.4.jar!orgspringframeworkbootdevtoolsautoconfigureDevToolsProperties.class

getRemote方法返回的是RemoteDevToolsProperties对象

跟进RemoteDevToolsProperties对象

该类返回各种对应的属性值

其中getContextPath方法返回的是remoteRestartHandlerMapper方法中的url

拼接得出远程访问的url为/.~~spring-boot!~/restart

然后往下走进入到HttpRestartServerHandler

跟进HttpRestartServer

在该类的handle方法中,获取请求封装为objectInputStream对象,随后使用ObjectInputStreamreadObject方法对request进行反序列化,因为request是可控的,所以导致漏洞产生

0x02 漏洞场景

实际想要利用这个漏洞,条件其实有点苛刻(所以只能算风险项),要满足以下几个条件:

1、需要一个密码;
2、生产环境需要启用devtools Remote。

首先看第一点:

结合对headerName的比对想象一下,就算我们不知道密码,但是可以通过状态来爆破密码,即:

1、403的时候肯定是密码不对,因为密码不对访问就403;
2、密码对了,但是请求内容为空或反序列化内容不对就会报错,这时候状态就是500

所以,可以利用403跟500来爆破密码,密码的问题就不怎么用担心。


其次看“生产环境需要启用devtools Remote”

条件苛刻的原因就在这里,开头讲到的配置其实是大多数情况下针对测试环境的配置,其中因为:

image.png

在打包成jar后,devtools就不会启用,也就是说如果要利用成功,spring-boot-maven-plugin的属性就要是false,这样才能打包带上devtools


可以测试一下

引用依赖

image.png

Idea自己导入的版本为2.6.4

正常配置启用远程热部署,即开头的配置(如果是idea直接运行,Boolean无论是什么都会启用Remote DevTools),如果远程热部署启用成功,项目启动后会有提示

下面在默认配置下打包成jar试试:

可以看到devtools没了,将spring-boot-maven-plugin的属性改成false再打包试一下:

将属性改成false后打包的生产环境会包含Remote DevTools 

最后,尝试把序列化后的恶意数据发送触发


0x03 结尾

然后发现有老外去年的时候就说过这事- -

https://medium.com/@sherif_ninja/springboot-devtools-insecure-deserialization-analysis-exploit-2c4ac77c285a


参考:

https://docs.spring.io/spring-boot/docs/current/reference/html/using.html#using.devtools.remote-applications

https://docs.spring.io/spring-boot/docs/current/reference/html/using.html#using.devtools


本文作者:白帽100安全攻防实验室

本文为安全脉搏专栏作者发布,转载请注明:https://www.secpulse.com/archives/184472.html

Tags:
评论  (0)
快来写下你的想法吧!

白帽100安全攻防实验室

文章数:22 积分: 52

安全问答社区

安全问答社区

脉搏官方公众号

脉搏公众号