diff --git a/data/java/com/metasploit/meterpreter/MemoryBufferURLConnection.class b/data/java/com/metasploit/meterpreter/MemoryBufferURLConnection.class index 19a15befbc..47a3eb1368 100644 Binary files a/data/java/com/metasploit/meterpreter/MemoryBufferURLConnection.class and b/data/java/com/metasploit/meterpreter/MemoryBufferURLConnection.class differ diff --git a/data/java/com/metasploit/meterpreter/MemoryBufferURLStreamHandler.class b/data/java/com/metasploit/meterpreter/MemoryBufferURLStreamHandler.class index e0a4a3137f..dbe896602f 100644 Binary files a/data/java/com/metasploit/meterpreter/MemoryBufferURLStreamHandler.class and b/data/java/com/metasploit/meterpreter/MemoryBufferURLStreamHandler.class differ diff --git a/data/java/metasploit/Payload.class b/data/java/metasploit/Payload.class index 5555166bbc..cf7661a289 100644 Binary files a/data/java/metasploit/Payload.class and b/data/java/metasploit/Payload.class differ diff --git a/data/java/metasploit/PayloadServlet.class b/data/java/metasploit/PayloadServlet.class index 335a9e1fb6..00e4e00e0d 100644 Binary files a/data/java/metasploit/PayloadServlet.class and b/data/java/metasploit/PayloadServlet.class differ diff --git a/external/source/javapayload/JavaPayload4Meterpreter.jar b/external/source/javapayload/JavaPayload4Meterpreter.jar deleted file mode 100644 index 173be1a851..0000000000 Binary files a/external/source/javapayload/JavaPayload4Meterpreter.jar and /dev/null differ diff --git a/external/source/javapayload/build.xml b/external/source/javapayload/build.xml index 3ae7b4212d..4c9f2f9ae1 100644 --- a/external/source/javapayload/build.xml +++ b/external/source/javapayload/build.xml @@ -7,7 +7,7 @@ - + @@ -65,4 +65,14 @@ + + + + + + + + + + diff --git a/external/source/javapayload/lib/servlet-api-2.2.jar b/external/source/javapayload/lib/servlet-api-2.2.jar new file mode 100644 index 0000000000..86f4aa543b Binary files /dev/null and b/external/source/javapayload/lib/servlet-api-2.2.jar differ diff --git a/external/source/javapayload/src/com/metasploit/meterpreter/MemoryBufferURLConnection.java b/external/source/javapayload/src/com/metasploit/meterpreter/MemoryBufferURLConnection.java index 7548421e99..d687aeff31 100644 --- a/external/source/javapayload/src/com/metasploit/meterpreter/MemoryBufferURLConnection.java +++ b/external/source/javapayload/src/com/metasploit/meterpreter/MemoryBufferURLConnection.java @@ -8,8 +8,8 @@ import java.net.MalformedURLException; import java.net.URL; import java.net.URLConnection; import java.util.ArrayList; -import java.util.Hashtable; import java.util.List; +import java.util.Map; /** * An {@link URLConnection} for an URL that is stored completely in memory. @@ -23,10 +23,42 @@ public class MemoryBufferURLConnection extends URLConnection { static { // tweak the cache of already loaded protocol handlers via reflection try { - Field fld = URL.class.getDeclaredField("handlers"); + Field fld; + try { + fld = URL.class.getDeclaredField("handlers"); + } catch (NoSuchFieldException ex) { + try { + // GNU Classpath (libgcj) calls this field differently + fld = URL.class.getDeclaredField("ph_cache"); + } catch (NoSuchFieldException ex2) { + // throw the original exception + throw ex; + } + } fld.setAccessible(true); - Hashtable handlers = (Hashtable) fld.get(null); - handlers.put("metasploitmembuff", new MemoryBufferURLStreamHandler()); + Map handlers = (Map) fld.get(null); + // Note that although this is a static initializer, it can happen + // that two threads are entering this spot at the same time: When + // there is more than one classloader context (e. g. in a servlet + // container with Spawn=0) and more than one of them is loading + // a copy of this class at the same time. Work around this by + // letting all of them use the same URL stream handler object. + synchronized(handlers) { + // do not use the "real" class name here as the same class + // loaded in different classloader contexts is not the same + // one for Java -> ClassCastException + Object /*MemoryBufferURLStreamHandler*/ handler; + + if (handlers.containsKey("metasploitmembuff")) { + handler = handlers.get("metasploitmembuff"); + } else { + handler = new MemoryBufferURLStreamHandler(); + handlers.put("metasploitmembuff", handler); + } + + // for the same reason, use reflection to obtain the files List + files = (List) handler.getClass().getMethod("getFiles", new Class[0]).invoke(handler, new Object[0]); + } } catch (Exception ex) { throw new RuntimeException(ex.toString()); } @@ -36,8 +68,10 @@ public class MemoryBufferURLConnection extends URLConnection { * Create a new URL from a byte array and its content type. */ public static URL createURL(byte[] data, String contentType) throws MalformedURLException { - files.add(data); - return new URL("metasploitmembuff", "", (files.size() - 1) + "/" + contentType); + synchronized(files) { + files.add(data); + return new URL("metasploitmembuff", "", (files.size() - 1) + "/" + contentType); + } } private final byte[] data; @@ -47,7 +81,9 @@ public class MemoryBufferURLConnection extends URLConnection { super(url); String file = url.getFile(); int pos = file.indexOf('/'); - data = (byte[]) files.get(Integer.parseInt(file.substring(0, pos))); + synchronized (files) { + data = (byte[]) files.get(Integer.parseInt(file.substring(0, pos))); + } contentType = file.substring(pos + 1); } diff --git a/external/source/javapayload/src/com/metasploit/meterpreter/MemoryBufferURLStreamHandler.java b/external/source/javapayload/src/com/metasploit/meterpreter/MemoryBufferURLStreamHandler.java index 99757cce2d..b0c50f90ea 100644 --- a/external/source/javapayload/src/com/metasploit/meterpreter/MemoryBufferURLStreamHandler.java +++ b/external/source/javapayload/src/com/metasploit/meterpreter/MemoryBufferURLStreamHandler.java @@ -4,6 +4,8 @@ import java.io.IOException; import java.net.URL; import java.net.URLConnection; import java.net.URLStreamHandler; +import java.util.ArrayList; +import java.util.List; /** * An {@link URLStreamHandler} for a {@link MemoryBufferURLConnection} @@ -11,7 +13,14 @@ import java.net.URLStreamHandler; * @author mihi */ public class MemoryBufferURLStreamHandler extends URLStreamHandler { + + private List files = new ArrayList(); + protected URLConnection openConnection(URL u) throws IOException { return new MemoryBufferURLConnection(u); } + + public List getFiles() { + return files; + } }