Browse Source

porthack deployment from within the app. also scripts

Fabio Arnold 9 years ago
parent
commit
5d231915e0

BIN
assets/payload/bind.x86


+ 7 - 0
res/layout/fragment_settings.xml

@@ -36,6 +36,13 @@
 				android:text="@string/yes"
 				android:id="@+id/settings_porthack_installed" android:layout_below="@+id/settings_device_rooted"
 				android:layout_alignParentRight="true" android:layout_alignParentEnd="true"/>
+		<Button
+				android:layout_width="wrap_content"
+				android:layout_height="wrap_content"
+				android:text="Deploy Porthack"
+				android:id="@+id/settings_deploy_porthack"
+				android:layout_below="@+id/txtP2PSubheader" android:layout_alignParentLeft="true"
+				android:layout_alignParentStart="false" android:layout_alignParentEnd="true"/>
 	</RelativeLayout>
 	<FrameLayout
 			android:layout_width="fill_parent"

+ 127 - 1
src/de/tudarmstadt/informatik/hostage/commons/HelperUtils.java

@@ -18,13 +18,22 @@ import org.apache.http.params.HttpParams;
 import org.apache.http.params.HttpProtocolParams;
 import org.apache.http.protocol.HTTP;
 
+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 java.net.InetAddress;
 import java.net.UnknownHostException;
 import java.security.KeyStore;
 import java.security.SecureRandom;
 
+import android.app.Activity;
 import android.content.Context;
+import android.content.res.AssetManager;
 import android.net.ConnectivityManager;
 import android.net.NetworkInfo;
 import android.net.wifi.WifiInfo;
@@ -32,11 +41,13 @@ import android.net.wifi.WifiManager;
 import android.os.Environment;
 import android.preference.PreferenceManager;
 import android.text.TextUtils;
+import android.util.Log;
 
 import de.tudarmstadt.informatik.hostage.logging.Record;
 import de.tudarmstadt.informatik.hostage.logging.formatter.TraCINgFormatter;
 import de.tudarmstadt.informatik.hostage.net.MySSLSocketFactory;
 import de.tudarmstadt.informatik.hostage.system.Device;
+import de.tudarmstadt.informatik.hostage.ui.activity.MainActivity;
 
 /**
  * Helper class with some static methods for general usage.
@@ -463,4 +474,119 @@ public final class HelperUtils {
     public static int getRedirectedPort(int port){
         return port + 1024 + 27113;
     }
-}
+
+	/**
+	 * 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 boolean deployPortRedirectionScript() {
+		return deployAsset("payload/redirect-ports.sh", "redirect-ports.sh");
+	}
+
+	/**
+	 * @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!
+	}
+
+	// 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());
+	}
+}

+ 34 - 72
src/de/tudarmstadt/informatik/hostage/system/Device.java

@@ -2,69 +2,55 @@ package de.tudarmstadt.informatik.hostage.system;
 
 import java.io.IOException;
 
-import android.app.Activity;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.preference.PreferenceManager;
 import android.util.Log;
 
-import de.tudarmstadt.informatik.hostage.Hostage;
-import de.tudarmstadt.informatik.hostage.R;
+import de.tudarmstadt.informatik.hostage.commons.HelperUtils;
 
 
 public class Device {
-
-	@SuppressWarnings("unused")
-	// DO NOT REMOVE, NEEDED FOR SINGLETON INITIALIZATION
-	private static final Device INSTANCE = new Device();
-
+	private static String porthackFilepath = "/data/local/bind";
 	private static boolean initialized = false;
 	private static boolean root = false;
 	private static boolean pp = false;
 
-    private Device() {
-
-        new Thread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-                    String portBinder = "[ -e /data/local/bind ]";
-
-					Process su = new ProcessBuilder("su", "-c", portBinder).start();
-					switch (su.waitFor()) {
-					case 0:
-						root = true;
-						pp = true;
-						break;
-					case 1:
-						root = true;
-						pp = false;
-						break;
-					case 127:
-						root = false;
-						pp = false;
-						break;
-					}
-				} catch (InterruptedException e) {
-				} catch (IOException e) {
-				} finally {
-					initialized = true;
-					Log.d("hostage", "Root: " + Boolean.toString(root));
-					Log.d("hostage", "PP: " + Boolean.toString(pp));
-				}
+    private static void checkPorthack() {
+		initialized = false;
+		porthackFilepath = HelperUtils.getPorthackFilepath();
+		Log.i("FILEPATH", porthackFilepath);
+		String portBinder = "[ -e "+porthackFilepath+" ]";
+
+		try {
+			Process su = new ProcessBuilder("su", "-c", portBinder).start();
+			switch (su.waitFor()) {
+			case 0:
+				root = true;
+				pp = true;
+				break;
+			case 1:
+				root = true;
+				pp = false;
+				break;
+			case 127:
+				root = false;
+				pp = false;
+				break;
 			}
-		}).start();
+		} catch (InterruptedException e) {
+		} catch (IOException e) {
+		} finally {
+			initialized = true;
+			Log.d("hostage", "Root: " + Boolean.toString(root));
+			Log.d("hostage", "PP: " + Boolean.toString(pp));
+		}
 	}
 
 	public static boolean isRooted() {
-		while (!initialized)
-			;
+		assert(initialized);
 		return root;
 	}
 
 	public static boolean isPorthackInstalled() {
-		while (!initialized)
-			;
+		assert(initialized);
 		return pp;
 	}
 
@@ -72,32 +58,8 @@ public class Device {
      * Called after auto-loading porthack. To update the local variables.
      */
 
