
An interesting
post appeared on the Apache FSF blog yesterday. Practically all software that uses serialization and deserialization of data together with apache commons collections and some other libraries turned out to be vulnerable.
The vulnerability itself
was described on November 6, and today Oracle
has released the first patches to WebLogic.
Briefly
Type : Remote code execution
Danger : high
Vulnerable software : Oracle WebLogic, IBM WebSphere, JBoss, Jenkins, OpenNMS, and other software with commons collections in the classpath.
Description : The vulnerability allows an attacker to create such a serialized data package, which, when unpacked, will force the vulnerable server to execute arbitrary code.
In detail
Data
- In Java, as in many other languages, there is a mechanism called serialization / deserialization, which turns a java object into a sequence of bytes and vice versa. It is used to transfer objects, for example via RMI or http cookie.
- In the commons collections library, there are a number of classes (* Transformer) that can be serialized.
- Under certain conditions, when deserializing InvokerTransformer can execute code
- The commons-collections library is used in a huge number of projects, including the application servers listed above.
- For operation, it is enough to have these classes in the classpath; it is not necessary to use it in your application.
Payload
I honestly copied this example from the original article and provided my own comments; they clearly show the essence of the problem.public InvocationHandler getObject(final String command) throws Exception { final String[] execArgs = new String[] { command }; final Transformer transformerChain = new ChainedTransformer( new Transformer[]{ new ConstantTransformer(1) }); final Transformer[] transformers = new Transformer[] { new ConstantTransformer(Runtime.class), new InvokerTransformer("getMethod", new Class[] { String.class, Class[].class }, new Object[] { "getRuntime", new Class[0] }), new InvokerTransformer("invoke", new Class[] { Object.class, Object[].class }, new Object[] { null, new Object[0] }), new InvokerTransformer("exec", new Class[] { String.class }, execArgs), new ConstantTransformer(1) }; final Map innerMap = new HashMap(); final Map lazyMap = LazyMap.decorate(innerMap, transformerChain); final Map mapProxy = Gadgets.createMemoitizedProxy(lazyMap, Map.class); final InvocationHandler handler = Gadgets.createMemoizedInvocationHandler(mapProxy); Reflections.setFieldValue(transformerChain, "iTransformers", transformers); return handler; }
The code generates an object whose deserialization will lead to the execution of the code.
The thing is how
InvokerTransformer is packaged, which, when unpacking the chain of transformers, will cause Runtime.getRuntime (). Exec (new String [] {command}), which will lead to code execution in the operating system.
')
Comment by
tbl :
InvokerTransformer does not have a default constructor, everything is more confusing: the PriorityQueue in readObject () has a call to the compare object, which is passed to the TransformerComparator instance, which in turn calls the transform () method of the transferred InvokerTransformer. And there already Method.invoke (), which is transmitted thrash, waste and sodomy, for example, Runtime.getRuntime (). Exec ().
So it’s not the default constructors that are to be looked for, but readObject (), which call interface methods, whose implementations are somewhere in the deep stack invoke ()For operation, it is enough to serialize the obtained object through java.io.ObjectOutputStream and transfer it using the protocol used.
Examples of operation are presented in the original article, PoC itself is
here .
Workaround
For successful operation, it is enough to find a remote service that accepts serialized data as input.
Potential vulnerabilities:
- HTTP requests - settings, cookies, ViewState's, headers, etc.
- RMI and RMI over HTTP
- Jmx
- Proprietary Protocols Transmitting Serialized Objects
To search for such objects in the traffic of your servers, you can use the sniffer and search for the byte sequence "
ac ed 00 05 73 72 ", which is the header of any serialized object. Do not forget that the object may be wrapped in base64 or other encoding, depending on the type of system. After finding the services that accept such objects, it is highly desirable to isolate them from the external network. Meanwhile, RedHat Security
offers to simply remove the “harmful” classes from the jar-files.
PS And it is better not to use serialization for external data, because no one knows how many more such "Transformers" exist.