1
mirror of https://github.com/rapid7/metasploit-payloads synced 2025-04-30 13:07:22 +02:00

store Payload config as byte array

This commit is contained in:
Tim 2016-09-30 16:21:50 +08:00
parent 92a598101f
commit d6cd73e2bc
No known key found for this signature in database
GPG Key ID: 62361A8B17EEED19
9 changed files with 113 additions and 110 deletions
java
androidpayload
app
pom.xml
src/com/metasploit/stage
library
pom.xml
src/com/metasploit/meterpreter
meterpreter
meterpreter/src/main/java/com/metasploit/meterpreter
shared/src/main/java/com/metasploit/meterpreter

@ -21,7 +21,6 @@
<groupId>com.metasploit</groupId> <groupId>com.metasploit</groupId>
<artifactId>Metasploit-Java-Shared</artifactId> <artifactId>Metasploit-Java-Shared</artifactId>
<version>${project.version}</version> <version>${project.version}</version>
<scope>provided</scope>
</dependency> </dependency>
</dependencies> </dependencies>
<build> <build>

File diff suppressed because one or more lines are too long

@ -153,6 +153,7 @@
<arg value="--output=${project.basedir}/../../${deploy.path}/data/android/meterpreter.dex" /> <arg value="--output=${project.basedir}/../../${deploy.path}/data/android/meterpreter.dex" />
<arg value="${project.basedir}/../app/target/classes" /> <arg value="${project.basedir}/../app/target/classes" />
<arg value="${project.basedir}/target/dx/meterpreter" /> <arg value="${project.basedir}/target/dx/meterpreter" />
<arg value="${com.metasploit:Metasploit-Java-Shared:jar}" />
<arg value="${com.metasploit:Metasploit-Java-Meterpreter:jar}" /> <arg value="${com.metasploit:Metasploit-Java-Meterpreter:jar}" />
<arg value="${com.metasploit:Metasploit-Java-Meterpreter-stdapi:jar}" /> <arg value="${com.metasploit:Metasploit-Java-Meterpreter-stdapi:jar}" />
<arg value="${com.metasploit:Metasploit-JavaPayload:jar}" /> <arg value="${com.metasploit:Metasploit-JavaPayload:jar}" />

