CVE-2022-22965 漏洞分析


CVE-2022-22965 漏洞分析

文章插图
CVE-2022-22965
A Spring MVC or Spring WebFlux Application running on JDK 9+ may be vulnerable to remote code execution (RCE) via data binding. The specific exploit requires the application to run on Tomcat as a WAR deployment. If the application is deployed as a Spring Boot executable jar, i.e. the default, it is not vulnerable to the exploit. However, the nature of the vulnerability is more general, and there may be other ways to exploit it.
 
[VulEnv/springboot/cve-2022-22965 at master · XuCcc/VulEnv]
 
 
一个典型的 Bean 对象如下
class UserInfo {      private int age;      public int getAge() {          return age;      }      public void setAge(int age) {          this.age = age;      }  }通过 private 定义属性 通过 public getXyz/setXyz 来读写的 class 被称为 JAVABean [^1]
 
java.beans.Introspector [^2] 提供一套标准的方法来访问 javaBean 中的属性、方法、事件,会搜索 Bean 本身并一路往上搜索父类来获取信息 。如通过 java.beans.PropertyDescriptor 来获取属性相关的信息(name/getter/setter/...)
public static void main(String args[]) throws IntrospectionException {      BeanInfo info = Introspector.getBeanInfo(UserInfo.class);      PropertyDescriptor[] propertyDescriptors = info.getPropertyDescriptors();      for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {          System.out.println(propertyDescriptor);          System.out.println("=================================================");      }  }// java.beans.PropertyDescriptor[name=age; values={expert=false; visualUpdate=false; hidden=false; enumerationValues=[Ljava.lang.Object;@6e1567f1; required=false}; propertyType=int; readMethod=public int person.xu.vulEnv.UserInfo.getAge(); writeMethod=public void person.xu.vulEnv.UserInfo.setAge(int)]// =================================================// java.beans.PropertyDescriptor[name=class; values={expert=false; visualUpdate=false; hidden=false; enumerationValues=[Ljava.lang.Object;@5cb9f472; required=false}; propertyType=class java.lang.Class; readMethod=public final native java.lang.Class java.lang.Object.getClass()]// =================================================也可以通过内省操作来进行赋值操作
UserInfo user = new UserInfo();  System.out.println("age: " + user.getAge());  PropertyDescriptor pd = Arrays.stream(info.getPropertyDescriptors()).filter(p -> p.getName().equals("age")).findFirst().get();  pd.getWriteMethod().invoke(user, 18);  System.out.println("age: " + user.getAge());// age: 0// age: 18 
提供了一套简单的api来进行 JavaBean 的操作,以及一些高级特性(嵌套属性、批量读写等)
public class User {      private String name;      private UserInfo info;      public String getName() {          return name;      }      public void setName(String name) {          this.name = name;      }      public UserInfo getInfo() {          return info;      }      public void setInfo(UserInfo info) {          this.info = info;      }      public static void main(String args[]) {          User user = new User();          BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(user);          bw.setAutoGrowNestedPaths(true);          bw.setPropertyValue("name", "wang");          bw.setPropertyValue("info.age", 18);          System.out.printf("%s is %d%n", user.getName(), user.getInfo().getAge());      }  }// wang is 18


推荐阅读