You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository has been archived by the owner on Aug 10, 2022. It is now read-only.
(after discussing the issue with the project maintainers, agreed to publish the details to make users aware of unsafe RMI deserialization in RemoteEngine)
I noticed that Weka offers a remote object via RMI:
RMI uses the default Java serialization mechanism to pass parameters in RMI invocations. A remote attacker can send a malicious serialized object to the above RMI entries. The objects get deserialized without any check on the incoming data. In the worst case, it may let the attacker run arbitrary code remotely. You can find more details about this attack in the following articles
Unfortunately, I don't see any easy way to fix it because RMI does not allow restricting classes for deserialization. The only idea I have is to set a process-wide filter for deserialization, see JEP 290:
As an example, I am attaching DeserializationConfig that helps to set the filter. The method DeserializationConfig.setDeserializationFilterIfNecessary() has to be called before accessing the default serialization mechanism in the JVM. It is important because the filter is loaded only once when the JVM loads classes which implement the default deserialization mechanism (ObjectInputStream and others). For example, you can call the method in the beginning of main(). Or, maybe you can just delete RemoteEngine.
importjava.security.Security;
/** * This class helps to configure deserialization. */publicclassDeserializationConfig {
/** * This filter specifies classes that are allowed for deserialization in RMI communications. * * @see <a href="http://openjdk.java.net/jeps/290">JEP 290: Filter Incoming Serialization Data</a> */privatestaticfinalStringDEFAULT_DESERIALIZATION_FILTER = String.join(";",
"weka.**",
"java.lang.Boolean", "java.lang.Byte", "java.lang.Character", "java.lang.Double", "java.lang.Enum",
"java.lang.Float", "java.lang.Integer", "java.lang.Long", "java.lang.Number", "java.lang.Object",
"java.lang.Short",
"java.util.*",
"!*"
);
/** * Returns a process-wide deserialization filter. */privatestaticStringgetSerialFilter() {
Stringfilter = System.getProperty("jdk.serialFilter");
if (filter != null) {
returnfilter;
}
returnSecurity.getProperty("jdk.serialFilter");
}
/** * Sets a process-wide deserialization filter if it is not already set. */publicstaticvoidsetDeserializationFilterIfNecessary() {
Stringfilter = getSerialFilter();
if (filter == null) {
System.out.printf("Use the following filter for deserialization:%n%s%n", DEFAULT_DESERIALIZATION_FILTER);
System.setProperty("jdk.serialFilter", DEFAULT_DESERIALIZATION_FILTER);
}
}
}
The text was updated successfully, but these errors were encountered:
(after discussing the issue with the project maintainers, agreed to publish the details to make users aware of unsafe RMI deserialization in
RemoteEngine
)I noticed that Weka offers a remote object via RMI:
weka-trunk/weka/src/main/java/weka/experiment/RemoteEngine.java
Line 367 in 7ab9c43
The remote object has methods with not-primitive parameters:
RMI uses the default Java serialization mechanism to pass parameters in RMI invocations. A remote attacker can send a malicious serialized object to the above RMI entries. The objects get deserialized without any check on the incoming data. In the worst case, it may let the attacker run arbitrary code remotely. You can find more details about this attack in the following articles
https://mogwailabs.de/en/blog/2019/03/attacking-java-rmi-services-after-jep-290/
https://itnext.io/java-rmi-for-pentesters-part-two-reconnaissance-attack-against-non-jmx-registries-187a6561314d
Unfortunately, I don't see any easy way to fix it because RMI does not allow restricting classes for deserialization. The only idea I have is to set a process-wide filter for deserialization, see JEP 290:
http://openjdk.java.net/jeps/290
As an example, I am attaching
DeserializationConfig
that helps to set the filter. The methodDeserializationConfig.setDeserializationFilterIfNecessary()
has to be called before accessing the default serialization mechanism in the JVM. It is important because the filter is loaded only once when the JVM loads classes which implement the default deserialization mechanism (ObjectInputStream
and others). For example, you can call the method in the beginning ofmain()
. Or, maybe you can just deleteRemoteEngine
.The text was updated successfully, but these errors were encountered: