Class DGCClient


  • public class DGCClient
    extends Object
    The distributed garbage collector (DGC) is a well known RMI object with publicly known method definitions. In the early days of RMI, the DGC was the prime target for attackers and most attacks like codebase or deserialization exploits targeted methods exposed by the DGC. Today, the DGC is probably one of the most locked down RMI interfaces. It implements a very strict deserialization filter for incoming and outgoing calls, enables useCodebaseOnly internally, which overwrites the user settings and uses a separate AccessControlContext that denies basically everything apart from accepting connections. Nonetheless, it is may desired to test DGC protections during security assessments to identify vulnerabilities on outdated RMI endpoints or custom implementations. Therefore, DGC support was also implemented for rmg.
    Author:
    Tobias Neitzel (@qtc_de)
    • Constructor Detail

      • DGCClient

        public DGCClient​(RMIEndpoint rmiEndpoint)
        Create a new DGCClient.
        Parameters:
        rmiEndpoint - associated RMIEndpoint.
    • Method Detail

      • enumSecurityManager

        public void enumSecurityManager​(String callName)
        The enumSecurityManager uses the DGC endpoint to check for an Security Manager. It does so by sending a class unknown to the remote server within a DGC call. If the server runs without a Security Manager, it will reject class loading and inform the caller about the missing Security Manager within the raised exception. If a Security Manager is in use, the DGC should raise an UnmarshalException that contains the ClassNotFoundException as its cause. During the RMI call, the enumSecurityManager function sets an invalid URL as client side codebase. However, modern DGC implementations set useCodebaseOnly to false internally and do not respect user defined settings for this property. Remote class loading is therefore always disabled on modern DGC endpoints. Getting an UnmarshalException containing a plain ClassNotFoundException is therefore the most common behavior when a Security Manager is in use. If the remote server specifies a codebase value on its own, we may also encounter a ClassNotFoundException that contains 'access to class loader denied' within the Exception text. This is caused by the separate AccessControlContext that is used by the DGC. Since the codebase is defined by the server itself, useCodebaseOnly=true does not matter here and the DGC attempts to load the unknown class from the server specified codebase. However, due to the separate and more restrictive AccessControlContext, the Security Manager prevents the DGC from accessing the locally defined codebase. Therefore, this behavior is expected for RMI servers that use a Security Manager and set an RMI codebase locally. On really old RMI servers you may also obtain a MalformedURLException. This indicates that the server uses a Security Manager and that useCodebaseOnly is set to false. Since useCodebaseOnly is set to false automatically for modern DGC implementations, this always indicates that server is outdated. Furthermore, it may be possible to perform remote class loading attacks on it.
        Parameters:
        callName - DGC call to use for the enumeration
      • enumJEP290

        public void enumJEP290​(String callName)
        Checks for deserialization filters on the DGC endpoint. This is pretty straight forward. Just sends a java.util.HashMap during a DGC call and checks whether the class is rejected.
        Parameters:
        callName - the DGC call to use for the operation (clean|dirty)
      • codebaseCall

        public void codebaseCall​(String callName,
                                 Object payloadObject)
        Invokes a DGC method with a user controlled codebase as class annotation. The codebase is already set by the ArgumentParser during the startup of the program. This method was never successfully tested, as it is difficult to find a Java version that is still vulnerable to this :D
        Parameters:
        callName - the DGC call to use for the operation (clean|dirty)
        payloadObject - object to use during the codebase call
      • gadgetCall

        public void gadgetCall​(String callName,
                               Object payloadObject)
        Invokes a DGC call with a user controlled payload object (usually a gadget created by ysoserial).
        Parameters:
        callName - the DGC call to use for the operation (clean|dirty)
        payloadObject - object to use during the DGC call