Hacker News new | ask | show | jobs
by tauwauwau 1538 days ago
Not sure why it's tagged JDK9+, but 'class' attribute is accessible on org.springframework.beans.BeanWrapperImpl.getLocalPropertyHandler() in JDK 8 also. It probably doesn't matter which JDK is being used, as long as this spring-beans dependency is used.

Whether logging JSP exploit in JDK 8 or lower can be used is another question. However, since 'class' is accessible via request parameter, it's already bad and there will probably be some ways to exploiting it. It doesn't matter whether the request is GET or POST, as long as mapped controller method uses a non-primitive request object, 'class' can be accessed. 'class.module' attribute is accessible from Java 9 and above, I tested on Java 11 and can access 'class.module'. Sample code that I used to test this with JDK 8 is below. I just tested whether 'class' attribute can be accessed via request parameter.

curl -X POST localhost:8080/test?class.modifiers=Hello

package com.test;

    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.web.bind.annotation.PostMapping;
    import org.springframework.web.bind.annotation.RestController;

    @SpringBootApplication
    public class Spring4ShellTestApplication {

    public static void main(String[] args) {
      SpringApplication.run(Spring4ShellTestApplication.class, args);
     }

    }
    @RestController
    class TestController {

    @PostMapping("/test")
     public String test(TestOuterRequest request) {

      String message = "Inner request is null";

      if (request.getInnerRequest() != null) {
       message = "your message was: " + request.getInnerRequest().getMessage();
      }

      System.out.println(message);

      return message;
     }
    }

    class TestOuterRequest {
     private TestInnerRequest innerRequest;

    public TestInnerRequest getInnerRequest() {
      return innerRequest;
     }

    public void setInnerRequest(TestInnerRequest innerRequest) {
      this.innerRequest = innerRequest;
     }
    }

    class TestInnerRequest {
     private String message;

    public String getMessage() {
      return message;
     }

    public void setMessage(String message) {
      this.message = message;
     }
    }
Finally here are the attributes that're exposed on 'class' as accessible properties in JDK 8 (JDK9+ adds 'module' on top of all these)

    annotatedInterfaces
    annotatedSuperclass
    annotation
    annotations
    anonymousClass
    array
    canonicalName
    class
    classes
    componentType
    constructors
    declaredAnnotations
    declaredClasses
    declaredConstructors
    declaredFields
    declaredMethods
    declaringClass
    enclosingClass
    enclosingConstructor
    enclosingMethod
    enum
    enumConstants
    fields
    genericInterfaces
    genericSuperclass
    interface
    interfaces
    localClass
    memberClass
    methods
    modifiers
    name
    package
    primitive
    signers
    simpleName
    superclass
    synthetic
    typeName
    typeParameters
1 comments

JDK9+ is important because Spring already prevents access to `class.classloader`, but it can be worked around thanks to modules (i.e. `class.module.classloader` works).
Yes but there may be some other Gadget vulnerabilities in all those fields too. Also, you might be able to make an app OOM by setting big string values somewhere in there.

It boggles my mind why this field is accessible at all and wasn't blocked in CVE-2010-1622.

You can make an app OOM by setting big string values anywhere. You gotta handle that at a higher level and reject requests larger than a certain size, which there is already a default for.
I spent a good amount of time trying to find some gadgets on jdk8 today no dice besides some DoS