1
mirror of https://github.com/rapid7/metasploit-payloads synced 2025-04-18 07:11:12 +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>
<artifactId>Metasploit-Java-Shared</artifactId>
<version>${project.version}</version>
<scope>provided</scope>
</dependency>
</dependencies>
<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="${project.basedir}/../app/target/classes" />
<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-stdapi: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_net_socket_tcp_shutdown_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.File;
@ -126,9 +127,8 @@ public class AndroidMeterpreter extends Meterpreter {
} catch (Exception e) {
e.printStackTrace();
}
if (parameters.length > 1 && parameters[1].charAt(0) != ' ') {
byte[] configBytes = Utils.hexStringToByteArray(parameters[1]);
loadConfiguration(in, rawOut, configBytes);
if (Payload.configBytes[0] != 0) {
loadConfiguration(in, rawOut, Payload.configBytes);
} else {
int configLen = in.readInt();
byte[] configBytes = new byte[configLen];

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

@ -30,9 +30,6 @@ import com.metasploit.meterpreter.core.core_loadlib;
*/
public class Meterpreter {
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 Random rnd = new Random();
@ -46,27 +43,28 @@ public class Meterpreter {
protected int ignoreBlocks = 0;
private byte[] uuid;
private long sessionExpiry;
private ConfigParser configParser;
protected 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));
setExpiry(ConfigParser.unpack32(configuration, csr));
csr += 4;
// this is followed with the UUID
this.uuid = readBytes(configuration, csr, UUID_LEN);
csr += UUID_LEN;
this.uuid = ConfigParser.readBytes(configuration, csr, ConfigParser.UUID_LEN);
csr += ConfigParser.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;
String url = ConfigParser.readString(configuration, csr, ConfigParser.URL_LEN);
csr += ConfigParser.URL_LEN;
Transport t = null;
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.
*

@ -33,15 +33,15 @@ public abstract class Transport {
protected int parseTimeouts(byte[] configuration, int offset) {
// starts with the comms timeout
this.commTimeout = MS * Meterpreter.unpack32(configuration, offset);
this.commTimeout = MS * ConfigParser.unpack32(configuration, offset);
offset += 4;
// then we have the retry total
this.retryTotal = MS * Meterpreter.unpack32(configuration, offset);
this.retryTotal = MS * ConfigParser.unpack32(configuration, offset);
offset += 4;
// then we have the retry wait
this.retryWait = MS * Meterpreter.unpack32(configuration, offset);
this.retryWait = MS * ConfigParser.unpack32(configuration, offset);
offset += 4;
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.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Arrays;
/**
* 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 {
private String certHash;
private byte[] certHash;
private PayloadTrustManager(String certHash) {
private PayloadTrustManager(byte[] certHash) {
this.certHash = certHash;
}
@ -67,21 +68,11 @@ public class PayloadTrustManager implements X509TrustManager, HostnameVerifier {
return new X509Certificate[0];
}
public static String getCertificateSHA1(X509Certificate cert)
public static byte[] getCertificateSHA1(X509Certificate cert)
throws NoSuchAlgorithmException, CertificateEncodingException {
MessageDigest md = MessageDigest.getInstance("SHA-1");
md.update(cert.getEncoded());
return bytesToHex(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();
return md.digest();
}
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
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) {
throw new CertificateException();
}
for (X509Certificate certificate : certs) {
try {
String serverHash = getCertificateSHA1(certificate);
if (!serverHash.equals(payloadHash)) {
byte[] serverHash = getCertificateSHA1(certificate);
if (!Arrays.equals(certHash, serverHash)) {
throw new CertificateException("Invalid certificate");
}
} catch (Exception e) {
@ -125,7 +111,7 @@ public class PayloadTrustManager implements X509TrustManager, HostnameVerifier {
* Called by the Payload class to modify the given
* {@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) {
HttpsURLConnection huc = ((HttpsURLConnection) uc);
PayloadTrustManager ptm = new PayloadTrustManager(certHash);