Remote Code Execution (RCE) is a general vulnerability that can be exploited in many forms based upon the language and framework of choice. At the basic level, it allows an agent to run arbitrary code operations on the target machine/device. By having the ability to run arbitrary code on the target machine, the execution can assume the same privileges associated with the parent executor of that code, allowing for potential access of critical systems as well as its interconnects.c

Remote Code Execution (RCE) Impact

Remote code execution(RCE), allowing an attacker to run their program on the target device or platform and can have very severe ramifications. Some examples include running malware, exfiltration of sensitive data, carrying out distributed denial of service and destroying infrastructure. Some common RCE exploits use vulnerabilities within code including buffer overflow, deserialization, and type confusion.

Java Specific RCE Fixes

Consider a real-life example of apache struts:

public UserProfile loadUserProfile(Socket socket) {
  try(ObjectInputStream ois = new ObjectInputStream(socket.getInputStream())) {
    return (UserProfile) ois.readObject();
  }
}

by deserializing the socket input stream it allows for RCE. In the struts2-rest-plugin, the toObject directly calling XStream.fromXML without sanitizing the data.

Solution: To fix this vulnerability, it’s not possible to sanitize user input but the strategy was to add default permissions to allow types in XStream object. It was able to perform type filtering to allow sane defaults of primitives with the addDefaultPermissions method:

    protected void addDefaultPermissions(ActionInvocation invocation, XStream stream) {
        stream.addPermission(new ExplicitTypePermission(new Class[]{invocation.getAction().getClass()}));
        if (invocation.getAction() instanceof ModelDriven) {
            stream.addPermission(new ExplicitTypePermission(new Class[]{((ModelDriven) invocation.getAction()).getModel().getClass()}));
        }
        stream.addPermission(NullPermission.NULL);
        stream.addPermission(PrimitiveTypePermission.PRIMITIVES);
        stream.addPermission(ArrayTypePermission.ARRAYS);
        stream.addPermission(CollectionTypePermission.COLLECTIONS);
        stream.addPermission(new ExplicitTypePermission(new Class[]{Date.class}));
    }

More details can be seen here: Git commit for 2.5.x

As a general rule, audit all java code for execution paths e.g. CreateProcess() or ProcessBuilder(), and validate that arguments to these methods are not user-defined or manipulated. In general detection and fixes to RCE are very complex. As a general rule it NOT enough to:

  • sanitize user-inputs, either by whitelisting or blacklist inputs/characters
  • prevent users from defining file extensions

RCE Tales

Sierra Wireless: RCE in Sierra Wireless AirLink ES450 LTE gateway
Microsoft Excel: RCE in Microsoft’s Excel
Microsoft Server: Microsoft’s Server Message Block (SMB)
WannaCry: WannaCry and Microsoft’s SMB

References

GitHub Cisco-AMP: Remote Code Execution for Java Developers
GitHub Shawn McKinney: How Java Security Manager can prevent RCE

Thanks for reading 🙂

Want to check your projects for free?