|
@@ -1,10 +1,19 @@
|
|
|
package de.tudarmstadt.informatik.hostage.system;
|
|
|
|
|
|
+import java.io.BufferedReader;
|
|
|
+import java.io.File;
|
|
|
+import java.io.FileNotFoundException;
|
|
|
+import java.io.FileOutputStream;
|
|
|
import java.io.IOException;
|
|
|
+import java.io.InputStream;
|
|
|
+import java.io.InputStreamReader;
|
|
|
+import java.io.OutputStream;
|
|
|
|
|
|
+import android.app.Activity;
|
|
|
import android.util.Log;
|
|
|
|
|
|
import de.tudarmstadt.informatik.hostage.commons.HelperUtils;
|
|
|
+import de.tudarmstadt.informatik.hostage.ui.activity.MainActivity;
|
|
|
|
|
|
|
|
|
public class Device {
|
|
@@ -21,7 +30,7 @@ public class Device {
|
|
|
porthack = false;
|
|
|
iptables = false;
|
|
|
|
|
|
- porthackFilepath = HelperUtils.getPorthackFilepath();
|
|
|
+ porthackFilepath = getPorthackFilepath();
|
|
|
String porthackExists = "[ -e "+porthackFilepath+" ]"; // checks existence of porthack
|
|
|
|
|
|
try {
|
|
@@ -80,4 +89,142 @@ public class Device {
|
|
|
assert(initialized);
|
|
|
return iptables;
|
|
|
}
|
|
|
+ /**
|
|
|
+ * copies an asset to the local filesystem for later usage
|
|
|
+ * (used for port hack and shell scripts)
|
|
|
+ * @param assetFilePath
|
|
|
+ * @param destFilePath
|
|
|
+ * @return true on success
|
|
|
+ */
|
|
|
+ private static boolean deployAsset(String assetFilePath, String destFilePath) {
|
|
|
+ Activity activity = MainActivity.getInstance();
|
|
|
+ File file = new File(activity.getFilesDir(), destFilePath);
|
|
|
+ try {
|
|
|
+ OutputStream os = new FileOutputStream(file);
|
|
|
+ try {
|
|
|
+ InputStream is = activity.getAssets().open(assetFilePath);
|
|
|
+ byte[] buffer = new byte[4096];
|
|
|
+ int bytesRead;
|
|
|
+ while ((bytesRead = is.read(buffer)) != -1) {
|
|
|
+ os.write(buffer, 0, bytesRead);
|
|
|
+ }
|
|
|
+ is.close();
|
|
|
+ } catch (IOException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ os.close();
|
|
|
+ } catch (FileNotFoundException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ return false;
|
|
|
+ } catch (IOException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ //Log.i("FILEPATH", file.getAbsolutePath());
|
|
|
+ return true; // SUCCESS!
|
|
|
+ }
|
|
|
+
|
|
|
+ public static void executePortRedirectionScript() {
|
|
|
+ assert(iptables); // we need iptables for our next trick
|
|
|
+ if (deployAsset("payload/redirect-ports.sh", "redirect-ports.sh")) {
|
|
|
+ String scriptFilePath = new File(MainActivity.getInstance().getFilesDir(), "redirect-ports.sh").getAbsolutePath();
|
|
|
+ Process p = null;
|
|
|
+ try {
|
|
|
+ p = new ProcessBuilder("su", "-c", "sh "+scriptFilePath).start();
|
|
|
+ p.waitFor(); // stall the main thread
|
|
|
+ // TODO: check return value?
|
|
|
+ } catch (IOException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ } catch (InterruptedException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @return name of porthack binary for device architecture
|
|
|
+ */
|
|
|
+ private static String getPorthackName() {
|
|
|
+ String porthack = "bind";
|
|
|
+
|
|
|
+ // determine system architecture to return the correct binary
|
|
|
+ String arch = System.getProperty("os.arch");
|
|
|
+ // TODO: handle more architectures
|
|
|
+ if (arch.equals("i686")) { // this is what genymotion reports
|
|
|
+ porthack += ".x86";
|
|
|
+ } else if (arch.startsWith("arm")) {
|
|
|
+ /*
|
|
|
+ possible values:
|
|
|
+ armv4
|
|
|
+ armv4t
|
|
|
+ armv5t
|
|
|
+ armv5te
|
|
|
+ armv5tej
|
|
|
+ armv6
|
|
|
+ armv7
|
|
|
+ */
|
|
|
+ porthack += ".arm";
|
|
|
+ } else if (arch.equals("mips")) {
|
|
|
+ porthack += ".mips";
|
|
|
+ }
|
|
|
+
|
|
|
+ return porthack;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @return filepath to deployed porthack binary
|
|
|
+ */
|
|
|
+ public static String getPorthackFilepath() {
|
|
|
+ File file = new File(MainActivity.getInstance().getFilesDir(), getPorthackName());
|
|
|
+ return file.getAbsolutePath();
|
|
|
+ }
|
|
|
+
|
|
|
+ public static boolean deployPorthack() {
|
|
|
+ String porthack = getPorthackName();
|
|
|
+ if (!deployAsset("payload/"+porthack, porthack)) {
|
|
|
+ return false; // :(
|
|
|
+ }
|
|
|
+
|
|
|
+ // make port hack executable
|
|
|
+ try {
|
|
|
+ Process p = new ProcessBuilder("su", "-c", "chmod 700 "+getPorthackFilepath()).start();
|
|
|
+ if (p.waitFor() != 0) {
|
|
|
+ logError(p.getErrorStream());
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ logOutput(p.getInputStream());
|
|
|
+ } catch (IOException e) {
|
|
|
+ return false;
|
|
|
+ } catch (InterruptedException e) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ return true; // SUCCESS!
|
|
|
+ }
|
|
|
+
|
|
|
+ public static void uninstallPorthack() {try {
|
|
|
+ Process p = new ProcessBuilder("su", "-c", "rm "+getPorthackFilepath()).start();
|
|
|
+ if (p.waitFor() != 0) {
|
|
|
+ logError(p.getErrorStream());
|
|
|
+ }
|
|
|
+ logOutput(p.getInputStream());
|
|
|
+ } catch (IOException e) {
|
|
|
+ } catch (InterruptedException e) {
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // copied from PrivilegedPort.java
|
|
|
+ private static void logOutput(InputStream stdout) throws IOException {
|
|
|
+ BufferedReader reader = new BufferedReader(new InputStreamReader(stdout));
|
|
|
+ String line;
|
|
|
+ while ((line = reader.readLine()) != null) {
|
|
|
+ Log.i("HelperUtils", line);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private static void logError(InputStream stderr) throws IOException {
|
|
|
+ BufferedReader reader = new BufferedReader(new InputStreamReader(stderr));
|
|
|
+ Log.e("HelperUtils", reader.readLine());
|
|
|
+ }
|
|
|
}
|