-    public static boolean updatePorthack (){
-        try {
-            String portBinder = "[ -e /data/local/bind ]";
-
-            Process su = new ProcessBuilder("su", "-c", portBinder).start();
-            switch (su.waitFor()) {
-                case 0:
-                    root = true;
-                    pp = true;
-                    break;
-                case 1:
-                    root = true;
-                    pp = false;
-                    break;
-                case 127:
-                    root = false;
-                    pp = false;
-                    break;
-            }
-        } catch (InterruptedException e) {
-        } catch (IOException e) {
-        } finally {
-            initialized = true;
-            Log.d("hostage", "Root: " + Boolean.toString(root));
-            Log.d("hostage", "PP: " + Boolean.toString(pp));
-        }
+    public static boolean updatePorthack(){
+		checkPorthack();
         return (pp && root);
     }
 

+ 4 - 2
src/de/tudarmstadt/informatik/hostage/system/PrivilegedPort.java

@@ -13,6 +13,7 @@ import android.preference.PreferenceManager;
 import android.util.Log;
 
 import de.tudarmstadt.informatik.hostage.Hostage;
+import de.tudarmstadt.informatik.hostage.commons.HelperUtils;
 
 public class PrivilegedPort implements Runnable {
 
@@ -56,8 +57,9 @@ public class PrivilegedPort implements Runnable {
 
 	@Override
 	public void run() {
-
-        String command = String.format("/data/local/bind %s %d", type.toString(), port);
+		String porthack = HelperUtils.getPorthackFilepath();
+		Log.i("privileged port", porthack);
+        String command = String.format(porthack+" %s %d", type.toString(), port);
 
 		try {
 			Process p = new ProcessBuilder("su", "-c", command).start();

+ 4 - 0
src/de/tudarmstadt/informatik/hostage/ui/activity/MainActivity.java

@@ -38,6 +38,7 @@ import de.tudarmstadt.informatik.hostage.Hostage;
 import de.tudarmstadt.informatik.hostage.R;
 import de.tudarmstadt.informatik.hostage.model.Profile;
 import de.tudarmstadt.informatik.hostage.persistence.ProfileManager;
+import de.tudarmstadt.informatik.hostage.system.Device;
 import de.tudarmstadt.informatik.hostage.ui.model.LogFilter;
 import de.tudarmstadt.informatik.hostage.ui.adapter.DrawerListAdapter;
 import de.tudarmstadt.informatik.hostage.ui.fragment.AboutFragment;
@@ -216,6 +217,9 @@ public class MainActivity extends Activity {
 		setContentView(R.layout.activity_drawer_main);
 		mProfileManager = ProfileManager.getInstance();
 
+		// check for the porthack
+		Device.updatePorthack();
+
 		// init threat indicator animation
 		ThreatIndicatorGLRenderer.assets = getAssets();
 		ThreatIndicatorGLRenderer.setThreatLevel(ThreatIndicatorGLRenderer.ThreatLevel.NOT_MONITORING);

+ 26 - 7
src/de/tudarmstadt/informatik/hostage/ui/fragment/SettingsFragment.java

@@ -5,8 +5,10 @@ import android.os.Bundle;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
+import android.widget.Button;
 import android.widget.TextView;
 import de.tudarmstadt.informatik.hostage.R;
+import de.tudarmstadt.informatik.hostage.commons.HelperUtils;
 import de.tudarmstadt.informatik.hostage.system.Device;
 
 /**
@@ -14,13 +16,16 @@ import de.tudarmstadt.informatik.hostage.system.Device;
  * @created 24.02.14 23:37
  */
 public class SettingsFragment extends UpNavigatibleFragment {
+	private TextView mPorthackText;
+
 	public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
 		super.onCreateView(inflater, container, savedInstanceState);
 		getActivity().setTitle(getResources().getString(R.string.drawer_settings));
 		View v = inflater.inflate(R.layout.fragment_settings, container, false);
 
 		TextView rootedText = (TextView) v.findViewById(R.id.settings_device_rooted);
-		TextView porthackText = (TextView) v.findViewById(R.id.settings_porthack_installed);
+		mPorthackText = (TextView) v.findViewById(R.id.settings_porthack_installed);
+		Button porthackButton = (Button) v.findViewById(R.id.settings_deploy_porthack);
 
 		if (Device.isRooted()) {
 			rootedText.setText(R.string.yes);
@@ -30,15 +35,29 @@ public class SettingsFragment extends UpNavigatibleFragment {
 			rootedText.setTextColor(getResources().getColor(R.color.holo_red));
 		}
 
+		updatePorthackStatus();
+
+		porthackButton.setOnClickListener(new View.OnClickListener() {
+			@Override
+			public void onClick(View v) {
+				HelperUtils.deployPorthack();
+				updatePorthackStatus();
+			}
+		});
+
+		return v;
+	}
+
+	private void updatePorthackStatus() {
+		Device.updatePorthack(); // get current situation
+
 		if (Device.isPorthackInstalled()) {
-			porthackText.setText(R.string.yes);
-			porthackText.setTextColor(getResources().getColor(R.color.holo_dark_green));
+			mPorthackText.setText(R.string.yes);
+			mPorthackText.setTextColor(getResources().getColor(R.color.holo_dark_green));
 		} else {
-			porthackText.setText(R.string.no);
-			porthackText.setTextColor(getResources().getColor(R.color.holo_red));
+			mPorthackText.setText(R.string.no);
+			mPorthackText.setTextColor(getResources().getColor(R.color.holo_red));
 		}
-
-		return v;
 	}
 
 	public void onViewCreated(View view, Bundle savedInstanceState) {