背景
最近 Spring 框架不大太平,接连爆出来多个 RCE 远程代码执行的 CVE 漏洞,其中有 CVE-2018-1270,CVE-2018-1273,通过对造成漏洞部分代码进行分析,发现都是因为滥用 SpEL 的 StandardEvaluationContext。
漏洞影响
攻击者可以在未获得授权的情况下,将精心制作的请求参数注入到存在该漏洞的服务器上,从而发起远程代码执行攻击。
受影响的范围
Spring Data Commons 1.13 - 1.13.10 (Ingalls SR10)
Spring Data REST 2.6 - 2.6.10 (Ingalls SR10)
Spring Data Commons 2.0 to 2.0.5 (Kay SR5)
Spring Data REST 3.0 - 3.0.5 (Kay SR5)
更早的版本也会受到影响
SpEL
SpEL 是一门非常简单的表达式语言,但是功能或者权限来说太大了,因此这里如果表达式能够被外部污染,基本上都可以造成 RCE。
SpEL 的具体语法,我这里就不一一介绍了,详情参考官方文档。我这里只说两个能够被有效利用的点。
类型表达式
使用类型表达式还可以进行访问类静态方法及类静态字段。使用 T()来表示,其中类名必须是全称,java.lang 包除外。因此这里就出现了第一类 payload。
类实例化
创建一个 Java 类实例,和上面一样,类名要求是全称。因此这里可以产生第二类 payload。
变量和函数的使用
在表达式里面要是用变量或者函数,需要提前在 context 使用 setVariable 和 registerFunction 才能使用,因此初步看没有太大利用价值。其中有两个内置变量 #root 根对象,#this 代表 Context 对象。而在 CVE-2018-1273 的 Spring Data Commons 中,
context 在初始化的时候,没有传入根对象,但是后面显式调用了 setRootObject,因此 #root 为 Map 对象,利用价值不大,#this 为 StandardEvaluationContext 对象,方法比较多,还在研究中,感觉这里也能提取出一类 payload,未完待续。
SpEL 调试
我们在写出来 payload 后,需要校验一下 payload 是否有效,可以使用如下的代码快速进行校验。
实战分析
CVE-2018-1273
上面也贴出来部分造成漏洞的代码,现在把完整的代码贴出来,代码位于 org,springframework.data.web.MapDataBinder 类中,
propertyName 是攻击者可以控制的变量,但是代码中将它直接用来生成 Expression。但是在使用之前我们发现有一段代码进行 propertyName 的有效性校验,它用来判断实体类的 propertyName 属性是否可写。
但是经过我们对这个 isWritableProperty 函数的分析,我们发现这里存在一个逻辑问题。
这个函数会造成 propertyName 如果是 name 和 name[huangjacky]返回一个东西。
攻击 Exploit 的诞生
我们的演示程序中,实体类是这样定义的:
因此我们对应的 Exploit 就应该为:
不出意外的话,这个时候可爱的计算器就出来了。
修复建议
使用华为云 WAF 立即防护
华为云安全团队第一时间对漏洞进行分析,云端下发内置规则进行防护,用户只需要接入华为云 WAF 即可。
使用华为云漏洞扫描服务进行安全检测
华为云漏洞扫描服务根据华为云安全团队漏洞分析后提取出对用户网站无害的安全检测规则,有效帮助用户发现该漏洞。
升级代码框架
Spring Data Commons
2.0.x 的用户升级到 2.0.6
1.13.x 的用户升级到 1.13.11
Spring Data REST
2.x 用户升级到 2.6.11
3.x 用户升级到 3.0.6
Spring Boot
1.5.x 用户升级到 1.5.11
2.x 用户升级到 2.0.1
本文转载自 华为云产品与解决方案 公众号。
原文链接:https://mp.weixin.qq.com/s/ZZPVOO61ffC0ry6-V6vdWA
评论