@ -54,6 +54,7 @@ import com.metasploit.meterpreter.stdapi.stdapi_net_config_get_routes_V1_4;
import com.metasploit.meterpreter.stdapi.stdapi_sys_config_localtime; import com.metasploit.meterpreter.stdapi.stdapi_sys_config_localtime;
import com.metasploit.meterpreter.stdapi.stdapi_net_socket_tcp_shutdown_V1_3; import com.metasploit.meterpreter.stdapi.stdapi_net_socket_tcp_shutdown_V1_3;
import com.metasploit.meterpreter.stdapi.stdapi_sys_process_execute_V1_3; import com.metasploit.meterpreter.stdapi.stdapi_sys_process_execute_V1_3;
import com.metasploit.stage.Payload;
import java.io.DataInputStream; import java.io.DataInputStream;
import java.io.File; import java.io.File;
@ -126,9 +127,8 @@ public class AndroidMeterpreter extends Meterpreter {
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
if (parameters.length > 1 && parameters[1].charAt(0) != ' ') { if (Payload.configBytes[0] != 0) {
byte[] configBytes = Utils.hexStringToByteArray(parameters[1]); loadConfiguration(in, rawOut, Payload.configBytes);
loadConfiguration(in, rawOut, configBytes);
} else { } else {
int configLen = in.readInt(); int configLen = in.readInt();
byte[] configBytes = new byte[configLen]; byte[] configBytes = new byte[configLen];

@ -12,11 +12,6 @@ import java.net.URL;
import java.net.URLConnection; import java.net.URLConnection;
public class HttpTransport extends Transport { 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 URL targetUrl = null; private URL targetUrl = null;
private URL nextUrl = null; private URL nextUrl = null;
@ -54,21 +49,21 @@ public class HttpTransport extends Transport {
public int parseConfig(byte[] configuration, int offset) { public int parseConfig(byte[] configuration, int offset) {
offset = this.parseTimeouts(configuration, offset); offset = this.parseTimeouts(configuration, offset);
this.proxy = Meterpreter.readString(configuration, offset, PROXY_HOST_LEN); this.proxy = ConfigParser.readString(configuration, offset, ConfigParser.PROXY_HOST_LEN);
offset += PROXY_HOST_LEN; offset += ConfigParser.PROXY_HOST_LEN;
this.proxyUser = Meterpreter.readString(configuration, offset, PROXY_USER_LEN); this.proxyUser = ConfigParser.readString(configuration, offset, ConfigParser.PROXY_USER_LEN);
offset += PROXY_USER_LEN; offset += ConfigParser.PROXY_USER_LEN;
this.proxyPass = Meterpreter.readString(configuration, offset, PROXY_PASS_LEN); this.proxyPass = ConfigParser.readString(configuration, offset, ConfigParser.PROXY_PASS_LEN);
offset += PROXY_PASS_LEN; offset += ConfigParser.PROXY_PASS_LEN;
this.userAgent = Meterpreter.readString(configuration, offset, UA_LEN); this.userAgent = ConfigParser.readString(configuration, offset, ConfigParser.UA_LEN);
offset += UA_LEN; offset += ConfigParser.UA_LEN;
this.certHash = null; this.certHash = null;
byte[] loadedHash = Meterpreter.readBytes(configuration, offset, CERT_HASH_LEN); byte[] loadedHash = ConfigParser.readBytes(configuration, offset, ConfigParser.CERT_HASH_LEN);
offset += CERT_HASH_LEN; offset += ConfigParser.CERT_HASH_LEN;
// we only store the cert hash value if it's got a value // we only store the cert hash value if it's got a value
for (int i = 0; i < loadedHash.length; i++) { for (int i = 0; i < loadedHash.length; i++) {
@ -263,11 +258,7 @@ public class HttpTransport extends Transport {
if (this.targetUrl.getProtocol().equals("https")) { if (this.targetUrl.getProtocol().equals("https")) {
try { try {
String certHashHex = null; PayloadTrustManager.useFor(conn, certHash);
if (certHash != null) {
certHashHex = PayloadTrustManager.bytesToHex(certHash);
}
PayloadTrustManager.useFor(conn, certHashHex);
} catch (Exception ex) { } catch (Exception ex) {
// perhaps log? // perhaps log?
} }

@ -30,9 +30,6 @@ import com.metasploit.meterpreter.core.core_loadlib;
*/ */
public class Meterpreter { public class Meterpreter {
public static final int UUID_LEN = 16;
public static final int URL_LEN = 512;
private List/* <Channel> */channels = new ArrayList(); private List/* <Channel> */channels = new ArrayList();
private final CommandManager commandManager; private final CommandManager commandManager;
private final Random rnd = new Random(); private final Random rnd = new Random();
@ -46,27 +43,28 @@ public class Meterpreter {
protected int ignoreBlocks = 0; protected int ignoreBlocks = 0;
private byte[] uuid; private byte[] uuid;
private long sessionExpiry; private long sessionExpiry;
private ConfigParser configParser;
protected void loadConfiguration(DataInputStream in, OutputStream rawOut, byte[] configuration) throws MalformedURLException { protected void loadConfiguration(DataInputStream in, OutputStream rawOut, byte[] configuration) throws MalformedURLException {
// socket handle is 4 bytes, followed by exit func, both of // socket handle is 4 bytes, followed by exit func, both of
// which we ignore. // which we ignore.
int csr = 8; int csr = 8;
// We start with the expiry, which is a 32 bit int // We start with the expiry, which is a 32 bit int
setExpiry(unpack32(configuration, csr)); setExpiry(ConfigParser.unpack32(configuration, csr));
csr += 4; csr += 4;
// this is followed with the UUID // this is followed with the UUID
this.uuid = readBytes(configuration, csr, UUID_LEN); this.uuid = ConfigParser.readBytes(configuration, csr, ConfigParser.UUID_LEN);
csr += UUID_LEN; csr += ConfigParser.UUID_LEN;
// here we need to loop through all the given transports, we know that we're // here we need to loop through all the given transports, we know that we're
// going to get at least one. // going to get at least one.
while (configuration[csr] != '\0') { while (configuration[csr] != '\0') {
// read the transport URL // read the transport URL
String url = readString(configuration, csr, URL_LEN); String url = ConfigParser.readString(configuration, csr, ConfigParser.URL_LEN);
csr += URL_LEN; csr += ConfigParser.URL_LEN;
Transport t = null; Transport t = null;
if (url.startsWith("tcp")) { if (url.startsWith("tcp")) {
@ -110,31 +108,6 @@ public class Meterpreter {
} }
} }
public static String readString(byte[] bytes, int offset, int size) {
byte[] bytesRead = readBytes(bytes, offset, size);
try {
return new String(bytesRead, "ISO-8859-1").trim();
}
catch (UnsupportedEncodingException ex) {
// fallback to no encoding
return new String(bytesRead).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. * Initialize the meterpreter.
* *

@ -33,15 +33,15 @@ public abstract class Transport {
protected int parseTimeouts(byte[] configuration, int offset) { protected int parseTimeouts(byte[] configuration, int offset) {
// starts with the comms timeout // starts with the comms timeout
this.commTimeout = MS * Meterpreter.unpack32(configuration, offset); this.commTimeout = MS * ConfigParser.unpack32(configuration, offset);
offset += 4; offset += 4;
// then we have the retry total // then we have the retry total
this.retryTotal = MS * Meterpreter.unpack32(configuration, offset); this.retryTotal = MS * ConfigParser.unpack32(configuration, offset);
offset += 4; offset += 4;
// then we have the retry wait // then we have the retry wait
this.retryWait = MS * Meterpreter.unpack32(configuration, offset); this.retryWait = MS * ConfigParser.unpack32(configuration, offset);
offset += 4; offset += 4;
return offset; return offset;

@ -0,0 +1,41 @@
package com.metasploit.meterpreter;
import java.io.UnsupportedEncodingException;
public class ConfigParser {
public static final int UUID_LEN = 16;
public static final int URL_LEN = 512;
public static final int UA_LEN = 256;
public static final int PROXY_HOST_LEN = 128;
public static final int PROXY_USER_LEN = 64;
public static final int PROXY_PASS_LEN = 64;
public static final int CERT_HASH_LEN = 20;
public static String readString(byte[] bytes, int offset, int size) {
byte[] bytesRead = readBytes(bytes, offset, size);
try {
return new String(bytesRead, "ISO-8859-1").trim();
}
catch (UnsupportedEncodingException ex) {
// fallback to no encoding
return new String(bytesRead).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;
}
}

@ -47,6 +47,7 @@ import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateEncodingException; import java.security.cert.CertificateEncodingException;
import java.security.cert.CertificateException; import java.security.cert.CertificateException;
import java.security.cert.X509Certificate; import java.security.cert.X509Certificate;
import java.util.Arrays;
/** /**
* Trust manager used for HTTPS stagers. This is in its own class because it * Trust manager used for HTTPS stagers. This is in its own class because it
@ -56,9 +57,9 @@ import java.security.cert.X509Certificate;
*/ */
public class PayloadTrustManager implements X509TrustManager, HostnameVerifier { public class PayloadTrustManager implements X509TrustManager, HostnameVerifier {
private String certHash; private byte[] certHash;
private PayloadTrustManager(String certHash) { private PayloadTrustManager(byte[] certHash) {
this.certHash = certHash; this.certHash = certHash;
} }
@ -67,21 +68,11 @@ public class PayloadTrustManager implements X509TrustManager, HostnameVerifier {
return new X509Certificate[0]; return new X509Certificate[0];
} }
public static String getCertificateSHA1(X509Certificate cert) public static byte[] getCertificateSHA1(X509Certificate cert)
throws NoSuchAlgorithmException, CertificateEncodingException { throws NoSuchAlgorithmException, CertificateEncodingException {
MessageDigest md = MessageDigest.getInstance("SHA-1"); MessageDigest md = MessageDigest.getInstance("SHA-1");
md.update(cert.getEncoded()); md.update(cert.getEncoded());
return bytesToHex(md.digest()); return md.digest();
}
public static String bytesToHex(byte bytes[]) {
char[] hexDigits = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
StringBuilder buf = new StringBuilder(bytes.length * 2);
for (byte aByte : bytes) {
buf.append(hexDigits[(aByte & 0xf0) >> 4]);
buf.append(hexDigits[aByte & 0x0f]);
}
return buf.toString();
} }
public void checkClientTrusted(java.security.cert.X509Certificate[] certs, public void checkClientTrusted(java.security.cert.X509Certificate[] certs,
@ -96,18 +87,13 @@ public class PayloadTrustManager implements X509TrustManager, HostnameVerifier {
// No HandlerSSLCert set on payload, trust everyone // No HandlerSSLCert set on payload, trust everyone
return; return;
} }
String payloadHash = certHash.substring(4).trim();
if (payloadHash.length() == 0) {
// No HandlerSSLCert set on payload, trust everyone
return;
}
if (certs == null || certs.length < 1) { if (certs == null || certs.length < 1) {
throw new CertificateException(); throw new CertificateException();
} }
for (X509Certificate certificate : certs) { for (X509Certificate certificate : certs) {
try { try {
String serverHash = getCertificateSHA1(certificate); byte[] serverHash = getCertificateSHA1(certificate);
if (!serverHash.equals(payloadHash)) { if (!Arrays.equals(certHash, serverHash)) {
throw new CertificateException("Invalid certificate"); throw new CertificateException("Invalid certificate");
} }
} catch (Exception e) { } catch (Exception e) {
@ -125,7 +111,7 @@ public class PayloadTrustManager implements X509TrustManager, HostnameVerifier {
* Called by the Payload class to modify the given * Called by the Payload class to modify the given
* {@link URLConnection} so that it uses this trust manager. * {@link URLConnection} so that it uses this trust manager.
*/ */
public static void useFor(URLConnection uc, String certHash) throws Exception { public static void useFor(URLConnection uc, byte[] certHash) throws Exception {
if (uc instanceof HttpsURLConnection) { if (uc instanceof HttpsURLConnection) {
HttpsURLConnection huc = ((HttpsURLConnection) uc); HttpsURLConnection huc = ((HttpsURLConnection) uc);
PayloadTrustManager ptm = new PayloadTrustManager(certHash); PayloadTrustManager ptm = new PayloadTrustManager(certHash);