Java deserialization vulnerability in SerializationSessionDataTranscoder.decode()
idealzh opened this issue · 2 comments
To get a SessionData object from cookie,pippo base64 decode the PIPPO_SESSION,and then deserialize the decoded data(the decoded data is a serialized SessionData object);
However,ObjectInputStream.readObject() leads to a Java deserialization vulnerability.
The Apache Shiro framework used to have a similar issue(https://issues.apache.org/jira/browse/SHIRO-550).
There exists a gadget chain in jre8u20,we can generate the attack payload based on it;Here is a blog(https://www.anquanke.com/post/id/87270) about the generating procedure,I am sorry it's writed in Chinese,or get the payload by tool(https://github.com/360-A-Team/SerialWriter) ;So,if the version lowwer than jre8u20,it may leads to a remote code execution;
For details,please refer to the picture below:
The payload I used is as follows:
jre8u20payload_base64.txt
And some third party modules also have a gadget chain;
To fix the issue,we can implement a class FilteringObjectInputStream,and replace ObjectInputStream with it,The implementation of FilterObjectInputStream is as follows:
public class FilteringObjectInputStream extends ObjectInputStream {
public FilteringObjectInputStream(InputStream in) throws IOException {
super(in);
}
protected Class<?> resolveClass(java.io.ObjectStreamClass descriptor) throws ClassNotFoundException, IOException {
String className = descriptor.getName();
ClassFilter classFilter=new ClassFilter();
if(className != null && className.length() > 0 && !classFilter.isWhiteListed(className)) {
throw new InvalidClassException("Unauthorized deserialization attempt", descriptor.getName());
} else {
return super.resolveClass(descriptor);
}
}
}
public class ClassFilter {
private ArrayList<String> WhiteList= null;
public ClassFilter() {
WhiteList=new ArrayList<String>();
WhiteList.add("ro.pippo.session.SessionData");
WhiteList.add("java.util.HashMap");
WhiteList.add("ro.pippo.core.Flash");
WhiteList.add("java.util.ArrayList");
}
public boolean isWhiteListed(String className) {
if(className==null) return false;
for(String name:WhiteList) {
if(name.equals(className)) return true;
}
return false;
}
}
It's just a demo.
There is now a CVE for this: https://nvd.nist.gov/vuln/detail/CVE-2018-18628