According to the description in security bulletin, we can simply attain some critical points resulting in the vulnerability.
Setting the ErrorHandlingDeserializer as a key and/or value in the Kafka record in configuration.
Setting the boolean type properties checkDeserExWhenKeyNull and/or checkDeserExWhenValueNull to true.
The users can publish a Kafka topic without any verification.
0x02 Concepts of Kafka
Before deeply diving into the vulnerability, we promptly review some relevant concepts of the Kafka service.
Producer：we call the object for publishing record Kafka topic producer
Topic：The records are classified by the Kafka service, and each classification is named Topic.
Broker：The published messages are stored in a group of servers, we call it Kafka cluster. Each of the server is a Broker. The consumer can attain the data form Broker and consume more than one topic.
Consumer：The object which is used to subscribe message and handle with the published message is called Kafka topi consumer. The consumption messages are topic based.
Moreover,it is necessary to review the structure of Kafka record.
Kafka Record, we also call it Message or Event consisting of Header and Body. The header data virtually equals to Metadata including the basic elements like Topic, Patition and Timestamp. They are stored as a pair of key/value. The body data usually are the relevant business data stored as key/value constructure as well.
Zookeeper server is required before deploying Kafka service.
1.Installing Zookeeper server by docker
docker run -d --name zookeeper -p 2181:2181 -t zookeeper:latest
Se the breakpoint at the getExceptionFromHeader function and then have the server start.
Step into invokeIfHaveRecords function, the record object will be deserialized.
Back to the getExceptionFromHeader function.
This function makes the value springDeserializerExceptionKey of record.headers() into the the value of the variables headerName and be delivered header.
And then deliver the value to byteArrayToDeserializationException function.
Step into byteArrayToDeserializationException function.
The resolveClass function is overrided to restrain arbitrary Java class deserialization. Actually, we can find the way of preventing Java deserialization vulnerability in many projects, like Apache Shiro, Fastjson.
Apparently, only the class org.springframework.kafka.support.serializer.DeserializationException can be deserialized.
Step into DeserializationException function, it consists four arguments. One of them is cause which is used to invoke instantial class.
Write a malicious class and make it inherit the parent class Throwable.
Eventually, fill the value of the springDeserializerExceptionKey key in JSON data with the generated Java serialization. The remote code execution is trigged after send the HTTP request.