diff --git a/cSploit/build.gradle b/cSploit/build.gradle index 0002b242e6..b4a8ecb7e9 100644 --- a/cSploit/build.gradle +++ b/cSploit/build.gradle @@ -18,9 +18,10 @@ allprojects { mavenCentral() } } -apply plugin: 'com.android.application' +apply plugin: 'com.android.application' dependencies { + testCompile 'junit:junit:4.12' compile 'com.android.support:support-v4:23.1.1' compile 'com.android.support:appcompat-v7:23.1.1' compile 'com.android.support:design:23.1.1' @@ -33,7 +34,7 @@ dependencies { compile 'com.googlecode.juniversalchardet:juniversalchardet:1.0.3' compile 'org.tukaani:xz:1.5' compile 'ch.acra:acra:4.6.2' - testCompile 'junit:junit:4.12' + compile 'com.android.support:recyclerview-v7:23.1.1' } android { @@ -55,7 +56,7 @@ android { targetSdkVersion 22 versionCode 4 versionName "1.7.0-unstable" - if(System.getenv("NIGHTLY_BUILD")) { + if (System.getenv("NIGHTLY_BUILD")) { versionName += "+" + System.getenv("NIGHTLY_BUILD_COMMIT").substring(0, 7) } } diff --git a/cSploit/jni b/cSploit/jni index 02a6b6a46e..1c72f22afa 160000 --- a/cSploit/jni +++ b/cSploit/jni @@ -1 +1 @@ -Subproject commit 02a6b6a46eca27051e4d6558af1d83da56afb79d +Subproject commit 1c72f22afa70c0c603ac08cfb654c61d9fe97692 diff --git a/cSploit/src/main/AndroidManifest.xml b/cSploit/src/main/AndroidManifest.xml index 84618a1962..48c322c390 100644 --- a/cSploit/src/main/AndroidManifest.xml +++ b/cSploit/src/main/AndroidManifest.xml @@ -1,20 +1,20 @@ - + - - - - - - - - - + + + + + + + + + - + android:maxSdkVersion="18"/> + - + - + - - + - + android:name=".services.UpdateInstaller" + android:enabled="true"/> + android:enabled="true"/> + android:label="@string/title_activity_main"/> + android:label="@string/title_activity_main" + android:theme="@style/Theme.AppCompat.Light"/> + android:label="@string/title_activity_main"/> + android:label="@string/title_activity_main"/> + android:label="@string/title_activity_main"/> + android:label="@string/title_activity_main"/> + android:label="@string/title_activity_main"/> + android:label="@string/title_activity_main"/> + android:label="@string/title_activity_main"/> + android:label="@string/title_activity_main"/> + android:label="@string/title_activity_main"/> + android:label="@string/title_activity_main"/> + android:label="@string/title_activity_main"/> + android:label="@string/title_activity_main"/> + android:label="@string/title_activity_main"/> - + android:label="@string/title_activity_main"/> + android:label="@string/title_activity_main"/> + android:label="@string/title_activity_main"/> + android:label="@string/title_activity_main"/> + android:parentActivityName=".plugins.mitm.PasswordSniffer"> + + + + + diff --git a/cSploit/src/main/java/org/csploit/android/ActionActivity.java b/cSploit/src/main/java/org/csploit/android/ActionActivity.java index de675fcd1d..62709001a3 100644 --- a/cSploit/src/main/java/org/csploit/android/ActionActivity.java +++ b/cSploit/src/main/java/org/csploit/android/ActionActivity.java @@ -22,9 +22,9 @@ import android.os.Bundle; import android.support.v7.app.AppCompatActivity; -public class ActionActivity extends AppCompatActivity { +import org.csploit.android.gui.fragments.PluginList; - ActionFragment f; +public class ActionActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { @@ -39,14 +39,9 @@ protected void onCreate(Bundle savedInstanceState) { if (savedInstanceState != null) { return; } - f = new ActionFragment(); + PluginList f = new PluginList(); getSupportFragmentManager().beginTransaction() .add(R.id.mainframe, f).commit(); } } - - @Override - public void onBackPressed() { - f.onBackPressed(); - } } \ No newline at end of file diff --git a/cSploit/src/main/java/org/csploit/android/ActionFragment.java b/cSploit/src/main/java/org/csploit/android/ActionFragment.java deleted file mode 100644 index ba82dec8db..0000000000 --- a/cSploit/src/main/java/org/csploit/android/ActionFragment.java +++ /dev/null @@ -1,153 +0,0 @@ -package org.csploit.android; - -import android.annotation.SuppressLint; -import android.content.Context; -import android.content.Intent; -import android.content.SharedPreferences; -import android.os.Bundle; -import android.support.annotation.Nullable; -import android.support.v4.app.Fragment; -import android.support.v4.content.ContextCompat; -import android.support.v7.app.AppCompatActivity; -import android.view.LayoutInflater; -import android.view.MenuItem; -import android.view.View; -import android.view.ViewGroup; -import android.widget.AdapterView; -import android.widget.ArrayAdapter; -import android.widget.ImageView; -import android.widget.ListView; -import android.widget.TextView; -import android.widget.Toast; - -import org.csploit.android.core.Plugin; -import org.csploit.android.core.System; -import org.csploit.android.gui.dialogs.FinishDialog; -import org.csploit.android.net.Target; - -import java.util.ArrayList; - -public class ActionFragment extends Fragment { - - private ArrayList mAvailable = null; - private ListView theList; - private Target mTarget; - - - @Nullable - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setHasOptionsMenu(true); - return inflater.inflate(R.layout.actions_layout, container, false); - } - - @Override - public void onViewCreated(View v, Bundle savedInstanceState) { - SharedPreferences themePrefs = getActivity().getSharedPreferences("THEME", 0); - Boolean isDark = themePrefs.getBoolean("isDark", false); - if (isDark) { - getActivity().setTheme(R.style.DarkTheme); - v.setBackgroundColor(ContextCompat.getColor(getActivity(), R.color.background_window_dark)); - } - else { - getActivity().setTheme(R.style.AppTheme); - v.setBackgroundColor(ContextCompat.getColor(getActivity(), R.color.background_window)); - } - mTarget = org.csploit.android.core.System.getCurrentTarget(); - - if (mTarget != null) { - getActivity().setTitle("cSploit > " + mTarget); - ((AppCompatActivity) getActivity()).getSupportActionBar().setDisplayHomeAsUpEnabled(true); - theList = (ListView) getActivity().findViewById(R.id.android_list); - mAvailable = System.getPluginsForTarget(); - ActionsAdapter mActionsAdapter = new ActionsAdapter(); - theList.setAdapter(mActionsAdapter); - theList.setOnItemClickListener(new ListView.OnItemClickListener() { - @Override - public void onItemClick(AdapterView parent, View view, int position, long id) { - - if (System.checkNetworking(getActivity())) { - Plugin plugin = mAvailable.get(position); - System.setCurrentPlugin(plugin); - - if (plugin.hasLayoutToShow()) { - Toast.makeText(getActivity(), getString(R.string.selected) + getString(plugin.getName()), Toast.LENGTH_SHORT).show(); - - startActivity(new Intent( - getActivity(), - plugin.getClass() - )); - getActivity().overridePendingTransition(R.anim.fadeout, R.anim.fadein); - } else - plugin.onActionClick(getActivity().getApplicationContext()); - } - } - }); - } else { - new FinishDialog(getString(R.string.warning), getString(R.string.something_went_wrong), getActivity()).show(); - } - } - - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - switch (item.getItemId()) { - case android.R.id.home: - - getActivity().onBackPressed(); - - return true; - - default: - return super.onOptionsItemSelected(item); - } - } - - public void onBackPressed() { - getActivity().finish(); - getActivity().overridePendingTransition(R.anim.fadeout, R.anim.fadein); - } - - public class ActionsAdapter extends ArrayAdapter { - public ActionsAdapter() { - super(getActivity(), R.layout.actions_list_item, mAvailable); - } - - @SuppressLint("NewApi") - @Override - public View getView(int position, View convertView, ViewGroup parent) { - View row = convertView; - ActionHolder holder; - - if (row == null) { - LayoutInflater inflater = (LayoutInflater) getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE); - row = inflater.inflate(R.layout.actions_list_item, parent, false); - if (getActivity().getSharedPreferences("THEME", 0).getBoolean("isDark", false)) - row.setBackgroundResource(R.drawable.card_background_dark); - holder = new ActionHolder(); - - holder.icon = (ImageView) (row != null ? row.findViewById(R.id.actionIcon) : null); - holder.name = (TextView) (row != null ? row.findViewById(R.id.actionName) : null); - holder.description = (TextView) (row != null ? row.findViewById(R.id.actionDescription) : null); - if (row != null) row.setTag(holder); - - } else holder = (ActionHolder) row.getTag(); - - Plugin action = mAvailable.get(position); - - holder.icon.setImageResource(action.getIconResourceId()); - holder.name.setText(getString(action.getName())); - holder.description.setText(getString(action.getDescription())); - - return row; - } - - public class ActionHolder { - ImageView icon; - TextView name; - TextView description; - } - } - -} \ No newline at end of file diff --git a/cSploit/src/main/java/org/csploit/android/CSploitApplication.java b/cSploit/src/main/java/org/csploit/android/CSploitApplication.java index ce3a4b747c..e7ba8cd5cd 100644 --- a/cSploit/src/main/java/org/csploit/android/CSploitApplication.java +++ b/cSploit/src/main/java/org/csploit/android/CSploitApplication.java @@ -27,6 +27,7 @@ import org.acra.sender.HttpSender; import org.csploit.android.core.Logger; import org.csploit.android.core.System; +import org.csploit.android.helpers.GUIHelper; import org.csploit.android.plugins.ExploitFinder; import org.csploit.android.plugins.Inspector; import org.csploit.android.plugins.LoginCracker; @@ -55,38 +56,14 @@ public class CSploitApplication extends Application { @Override public void onCreate() { - SharedPreferences themePrefs = getSharedPreferences("THEME", 0); - Boolean isDark = themePrefs.getBoolean("isDark", false); - if (isDark) - setTheme(R.style.DarkTheme); - else - setTheme(R.style.AppTheme); - super.onCreate(); + System.setApplicationContext(this); + + GUIHelper.setupTheme(this); ACRA.init(this); Services.init(this); - // initialize the system - try { - System.init(this); - } catch (Exception e) { - // ignore exception when the user has wifi off - if (!(e instanceof NoRouteToHostException)) - System.errorLogging(e); - } - ACRA.setConfig(ACRA.getConfig().setApplicationLogFile(System.getCorePath() + "/cSploitd.log")); - - // load system modules even if the initialization failed - System.registerPlugin(new RouterPwn()); - System.registerPlugin(new Traceroute()); - System.registerPlugin(new PortScanner()); - System.registerPlugin(new Inspector()); - System.registerPlugin(new ExploitFinder()); - System.registerPlugin(new LoginCracker()); - System.registerPlugin(new Sessions()); - System.registerPlugin(new MITM()); - System.registerPlugin(new PacketForger()); } } diff --git a/cSploit/src/main/java/org/csploit/android/MainActivity.java b/cSploit/src/main/java/org/csploit/android/MainActivity.java index 79accb87a7..686da0e5f4 100644 --- a/cSploit/src/main/java/org/csploit/android/MainActivity.java +++ b/cSploit/src/main/java/org/csploit/android/MainActivity.java @@ -19,34 +19,130 @@ */ package org.csploit.android; -import android.content.SharedPreferences; +import android.content.Intent; import android.os.Bundle; -import android.support.v7.app.AppCompatActivity; +import android.support.design.widget.NavigationView; +import android.widget.Toast; -public class MainActivity extends AppCompatActivity { +import org.csploit.android.core.Plugin; +import org.csploit.android.core.System; +import org.csploit.android.gui.activities.AbstractSidebarActivity; +import org.csploit.android.gui.fragments.Heartless; +import org.csploit.android.gui.fragments.Init; +import org.csploit.android.gui.fragments.PortList; +import org.csploit.android.gui.fragments.TargetDetail; +import org.csploit.android.gui.fragments.TargetList; +import org.csploit.android.gui.fragments.plugins.mitm.Hijacker; +import org.csploit.android.helpers.FragmentHelper; +import org.csploit.android.net.Target; +import org.csploit.android.plugins.mitm.hijacker.HijackerWebView; +import org.csploit.android.plugins.mitm.hijacker.Session; +import org.csploit.android.services.receivers.ConnectivityReceiver; +import org.csploit.android.services.receivers.UpdateReceiver; - MainFragment f; +public class MainActivity extends AbstractSidebarActivity + implements NavigationView.OnNavigationItemSelectedListener, + TargetList.OnFragmentInteraction, + TargetDetail.OnFragmentInteractionListener, + Init.OnFragmentInteractionListener, + UpdateReceiver.CoreUpdateListener, + Hijacker.OnFragmentInteractionListener, + PortList.OnFragmentInteractionListener { + + private UpdateReceiver updateReceiver; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - SharedPreferences themePrefs = getSharedPreferences("THEME", 0); - if (themePrefs.getBoolean("isDark", false)) - setTheme(R.style.DarkTheme); - else - setTheme(R.style.AppTheme); + setContentView(R.layout.main); - if (findViewById(R.id.mainframe) != null) { - if (savedInstanceState != null) { - return; - } - f = new MainFragment(); - getSupportFragmentManager().beginTransaction() - .add(R.id.mainframe, f).commit(); + + if (savedInstanceState != null) { + return; + } + + updateReceiver = new UpdateReceiver(this); + updateReceiver.register(this); + } + + @Override + protected void onPostResume() { + super.onPostResume(); + init(); + } + + @Override + protected void onDestroy() { + updateReceiver.unregister(); + + super.onDestroy(); + } + + private void init() { + if(!System.isCoreInstalled()) { + FragmentHelper.switchToFragment(this, Heartless.class); + } else if(!System.isInitialized() || !System.isCoreInitialized()) { + FragmentHelper.switchToFragment(this, Init.class); + } else { + onInitDone(); + } + } + + @Override + public void onCoreUpdated() { + if(canSwitchFragment()) { + init(); + } + } + + @Override + public void onInitDone() { + if(!canSwitchFragment()) { + return; + } + + FragmentHelper.switchToFragment(this, TargetList.class); + } + + @Override + public void onPluginChosen(Plugin plugin) { + if (System.checkNetworking(this)) { + System.setCurrentPlugin(plugin); + + if (plugin.hasLayoutToShow()) { + Toast.makeText(this, getString(R.string.selected) + getString(plugin.getName()), Toast.LENGTH_SHORT).show(); + FragmentHelper.openFragment(this, plugin); + } else + plugin.onActionClick(this); + } + } + + @Override + public void onTargetSelected(Target target) { + //TODO: master/detail view + + Toast.makeText(this, getString(R.string.selected_) + target.getDisplayAddress(), Toast.LENGTH_SHORT).show(); + + TargetDetail fragment = (TargetDetail) FragmentHelper.getCachedFragment(this, TargetDetail.class); + + if(fragment == null) { + fragment = TargetDetail.newInstance(target); + } else { + TargetDetail.setUp(fragment, target); } + + FragmentHelper.openFragment(this, fragment); } - public void onBackPressed() { - f.onBackPressed(); + @Override + public void onHijackerSessionSelected(Session session) { + System.setCustomData(session); + //TODO: fragment it + startActivity(new Intent(this, HijackerWebView.class)); + } + + @Override + public void onPortChosen(Target.Port port) { + //TODO } } \ No newline at end of file diff --git a/cSploit/src/main/java/org/csploit/android/MainFragment.java b/cSploit/src/main/java/org/csploit/android/MainFragment.java index 6d1eb1e7d2..cf1295b253 100644 --- a/cSploit/src/main/java/org/csploit/android/MainFragment.java +++ b/cSploit/src/main/java/org/csploit/android/MainFragment.java @@ -25,7 +25,6 @@ import android.content.SharedPreferences; import android.graphics.Typeface; import android.net.ConnectivityManager; -import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.support.annotation.Nullable; @@ -57,7 +56,6 @@ import org.csploit.android.core.Plugin; import org.csploit.android.core.System; import org.csploit.android.events.Event; -import org.csploit.android.gui.dialogs.AboutDialog; import org.csploit.android.gui.dialogs.ChoiceDialog; import org.csploit.android.gui.dialogs.ConfirmDialog; import org.csploit.android.gui.dialogs.ConfirmDialog.ConfirmDialogListener; @@ -69,6 +67,8 @@ import org.csploit.android.gui.dialogs.MultipleChoiceDialog; import org.csploit.android.gui.dialogs.SpinnerDialog; import org.csploit.android.gui.dialogs.SpinnerDialog.SpinnerDialogListener; +import org.csploit.android.gui.fragments.PluginList; +import org.csploit.android.helpers.FragmentHelper; import org.csploit.android.helpers.ThreadHelper; import org.csploit.android.net.Network; import org.csploit.android.net.Target; @@ -83,7 +83,7 @@ import org.csploit.android.plugins.mitm.MITM; import org.csploit.android.services.Services; import org.csploit.android.services.UpdateChecker; -import org.csploit.android.services.UpdateService; +import org.csploit.android.services.UpdateInstaller; import org.csploit.android.services.receivers.MsfRpcdServiceReceiver; import org.csploit.android.services.receivers.NetworkRadarReceiver; import org.csploit.android.update.CoreUpdate; @@ -106,1232 +106,1207 @@ @SuppressLint("NewApi") public class MainFragment extends Fragment { - private String EMPTY_LIST_MESSAGE = ""; - private static final int WIFI_CONNECTION_REQUEST = 1012; - private boolean isAnyNetInterfaceAvailable = false; - private TargetAdapter mTargetAdapter = null; - private NetworkRadarReceiver mRadarReceiver = new NetworkRadarReceiver(); - private UpdateReceiver mUpdateReceiver = new UpdateReceiver(); - private WipeReceiver mWipeReceiver = new WipeReceiver(); - private MsfRpcdServiceReceiver mMsfReceiver = new MsfRpcdServiceReceiver(); - private ConnectivityReceiver mConnectivityReceiver = new ConnectivityReceiver(); - private Menu mMenu = null; - private TextView mEmptyTextView = null; - private Toast mToast = null; - private TextView mTextView = null; - private long mLastBackPressTime = 0; - private ActionMode mActionMode = null; - private ListView lv; - private boolean isRootMissing = false; - private String[] mIfaces = null; - private boolean mIsCoreInstalled = false; - private boolean mIsDaemonBeating = false; - private boolean mIsConnectivityAvailable = false; - private boolean mIsUpdateDownloading = false; - private boolean mHaveAnyWifiInterface = true; // TODO: check is device have a wifi interface - private boolean mOfflineMode = false; - - @Override - public void onActivityResult(int requestCode, int resultCode, - Intent intent) { - if (requestCode == WIFI_CONNECTION_REQUEST && resultCode == AppCompatActivity.RESULT_OK - && intent.hasExtra(WifiScannerFragment.CONNECTED)) { - init(); - } + private String EMPTY_LIST_MESSAGE = ""; + private static final int WIFI_CONNECTION_REQUEST = 1012; + private boolean isAnyNetInterfaceAvailable = false; + private TargetAdapter mTargetAdapter = null; + private NetworkRadarReceiver mRadarReceiver = new NetworkRadarReceiver(); + private UpdateReceiver mUpdateReceiver = new UpdateReceiver(); + private WipeReceiver mWipeReceiver = new WipeReceiver(); + private MsfRpcdServiceReceiver mMsfReceiver = new MsfRpcdServiceReceiver(); + private ConnectivityReceiver mConnectivityReceiver = new ConnectivityReceiver(); + private Menu mMenu = null; + private TextView mEmptyTextView = null; + private Toast mToast = null; + private TextView mTextView = null; + private long mLastBackPressTime = 0; + private ActionMode mActionMode = null; + private ListView lv; + private boolean isRootMissing = false; + private String[] mIfaces = null; + private boolean mIsCoreInstalled = false; + private boolean mIsDaemonBeating = false; + private boolean mIsConnectivityAvailable = false; + private boolean mIsUpdateDownloading = false; + private boolean mHaveAnyWifiInterface = true; // TODO: check is device have a wifi interface + private boolean mOfflineMode = false; + + @Override + public void onActivityResult(int requestCode, int resultCode, + Intent intent) { + if (requestCode == WIFI_CONNECTION_REQUEST && resultCode == AppCompatActivity.RESULT_OK + && intent.hasExtra(WifiScannerFragment.CONNECTED)) { + init(); } - - private void onInitializationError(final String message) { - getActivity().runOnUiThread(new Runnable() { - @Override - public void run() { - new FatalDialog(getString(R.string.initialization_error), - message, message.contains(">"), - getActivity()).show(); - } - }); + } + + private void onInitializationError(final String message) { + getActivity().runOnUiThread(new Runnable() { + @Override + public void run() { + new FatalDialog(getString(R.string.initialization_error), + message, message.contains(">"), + getActivity()).show(); + } + }); + } + + private void onCoreUpdated() { + System.onCoreInstalled(); + getActivity().runOnUiThread(new Runnable() { + @Override + public void run() { + init(); + startAllServices(); + notifyMenuChanged(); + } + }); + } + + @Nullable + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setHasOptionsMenu(true); + return inflater.inflate(R.layout.target_list, container, false); + } + + @Override + public void onViewCreated(View v, Bundle savedInstanceState) { + SharedPreferences themePrefs = getActivity().getSharedPreferences("THEME", 0); + Boolean isDark = themePrefs.getBoolean("isDark", false); + if (isDark) { + getActivity().setTheme(R.style.DarkTheme); + v.setBackgroundColor(ContextCompat.getColor(getActivity(), R.color.background_window_dark)); + } else { + getActivity().setTheme(R.style.AppTheme); + v.setBackgroundColor(ContextCompat.getColor(getActivity(), R.color.background_window)); } + mEmptyTextView = (TextView) v.findViewById(R.id.emptyTextView); + lv = (ListView) v.findViewById(R.id.android_list); + mTextView = (TextView) v.findViewById(R.id.textView); - private void onCoreUpdated() { - System.onCoreInstalled(); - getActivity().runOnUiThread(new Runnable() { - @Override - public void run() { - init(); - startAllServices(); - notifyMenuChanged(); - } - }); - } + lv.setOnItemClickListener(new ListView.OnItemClickListener() { - @Nullable - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setHasOptionsMenu(true); - return inflater.inflate(R.layout.target_layout, container, false); - } + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { - @Override - public void onViewCreated(View v, Bundle savedInstanceState) { - SharedPreferences themePrefs = getActivity().getSharedPreferences("THEME", 0); - Boolean isDark = themePrefs.getBoolean("isDark", false); - if (isDark) { - getActivity().setTheme(R.style.DarkTheme); - v.setBackgroundColor(ContextCompat.getColor(getActivity(), R.color.background_window_dark)); - } else { - getActivity().setTheme(R.style.AppTheme); - v.setBackgroundColor(ContextCompat.getColor(getActivity(), R.color.background_window)); + if (mActionMode != null) { + mTargetAdapter.toggleSelection(position); + return; } - mEmptyTextView = (TextView) v.findViewById(R.id.emptyTextView); - lv = (ListView) v.findViewById(R.id.android_list); - mTextView = (TextView) v.findViewById(R.id.textView); - - lv.setOnItemClickListener(new ListView.OnItemClickListener() { - - @Override - public void onItemClick(AdapterView parent, View view, int position, long id) { - if (mActionMode != null) { - mTargetAdapter.toggleSelection(position); - return; - } - - Target target = (Target) mTargetAdapter.getItem(position); - System.setCurrentTarget(target); - - ThreadHelper.getSharedExecutor().execute(new Runnable() { - @Override - public void run() { + final Target target = (Target) mTargetAdapter.getItem(position); + System.setCurrentTarget(target); - startActivityForResult(new Intent(getActivity(), - ActionActivity.class), WIFI_CONNECTION_REQUEST); - - getActivity().overridePendingTransition(R.anim.fadeout, R.anim.fadein); - } - }); + ThreadHelper.getSharedExecutor().execute(new Runnable() { + @Override + public void run() { - Toast.makeText(getActivity(), - getString(R.string.selected_) + System.getCurrentTarget(), - Toast.LENGTH_SHORT).show(); + PluginList fragment = (PluginList) getActivity().getSupportFragmentManager() + .findFragmentByTag("ActionFragment"); + if(fragment != null) { + PluginList.setup(fragment, target); + } else { + fragment = PluginList.newInstance(target); } - }); - lv.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() { - @Override - public boolean onItemLongClick(AdapterView parent, View view, int position, long id) { - Target t = (Target) mTargetAdapter.getItem(position); - if (t.getType() == Target.Type.NETWORK) { - if (mActionMode == null) - targetAliasPrompt(t); - return true; - } - if (mActionMode == null) { - mTargetAdapter.clearSelection(); - mActionMode = ((AppCompatActivity) getActivity()).startSupportActionMode(mActionModeCallback); - } - mTargetAdapter.toggleSelection(position); - return true; - } - }); - mTargetAdapter = new TargetAdapter(); - - lv.setEmptyView(v.findViewById(android.R.id.empty)); - lv.setAdapter(mTargetAdapter); - - System.setTargetListObserver(mTargetAdapter); - mRadarReceiver.register(getActivity()); - mUpdateReceiver.register(getActivity()); - mWipeReceiver.register(getActivity()); - mMsfReceiver.register(getActivity()); - mConnectivityReceiver.register(getActivity()); + FragmentHelper.switchToFragment(MainFragment.this, fragment); + } + }); - init(); - startAllServices(); + Toast.makeText(getActivity(), + getString(R.string.selected_) + System.getCurrentTarget(), + Toast.LENGTH_SHORT).show(); + + } + }); + lv.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() { + @Override + public boolean onItemLongClick(AdapterView parent, View view, int position, long id) { + Target t = (Target) mTargetAdapter.getItem(position); + if (t.getType() == Target.Type.NETWORK) { + if (mActionMode == null) + targetAliasPrompt(t); + return true; + } + if (mActionMode == null) { + mTargetAdapter.clearSelection(); + mActionMode = ((AppCompatActivity) getActivity()).startSupportActionMode(mActionModeCallback); + } + mTargetAdapter.toggleSelection(position); + return true; + } + }); + mTargetAdapter = new TargetAdapter(); + + lv.setEmptyView(v.findViewById(android.R.id.empty)); + lv.setAdapter(mTargetAdapter); + + System.setTargetListObserver(mTargetAdapter); + + mRadarReceiver.register(getActivity()); + mUpdateReceiver.register(getActivity()); + mWipeReceiver.register(getActivity()); + mMsfReceiver.register(getActivity()); + mConnectivityReceiver.register(getActivity()); + + init(); + startAllServices(); + } + + private void startAllServices() { + startNetworkRadar(); + startUpdateChecker(); + startRPCServer(); + } + + private void notifyMenuChanged() { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) + getActivity().invalidateOptionsMenu(); + else + configureMenu(); + } + + /** + * Performs the firsts actions when the app starts. + * called also when the user connects to a wifi from the app, and when the core is updated. + */ + public void init() { + loadInterfaces(); + isAnyNetInterfaceAvailable = (mIfaces.length > 0); + mIsConnectivityAvailable = isConnectivityAvailable(); + + mIsCoreInstalled = System.isCoreInstalled(); + mIsDaemonBeating = System.isCoreInitialized(); + + // check minimum requirements for system initialization + + if (!mIsCoreInstalled) { + EMPTY_LIST_MESSAGE = mIsConnectivityAvailable ? + getString(R.string.missing_core_update) : + getString(R.string.no_connectivity); + return; + } else if (!mIsDaemonBeating) { + try { + System.initCore(); + mIsDaemonBeating = true; + + if (Client.hadCrashed()) { + Logger.warning("Client has previously crashed, building a crash report."); + CrashReporter.notifyNativeLibraryCrash(); + onInitializationError(getString(R.string.JNI_crash_detected)); + return; + } + } catch (UnsatisfiedLinkError e) { + onInitializationError("hi developer, you missed to build JNI stuff, thanks for playing with me :)"); + return; + } catch (System.SuException e) { + onInitializationError(getString(R.string.only_4_root)); + return; + } catch (System.DaemonException e) { + Logger.error(e.getMessage()); + } + + if (!mIsDaemonBeating) { + if (mIsConnectivityAvailable) { + EMPTY_LIST_MESSAGE = getString(R.string.heart_attack_update); + } else { + onInitializationError(getString(R.string.heart_attack)); + } + return; + } } - private void startAllServices() { - startNetworkRadar(); - startUpdateChecker(); - startRPCServer(); + // if all is initialized, configure the network + initSystem(); + } + + @Override + public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { + inflater.inflate(R.menu.main, menu); + + mMenu = menu; + configureMenu(); + } + + private boolean isConnectivityAvailable() { + return Network.isConnectivityAvailable(getActivity()) || Network.isWifiConnected(getActivity()); + } + + public void configureMenu() { + if (mMenu == null) + return; + mMenu.findItem(R.id.add).setVisible(isAnyNetInterfaceAvailable); + mMenu.findItem(R.id.scan).setVisible(mHaveAnyWifiInterface); + mMenu.findItem(R.id.wifi_ifaces).setEnabled(canChangeInterface()); + mMenu.findItem(R.id.new_session).setEnabled(isAnyNetInterfaceAvailable); + mMenu.findItem(R.id.save_session).setEnabled(isAnyNetInterfaceAvailable); + mMenu.findItem(R.id.restore_session).setEnabled(isAnyNetInterfaceAvailable); + } + + @Override + public void onPrepareOptionsMenu(Menu menu) { + super.onPrepareOptionsMenu(menu); + MenuItem item = menu.findItem(R.id.ss_monitor); + + Services.getNetworkRadar().buildMenuItem(item); + + item = menu.findItem(R.id.ss_msfrpcd); + + Services.getMsfRpcdService().buildMenuItem(item); + + mMenu = menu; + getActivity().onPrepareOptionsMenu(menu); + } + + private boolean initSystem() { + // retry + try { + System.init(); + } catch (Exception e) { + boolean isFatal = !(e instanceof NoRouteToHostException); + + if (isFatal) { + System.errorLogging(e); + onInitializationError(System.getLastError()); + } + + return !isFatal; } - private void notifyMenuChanged() { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) - getActivity().invalidateOptionsMenu(); - else - configureMenu(); + registerPlugins(); + return true; + } + + private void registerPlugins() { + if (!System.getPlugins().isEmpty()) + return; + + System.registerPlugin(new RouterPwn()); + System.registerPlugin(new Traceroute()); + System.registerPlugin(new PortScanner()); + System.registerPlugin(new Inspector()); + System.registerPlugin(new ExploitFinder()); + System.registerPlugin(new LoginCracker()); + System.registerPlugin(new Sessions()); + System.registerPlugin(new MITM()); + System.registerPlugin(new PacketForger()); + } + + private void loadInterfaces() { + boolean menuChanged; + List interfaces = Network.getAvailableInterfaces(); + int size = interfaces.size(); + + if (mIfaces != null) { + menuChanged = mIfaces.length != size; + menuChanged &= mIfaces.length <= 1 || size <= 1; + } else { + menuChanged = true; } - /** - * Performs the firsts actions when the app starts. - * called also when the user connects to a wifi from the app, and when the core is updated. - */ - public void init() { - loadInterfaces(); - isAnyNetInterfaceAvailable = (mIfaces.length > 0); - mIsConnectivityAvailable = isConnectivityAvailable(); - - mIsCoreInstalled = System.isCoreInstalled(); - mIsDaemonBeating = System.isCoreInitialized(); - - // check minimum requirements for system initialization - - if (!mIsCoreInstalled) { - EMPTY_LIST_MESSAGE = mIsConnectivityAvailable ? - getString(R.string.missing_core_update) : - getString(R.string.no_connectivity); - return; - } else if (!mIsDaemonBeating) { - try { - System.initCore(); - mIsDaemonBeating = true; - - if (Client.hadCrashed()) { - Logger.warning("Client has previously crashed, building a crash report."); - CrashReporter.notifyNativeLibraryCrash(); - onInitializationError(getString(R.string.JNI_crash_detected)); - return; - } - } catch (UnsatisfiedLinkError e) { - onInitializationError("hi developer, you missed to build JNI stuff, thanks for playing with me :)"); - return; - } catch (System.SuException e) { - onInitializationError(getString(R.string.only_4_root)); - return; - } catch (System.DaemonException e) { - Logger.error(e.getMessage()); - } + mIfaces = new String[size]; + interfaces.toArray(mIfaces); + isAnyNetInterfaceAvailable = mIfaces.length > 0; - if (!mIsDaemonBeating) { - if (mIsConnectivityAvailable) { - EMPTY_LIST_MESSAGE = getString(R.string.heart_attack_update); - } else { - onInitializationError(getString(R.string.heart_attack)); - } - return; - } + if (menuChanged) { + getActivity().runOnUiThread(new Runnable() { + @Override + public void run() { + notifyMenuChanged(); } - - // if all is initialized, configure the network - initSystem(); - } - - @Override - public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { - inflater.inflate(R.menu.main, menu); - - mMenu = menu; - configureMenu(); - super.onCreateOptionsMenu(menu, inflater); - getActivity().onCreateOptionsMenu(menu); + }); } + } - private boolean isConnectivityAvailable() { - return Network.isConnectivityAvailable(getActivity()) || Network.isWifiConnected(getActivity()); - } + private boolean canChangeInterface() { + return mIfaces.length > 1 || (mOfflineMode && isAnyNetInterfaceAvailable); + } - public void configureMenu() { - if (mMenu == null) - return; - mMenu.findItem(R.id.add).setVisible(isAnyNetInterfaceAvailable); - mMenu.findItem(R.id.scan).setVisible(mHaveAnyWifiInterface); - mMenu.findItem(R.id.wifi_ifaces).setEnabled(canChangeInterface()); - mMenu.findItem(R.id.new_session).setEnabled(isAnyNetInterfaceAvailable); - mMenu.findItem(R.id.save_session).setEnabled(isAnyNetInterfaceAvailable); - mMenu.findItem(R.id.restore_session).setEnabled(isAnyNetInterfaceAvailable); + private boolean haveInterface(String ifname) { + for (String s : mIfaces) { + if (s.equals(ifname)) + return true; } + return false; + } - @Override - public void onPrepareOptionsMenu(Menu menu) { - super.onPrepareOptionsMenu(menu); - MenuItem item = menu.findItem(R.id.ss_monitor); + private void onNetworkInterfaceChanged() { + String toastMessage = null; - Services.getNetworkRadar().buildMenuItem(item); + stopNetworkRadar(); - item = menu.findItem(R.id.ss_msfrpcd); + if (!System.reloadNetworkMapping()) { + String ifname = System.getIfname(); - Services.getMsfRpcdService().buildMenuItem(item); + ifname = ifname == null ? getString(R.string.any_interface) : ifname; - mMenu = menu; - getActivity().onPrepareOptionsMenu(menu); + toastMessage = String.format(getString(R.string.error_initializing_interface), ifname); + } else { + startNetworkRadar(); + registerPlugins(); } - private boolean initSystem() { - // retry - try { - System.init(getActivity().getApplicationContext()); - } catch (Exception e) { - boolean isFatal = !(e instanceof NoRouteToHostException); - - if (isFatal) { - System.errorLogging(e); - onInitializationError(System.getLastError()); - } + final String msg = toastMessage; - return !isFatal; + getActivity().runOnUiThread(new Runnable() { + @Override + public void run() { + if (msg != null) { + Toast.makeText(getActivity(), msg, Toast.LENGTH_LONG).show(); } - - registerPlugins(); - return true; + notifyMenuChanged(); + } + }); + } + + private void onConnectionLost() { + if (mOfflineMode) + return; + + mOfflineMode = true; + + stopNetworkRadar(); + System.markNetworkAsDisconnected(); + + getActivity().runOnUiThread(new Runnable() { + @Override + public void run() { + new ConfirmDialog(getString(R.string.connection_lost), + getString(R.string.connection_lost_prompt), getActivity(), + new ConfirmDialogListener() { + @Override + public void onConfirm() { + mOfflineMode = false; + System.setIfname(null); + onNetworkInterfaceChanged(); + } + + @Override + public void onCancel() { + } + }).show(); + } + }); + } + + private void onConnectionResumed() { + if (!mOfflineMode) + return; + mOfflineMode = false; + System.markInitialNetworkTargetsAsConnected(); + startNetworkRadar(); + } + + /** + * Displays a dialog for choose a network interface + * + * @param forceDialog forces to show the dialog even if there's only one interface + */ + private void displayNetworkInterfaces(final boolean forceDialog) { + // reload the interfaces list if we've invoked the dialog from the menu + loadInterfaces(); + boolean autoload = !forceDialog && mIfaces.length == 1; + + if (autoload) { + System.setIfname(mIfaces[0]); + onNetworkInterfaceChanged(); + } else if (isAnyNetInterfaceAvailable) { + String title = getString(R.string.iface_dialog_title); + + new ListChoiceDialog(title, mIfaces, getActivity(), new ChoiceDialog.ChoiceDialogListener() { + @Override + public void onChoice(int index) { + System.setIfname(mIfaces[index]); + onNetworkInterfaceChanged(); + } + }).show(); + } else { + new ErrorDialog(getString(android.R.string.dialog_alert_title), + getString(R.string.iface_error_no_available), getActivity()).show(); + } + } + + private void displayNetworkInterfaces() { + displayNetworkInterfaces(false); + } + + private void targetAliasPrompt(final Target target) { + + new InputDialog(getString(R.string.target_alias), + getString(R.string.set_alias), + target.hasAlias() ? target.getAlias() : "", true, + false, getActivity(), new InputDialogListener() { + @Override + public void onInputEntered(String input) { + target.setAlias(input); + mTargetAdapter.notifyDataSetChanged(); + } + }).show(); + } + + private ActionMode.Callback mActionModeCallback = new ActionMode.Callback() { + + public boolean onCreateActionMode(ActionMode mode, Menu menu) { + MenuInflater inflater = mode.getMenuInflater(); + inflater.inflate(R.menu.main_multi, menu); + return true; } - private void registerPlugins() { - if (!System.getPlugins().isEmpty()) - return; - - System.registerPlugin(new RouterPwn()); - System.registerPlugin(new Traceroute()); - System.registerPlugin(new PortScanner()); - System.registerPlugin(new Inspector()); - System.registerPlugin(new ExploitFinder()); - System.registerPlugin(new LoginCracker()); - System.registerPlugin(new Sessions()); - System.registerPlugin(new MITM()); - System.registerPlugin(new PacketForger()); + public boolean onPrepareActionMode(ActionMode mode, Menu menu) { + int i = mTargetAdapter.getSelectedCount(); + mode.setTitle(i + " " + getString((i > 1 ? R.string.targets_selected : R.string.target_selected))); + MenuItem item = menu.findItem(R.id.multi_action); + if (item != null) + item.setIcon((i > 1 ? android.R.drawable.ic_dialog_dialer : android.R.drawable.ic_menu_edit)); + return false; } - private void loadInterfaces() { - boolean menuChanged; - List interfaces = Network.getAvailableInterfaces(); - int size = interfaces.size(); + public boolean onActionItemClicked(ActionMode mode, MenuItem item) { + ArrayList commonPlugins = null; + + switch (item.getItemId()) { + case R.id.multi_action: + final int[] selected = mTargetAdapter.getSelectedPositions(); + if (selected.length > 1) { + Target target = (Target) mTargetAdapter.getItem(selected[0]); + commonPlugins = System.getPluginsForTarget(target); + for (int i = 1; i < selected.length; i++) { + target = (Target) mTargetAdapter.getItem(selected[i]); + ArrayList targetPlugins = System.getPluginsForTarget(target); + ArrayList removeThem = new ArrayList(); + for (Plugin p : commonPlugins) { + if (!targetPlugins.contains(p)) + removeThem.add(p); + } + for (Plugin p : removeThem) { + commonPlugins.remove(p); + } + } + if (commonPlugins.size() > 0) { + final int[] actions = new int[commonPlugins.size()]; + for (int i = 0; i < actions.length; i++) + actions[i] = commonPlugins.get(i).getName(); - if (mIfaces != null) { - menuChanged = mIfaces.length != size; - menuChanged &= mIfaces.length <= 1 || size <= 1; - } else { - menuChanged = true; - } + (new MultipleChoiceDialog(R.string.choose_method, actions, getActivity(), new MultipleChoiceDialog.MultipleChoiceDialogListener() { + @Override + public void onChoice(int[] choices) { + Intent intent = new Intent(getActivity(), MultiAttackService.class); + int[] selectedActions = new int[choices.length]; - mIfaces = new String[size]; - interfaces.toArray(mIfaces); - isAnyNetInterfaceAvailable = mIfaces.length > 0; + for (int i = 0; i < selectedActions.length; i++) + selectedActions[i] = actions[choices[i]]; - if (menuChanged) { - getActivity().runOnUiThread(new Runnable() { - @Override - public void run() { - notifyMenuChanged(); + intent.putExtra(MultiAttackService.MULTI_TARGETS, selected); + intent.putExtra(MultiAttackService.MULTI_ACTIONS, selectedActions); + + getActivity().startService(intent); } - }); - } + })).show(); + } else { + (new ErrorDialog(getString(R.string.error), "no common actions found", getActivity())).show(); + } + } else { + targetAliasPrompt((Target) mTargetAdapter.getItem(selected[0])); + } + mode.finish(); // Action picked, so close the CAB + return true; + default: + return false; + } } - private boolean canChangeInterface() { - return mIfaces.length > 1 || (mOfflineMode && isAnyNetInterfaceAvailable); + // called when the user exits the action mode + public void onDestroyActionMode(ActionMode mode) { + mActionMode = null; + mTargetAdapter.clearSelection(); } + }; - private boolean haveInterface(String ifname) { - for (String s : mIfaces) { - if (s.equals(ifname)) - return true; - } - return false; + public void startUpdateChecker() { + if (!isConnectivityAvailable() || mIsUpdateDownloading) + return; + Services.getUpdateService().start(); + } + + public void startNetworkRadar() { + if (!isAnyNetInterfaceAvailable || !mIsDaemonBeating) { + return; } + ThreadHelper.getSharedExecutor().execute(new Runnable() { + @Override + public void run() { + Services.getNetworkRadar().start(); + } + }); + } + + public void stopNetworkRadar() { + ThreadHelper.getSharedExecutor().execute(new Runnable() { + @Override + public void run() { + Services.getNetworkRadar().stop(); + } + }); + } + + /** + * start MSF RPC Daemon + */ + public void startRPCServer() { + ThreadHelper.getSharedExecutor().execute(new Runnable() { + @Override + public void run() { + if (Services.getMsfRpcdService().isAvailable()) + Services.getMsfRpcdService().start(); + } + }); + } + + /** + * stop MSF RPC Daemon + */ + public void StopRPCServer() { + ThreadHelper.getSharedExecutor().execute(new Runnable() { + @Override + public void run() { + Services.getMsfRpcdService().stop(); + } + }); + } + + @Override + public boolean onOptionsItemSelected(final MenuItem item) { + switch (item.getItemId()) { + + case R.id.add: + new InputDialog(getString(R.string.add_custom_target), + getString(R.string.enter_url), getActivity(), + new InputDialogListener() { + @Override + public void onInputEntered(String input) { + final Target target = Target.getFromString(input); + if (target != null) { + ThreadHelper.getSharedExecutor().execute(new Runnable() { + @Override + public void run() { + System.addOrderedTarget(target); + } + }); + } else + new ErrorDialog(getString(R.string.error), + getString(R.string.invalid_target), + getActivity()).show(); + } + }).show(); + return true; - private void onNetworkInterfaceChanged() { - String toastMessage = null; + case R.id.scan: + startNetworkRadar(); + return true; + case R.id.wifi_ifaces: + displayNetworkInterfaces(true); + return true; + + case R.id.wifi_scan: stopNetworkRadar(); - if (!System.reloadNetworkMapping()) { - String ifname = System.getIfname(); + mRadarReceiver.unregister(); + mUpdateReceiver.unregister(); - ifname = ifname == null ? getString(R.string.any_interface) : ifname; + FragmentHelper.switchToFragment(this, WifiScannerFragment.class); + return true; - toastMessage = String.format(getString(R.string.error_initializing_interface), ifname); - } else { - startNetworkRadar(); - registerPlugins(); - } + case R.id.new_session: + new ConfirmDialog(getString(R.string.warning), + getString(R.string.warning_new_session), getActivity(), + new ConfirmDialogListener() { + @Override + public void onConfirm() { + try { + System.reset(); + + Toast.makeText( + getActivity(), + getString(R.string.new_session_started), + Toast.LENGTH_SHORT).show(); + } catch (Exception e) { + new FatalDialog(getString(R.string.error), e + .toString(), getActivity()).show(); + } + } - final String msg = toastMessage; + @Override + public void onCancel() { + } - getActivity().runOnUiThread(new Runnable() { - @Override - public void run() { - if (msg != null) { - Toast.makeText(getActivity(), msg, Toast.LENGTH_LONG).show(); - } - notifyMenuChanged(); - } - }); - } + }).show(); - private void onConnectionLost() { - if (mOfflineMode) - return; + return true; - mOfflineMode = true; + case R.id.save_session: + new InputDialog(getString(R.string.save_session), + getString(R.string.enter_session_name), + System.getSessionName(), true, false, getActivity(), + new InputDialogListener() { + @Override + public void onInputEntered(String input) { + String name = input.trim().replace("/", "") + .replace("..", ""); + + if (!name.isEmpty()) { + try { + String filename = System.saveSession(name); + + Toast.makeText( + getActivity(), + getString(R.string.session_saved_to) + + filename + " .", + Toast.LENGTH_SHORT).show(); + } catch (IOException e) { + new ErrorDialog(getString(R.string.error), + e.toString(), getActivity()) + .show(); + } + } else + new ErrorDialog(getString(R.string.error), + getString(R.string.invalid_session), + getActivity()).show(); + } + }).show(); + return true; - stopNetworkRadar(); - System.markNetworkAsDisconnected(); + case R.id.restore_session: + final ArrayList sessions = System + .getAvailableSessionFiles(); - getActivity().runOnUiThread(new Runnable() { + if (sessions != null && sessions.size() > 0) { + new SpinnerDialog(getString(R.string.select_session), + getString(R.string.select_session_file), + sessions.toArray(new String[sessions.size()]), + getActivity(), new SpinnerDialogListener() { @Override - public void run() { - new ConfirmDialog(getString(R.string.connection_lost), - getString(R.string.connection_lost_prompt), getActivity(), - new ConfirmDialogListener() { - @Override - public void onConfirm() { - mOfflineMode = false; - System.setIfname(null); - onNetworkInterfaceChanged(); - } - - @Override - public void onCancel() { - } - }).show(); + public void onItemSelected(int index) { + String session = sessions.get(index); + + try { + System.loadSession(session); + } catch (Exception e) { + e.printStackTrace(); + new ErrorDialog(getString(R.string.error), + e.getMessage(), getActivity()) + .show(); + } } - }); - } + }).show(); + } else + new ErrorDialog(getString(R.string.error), + getString(R.string.no_session_found), getActivity()) + .show(); + return true; - private void onConnectionResumed() { - if (!mOfflineMode) - return; - mOfflineMode = false; - System.markInitialNetworkTargetsAsConnected(); - startNetworkRadar(); - } + case R.id.ss_monitor: + new Thread(new Runnable() { + @Override + public void run() { + Services.getNetworkRadar().onMenuClick(getActivity(), item); + } + }).start(); + return true; - /** - * Displays a dialog for choose a network interface - * - * @param forceDialog forces to show the dialog even if there's only one interface - */ - private void displayNetworkInterfaces(final boolean forceDialog) { - // reload the interfaces list if we've invoked the dialog from the menu - loadInterfaces(); - boolean autoload = !forceDialog && mIfaces.length == 1; - - if (autoload) { - System.setIfname(mIfaces[0]); - onNetworkInterfaceChanged(); - } else if (isAnyNetInterfaceAvailable) { - String title = getString(R.string.iface_dialog_title); + case R.id.ss_msfrpcd: + new Thread(new Runnable() { + @Override + public void run() { + Services.getMsfRpcdService().onMenuClick(getActivity(), item); + } + }).start(); + return true; - new ListChoiceDialog(title, mIfaces, getActivity(), new ChoiceDialog.ChoiceDialogListener() { + default: + return super.onOptionsItemSelected(item); + } + } + + public void onBackPressed() { + if (mLastBackPressTime < java.lang.System.currentTimeMillis() - 4000) { + mToast = Toast.makeText(getActivity(), getString(R.string.press_back), + Toast.LENGTH_SHORT); + mToast.show(); + mLastBackPressTime = java.lang.System.currentTimeMillis(); + } else { + if (mToast != null) + mToast.cancel(); + + new ConfirmDialog(getString(R.string.exit), + getString(R.string.close_confirm), getActivity(), + new ConfirmDialogListener() { @Override - public void onChoice(int index) { - System.setIfname(mIfaces[index]); - onNetworkInterfaceChanged(); + public void onConfirm() { + getActivity().finish(); } - }).show(); - } else { - new ErrorDialog(getString(android.R.string.dialog_alert_title), - getString(R.string.iface_error_no_available), getActivity()).show(); - } - } - - private void displayNetworkInterfaces() { - displayNetworkInterfaces(false); - } - private void targetAliasPrompt(final Target target) { + @Override + public void onCancel() { + } + }).show(); - new InputDialog(getString(R.string.target_alias), - getString(R.string.set_alias), - target.hasAlias() ? target.getAlias() : "", true, - false, getActivity(), new InputDialogListener() { - @Override - public void onInputEntered(String input) { - target.setAlias(input); - mTargetAdapter.notifyDataSetChanged(); - } - }).show(); + mLastBackPressTime = 0; } + } - private ActionMode.Callback mActionModeCallback = new ActionMode.Callback() { - - public boolean onCreateActionMode(ActionMode mode, Menu menu) { - MenuInflater inflater = mode.getMenuInflater(); - inflater.inflate(R.menu.main_multi, menu); - return true; - } + @Override + public void onDestroy() { + stopNetworkRadar(); + StopRPCServer(); - public boolean onPrepareActionMode(ActionMode mode, Menu menu) { - int i = mTargetAdapter.getSelectedCount(); - mode.setTitle(i + " " + getString((i > 1 ? R.string.targets_selected : R.string.target_selected))); - MenuItem item = menu.findItem(R.id.multi_action); - if (item != null) - item.setIcon((i > 1 ? android.R.drawable.ic_dialog_dialer : android.R.drawable.ic_menu_edit)); - return false; - } + mRadarReceiver.unregister(); + mUpdateReceiver.unregister(); + mWipeReceiver.unregister(); + mMsfReceiver.unregister(); + mConnectivityReceiver.unregister(); - public boolean onActionItemClicked(ActionMode mode, MenuItem item) { - ArrayList commonPlugins = null; - - switch (item.getItemId()) { - case R.id.multi_action: - final int[] selected = mTargetAdapter.getSelectedPositions(); - if (selected.length > 1) { - Target target = (Target) mTargetAdapter.getItem(selected[0]); - commonPlugins = System.getPluginsForTarget(target); - for (int i = 1; i < selected.length; i++) { - target = (Target) mTargetAdapter.getItem(selected[i]); - ArrayList targetPlugins = System.getPluginsForTarget(target); - ArrayList removeThem = new ArrayList(); - for (Plugin p : commonPlugins) { - if (!targetPlugins.contains(p)) - removeThem.add(p); - } - for (Plugin p : removeThem) { - commonPlugins.remove(p); - } - } - if (commonPlugins.size() > 0) { - final int[] actions = new int[commonPlugins.size()]; - for (int i = 0; i < actions.length; i++) - actions[i] = commonPlugins.get(i).getName(); - - (new MultipleChoiceDialog(R.string.choose_method, actions, getActivity(), new MultipleChoiceDialog.MultipleChoiceDialogListener() { - @Override - public void onChoice(int[] choices) { - Intent intent = new Intent(getActivity(), MultiAttackService.class); - int[] selectedActions = new int[choices.length]; - - for (int i = 0; i < selectedActions.length; i++) - selectedActions[i] = actions[choices[i]]; - - intent.putExtra(MultiAttackService.MULTI_TARGETS, selected); - intent.putExtra(MultiAttackService.MULTI_ACTIONS, selectedActions); - - getActivity().startService(intent); - } - })).show(); - } else { - (new ErrorDialog(getString(R.string.error), "no common actions found", getActivity())).show(); - } - } else { - targetAliasPrompt((Target) mTargetAdapter.getItem(selected[0])); - } - mode.finish(); // Action picked, so close the CAB - return true; - default: - return false; - } - } + // make sure no zombie process is running before destroying the activity + System.clean(true); - // called when the user exits the action mode - public void onDestroyActionMode(ActionMode mode) { - mActionMode = null; - mTargetAdapter.clearSelection(); - } - }; + super.onDestroy(); + } - public void startUpdateChecker() { - if (!isConnectivityAvailable() || mIsUpdateDownloading) - return; - if (System.getSettings().getBoolean("PREF_CHECK_UPDATES", true)) { - new UpdateChecker(getActivity()).start(); - mIsUpdateDownloading = true; - } else { - getActivity().sendBroadcast(new Intent(UPDATE_NOT_AVAILABLE)); - mIsUpdateDownloading = false; - } - } + public class TargetAdapter extends BaseAdapter implements Runnable, Observer { - public void startNetworkRadar() { - if (!isAnyNetInterfaceAvailable || !mIsDaemonBeating) { - return; - } - ThreadHelper.getSharedExecutor().execute(new Runnable() { - @Override - public void run() { - Services.getNetworkRadar().start(); - } - }); - } + private List list = System.getTargets(); + private boolean isDark = getActivity().getSharedPreferences("THEME", 0).getBoolean("isDark", false); - public void stopNetworkRadar() { - ThreadHelper.getSharedExecutor().execute(new Runnable() { - @Override - public void run() { - Services.getNetworkRadar().stop(); - } - }); + @Override + public int getCount() { + return list.size(); } - /** - * start MSF RPC Daemon - */ - public void startRPCServer() { - ThreadHelper.getSharedExecutor().execute(new Runnable() { - @Override - public void run() { - if (Services.getMsfRpcdService().isAvailable()) - Services.getMsfRpcdService().start(); - } - }); + @Override + public Object getItem(int position) { + return list.get(position); } - /** - * stop MSF RPC Daemon - */ - public void StopRPCServer() { - ThreadHelper.getSharedExecutor().execute(new Runnable() { - @Override - public void run() { - Services.getMsfRpcdService().stop(); - } - }); + @Override + public long getItemId(int position) { + return R.layout.target_list_item; } @Override - public boolean onOptionsItemSelected(final MenuItem item) { - switch (item.getItemId()) { - - case R.id.add: - new InputDialog(getString(R.string.add_custom_target), - getString(R.string.enter_url), getActivity(), - new InputDialogListener() { - @Override - public void onInputEntered(String input) { - final Target target = Target.getFromString(input); - if (target != null) { - ThreadHelper.getSharedExecutor().execute(new Runnable() { - @Override - public void run() { - System.addOrderedTarget(target); - } - }); - } else - new ErrorDialog(getString(R.string.error), - getString(R.string.invalid_target), - getActivity()).show(); - } - }).show(); - return true; - - case R.id.scan: - startNetworkRadar(); - return true; - - case R.id.wifi_ifaces: - displayNetworkInterfaces(true); - return true; - - case R.id.wifi_scan: - stopNetworkRadar(); - - mRadarReceiver.unregister(); - mUpdateReceiver.unregister(); - - startActivityForResult(new Intent(getActivity(), - WifiScannerActivity.class), WIFI_CONNECTION_REQUEST); - getActivity().overridePendingTransition(R.anim.fadeout, R.anim.fadein); - return true; - - case R.id.new_session: - new ConfirmDialog(getString(R.string.warning), - getString(R.string.warning_new_session), getActivity(), - new ConfirmDialogListener() { - @Override - public void onConfirm() { - try { - System.reset(); - - Toast.makeText( - getActivity(), - getString(R.string.new_session_started), - Toast.LENGTH_SHORT).show(); - } catch (Exception e) { - new FatalDialog(getString(R.string.error), e - .toString(), getActivity()).show(); - } - } - - @Override - public void onCancel() { - } - - }).show(); - - return true; - - case R.id.save_session: - new InputDialog(getString(R.string.save_session), - getString(R.string.enter_session_name), - System.getSessionName(), true, false, getActivity(), - new InputDialogListener() { - @Override - public void onInputEntered(String input) { - String name = input.trim().replace("/", "") - .replace("..", ""); - - if (!name.isEmpty()) { - try { - String filename = System.saveSession(name); - - Toast.makeText( - getActivity(), - getString(R.string.session_saved_to) - + filename + " .", - Toast.LENGTH_SHORT).show(); - } catch (IOException e) { - new ErrorDialog(getString(R.string.error), - e.toString(), getActivity()) - .show(); - } - } else - new ErrorDialog(getString(R.string.error), - getString(R.string.invalid_session), - getActivity()).show(); - } - }).show(); - return true; - - case R.id.restore_session: - final ArrayList sessions = System - .getAvailableSessionFiles(); - - if (sessions != null && sessions.size() > 0) { - new SpinnerDialog(getString(R.string.select_session), - getString(R.string.select_session_file), - sessions.toArray(new String[sessions.size()]), - getActivity(), new SpinnerDialogListener() { - @Override - public void onItemSelected(int index) { - String session = sessions.get(index); - - try { - System.loadSession(session); - } catch (Exception e) { - e.printStackTrace(); - new ErrorDialog(getString(R.string.error), - e.getMessage(), getActivity()) - .show(); - } - } - }).show(); - } else - new ErrorDialog(getString(R.string.error), - getString(R.string.no_session_found), getActivity()) - .show(); - return true; - - case R.id.settings: - startActivity(new Intent(getActivity(), SettingsActivity.class)); - getActivity().overridePendingTransition(R.anim.fadeout, R.anim.fadein); - return true; - - case R.id.ss_monitor: - new Thread(new Runnable() { - @Override - public void run() { - Services.getNetworkRadar().onMenuClick(getActivity(), item); - } - }).start(); - return true; - - case R.id.ss_msfrpcd: - new Thread(new Runnable() { - @Override - public void run() { - Services.getMsfRpcdService().onMenuClick(getActivity(), item); - } - }).start(); - return true; - - case R.id.submit_issue: - String uri = getString(R.string.github_new_issue_url); - Intent browser = new Intent(Intent.ACTION_VIEW, Uri.parse(uri)); - startActivity(browser); - // for fat-tire: - // String.format(getString(R.string.issue_message), getString(R.string.github_issues_url), getString(R.string.github_new_issue_url)); - return true; - - case R.id.about: - new AboutDialog(getActivity()).show(); - return true; - - default: - return super.onOptionsItemSelected(item); - } + public View getView(int position, View convertView, ViewGroup parent) { + View row = convertView; + TargetHolder holder; + Object tag = row != null ? row.getTag() : null; + + if (row == null || tag == null || !(tag instanceof TargetHolder)) { + LayoutInflater inflater = (LayoutInflater) getActivity() + .getSystemService(Context.LAYOUT_INFLATER_SERVICE); + row = inflater.inflate(R.layout.target_list_item, parent, false); + + if (isDark) + row.setBackgroundResource(R.drawable.card_background_dark); + + holder = new TargetHolder(); + holder.itemImage = (ImageView) row.findViewById(R.id.itemIcon); + holder.itemTitle = (TextView) row.findViewById(R.id.itemTitle); + holder.itemDescription = (TextView) row.findViewById(R.id.itemDescription); + holder.portCount = (TextView) row.findViewById(R.id.portCount); + holder.portCountLayout = (LinearLayout) row.findViewById(R.id.portCountLayout); + if (isDark) + holder.portCountLayout.setBackgroundResource(R.drawable.rounded_square_grey); + row.setTag(holder); + } else { + holder = (TargetHolder) tag; + } + + final Target target = list.get(position); + + if (target.hasAlias()) { + holder.itemTitle.setText(Html.fromHtml("" + + target.getAlias() + " ( " + + target.getDisplayAddress() + " )")); + } else { + holder.itemTitle.setText(target.toString()); + } + holder.itemTitle.setTextColor(ContextCompat.getColor(getActivity().getApplicationContext(), (target.isConnected() ? R.color.app_color : R.color.gray_text))); + + holder.itemTitle.setTypeface(null, Typeface.NORMAL); + holder.itemImage.setImageResource(target.getDrawableResourceId()); + holder.itemDescription.setText(target.getDescription()); + + int openedPorts = target.getOpenPorts().size(); + + holder.portCount.setText(String.format("%d", openedPorts)); + holder.portCountLayout.setVisibility(openedPorts < 1 ? View.GONE : View.VISIBLE); + return row; } - public void onBackPressed() { - if (mLastBackPressTime < java.lang.System.currentTimeMillis() - 4000) { - mToast = Toast.makeText(getActivity(), getString(R.string.press_back), - Toast.LENGTH_SHORT); - mToast.show(); - mLastBackPressTime = java.lang.System.currentTimeMillis(); - } else { - if (mToast != null) - mToast.cancel(); - - new ConfirmDialog(getString(R.string.exit), - getString(R.string.close_confirm), getActivity(), - new ConfirmDialogListener() { - @Override - public void onConfirm() { - getActivity().finish(); - } - - @Override - public void onCancel() { - } - }).show(); - - mLastBackPressTime = 0; - } + public void clearSelection() { + synchronized (this) { + for (Target t : list) + t.setSelected(false); + } + notifyDataSetChanged(); + if (mActionMode != null) + mActionMode.finish(); } - @Override - public void onDestroy() { - stopNetworkRadar(); - StopRPCServer(); - - mRadarReceiver.unregister(); - mUpdateReceiver.unregister(); - mWipeReceiver.unregister(); - mMsfReceiver.unregister(); - mConnectivityReceiver.unregister(); + public void toggleSelection(int position) { + synchronized (this) { + Target t = list.get(position); + t.setSelected(!t.isSelected()); + } + notifyDataSetChanged(); + if (mActionMode != null) { + if (getSelectedCount() > 0) + mActionMode.invalidate(); + else + mActionMode.finish(); + } + } - // make sure no zombie process is running before destroying the activity - System.clean(true); + public int getSelectedCount() { + int i = 0; + synchronized (this) { + for (Target t : list) + if (t.isSelected()) + i++; + } + return i; + } - super.onDestroy(); + public ArrayList getSelected() { + ArrayList result = new ArrayList(); + synchronized (this) { + for (Target t : list) + if (t.isSelected()) + result.add(t); + } + return result; } - public class TargetAdapter extends BaseAdapter implements Runnable, Observer { + public int[] getSelectedPositions() { + int[] res; + int j = 0; + + synchronized (this) { + res = new int[getSelectedCount()]; + for (int i = 0; i < list.size(); i++) + if (list.get(i).isSelected()) + res[j++] = i; + } + return res; + } - private List list = System.getTargets(); - private boolean isDark = getActivity().getSharedPreferences("THEME", 0).getBoolean("isDark", false); + @Override + public void update(Observable observable, Object data) { + final Target target = (Target) data; - @Override - public int getCount() { - return list.size(); - } + if (target == null) { + // update the whole list + getActivity().runOnUiThread(this); + return; + } + // update only a row, if it's displayed + getActivity().runOnUiThread(new Runnable() { @Override - public Object getItem(int position) { - return list.get(position); + public void run() { + if (lv == null) + return; + synchronized (this) { + int start = lv.getFirstVisiblePosition(); + int end = Math.min(lv.getLastVisiblePosition(), list.size()); + for (int i = start; i <= end; i++) + if (target == list.get(i)) { + View view = lv.getChildAt(i - start); + getView(i, view, lv); + break; + } + } } + }); - @Override - public long getItemId(int position) { - return R.layout.target_list_item; - } + } - @Override - public View getView(int position, View convertView, ViewGroup parent) { - View row = convertView; - TargetHolder holder; - - if (row == null) { - LayoutInflater inflater = (LayoutInflater) getActivity() - .getSystemService(Context.LAYOUT_INFLATER_SERVICE); - row = inflater.inflate(R.layout.target_list_item, parent, false); - - if (isDark) - row.setBackgroundResource(R.drawable.card_background_dark); - - holder = new TargetHolder(); - holder.itemImage = (ImageView) (row != null ? row - .findViewById(R.id.itemIcon) : null); - holder.itemTitle = (TextView) (row != null ? row - .findViewById(R.id.itemTitle) : null); - holder.itemDescription = (TextView) (row != null ? row - .findViewById(R.id.itemDescription) : null); - holder.portCount = (TextView) (row != null ? row - .findViewById(R.id.portCount) : null); - holder.portCountLayout = (LinearLayout) (row != null ? row - .findViewById(R.id.portCountLayout) : null); - if (isDark) - holder.portCountLayout.setBackgroundResource(R.drawable.rounded_square_grey); - if (row != null) - row.setTag(holder); - } else - holder = (TargetHolder) row.getTag(); - - final Target target = list.get(position); - - if (target.hasAlias()) { - holder.itemTitle.setText(Html.fromHtml("" - + target.getAlias() + " ( " - + target.getDisplayAddress() + " )")); - } else { - holder.itemTitle.setText(target.toString()); - } - holder.itemTitle.setTextColor(ContextCompat.getColor(getActivity().getApplicationContext(), (target.isConnected() ? R.color.app_color : R.color.gray_text))); + @Override + public void run() { + synchronized (this) { + list = System.getTargets(); + } + notifyDataSetChanged(); + } - holder.itemTitle.setTypeface(null, Typeface.NORMAL); - holder.itemImage.setImageResource(target.getDrawableResourceId()); - holder.itemDescription.setText(target.getDescription()); + class TargetHolder { + ImageView itemImage; + TextView itemTitle; + TextView itemDescription; + TextView portCount; + LinearLayout portCountLayout; + } + } - int openedPorts = target.getOpenPorts().size(); + private class WipeReceiver extends ManagedReceiver { + private IntentFilter mFilter = null; - holder.portCount.setText(String.format("%d", openedPorts)); - holder.portCountLayout.setVisibility(openedPorts < 1 ? View.GONE : View.VISIBLE); - return row; - } + public WipeReceiver() { + mFilter = new IntentFilter(); - public void clearSelection() { - synchronized (this) { - for (Target t : list) - t.setSelected(false); - } - notifyDataSetChanged(); - if (mActionMode != null) - mActionMode.finish(); - } + mFilter.addAction(SettingsFragment.SETTINGS_WIPE_START); + } - public void toggleSelection(int position) { - synchronized (this) { - Target t = list.get(position); - t.setSelected(!t.isSelected()); - } - notifyDataSetChanged(); - if (mActionMode != null) { - if (getSelectedCount() > 0) - mActionMode.invalidate(); - else - mActionMode.finish(); - } - } + public IntentFilter getFilter() { + return mFilter; + } - public int getSelectedCount() { - int i = 0; - synchronized (this) { - for (Target t : list) - if (t.isSelected()) - i++; - } - return i; - } + @Override + public void onReceive(Context context, Intent intent) { - public ArrayList getSelected() { - ArrayList result = new ArrayList(); - synchronized (this) { - for (Target t : list) - if (t.isSelected()) - result.add(t); - } - return result; - } + if (intent.getAction().equals(SettingsFragment.SETTINGS_WIPE_START)) { + try { + String path; - public int[] getSelectedPositions() { - int[] res; - int j = 0; + if (intent.hasExtra(SettingsFragment.SETTINGS_WIPE_DIR)) { + path = intent.getStringExtra(SettingsFragment.SETTINGS_WIPE_DIR); + } else { + path = System.getRubyPath() + "' '" + System.getMsfPath(); + } - synchronized (this) { - res = new int[getSelectedCount()]; - for (int i = 0; i < list.size(); i++) - if (list.get(i).isSelected()) - res[j++] = i; + StopRPCServer(); + System.getTools().raw.async("rm -rf '" + path + "'", new Child.EventReceiver() { + @Override + public void onEnd(int exitCode) { + getActivity().sendBroadcast(new Intent(SettingsFragment.SETTINGS_WIPE_DONE)); } - return res; - } - @Override - public void update(Observable observable, Object data) { - final Target target = (Target) data; - - if (target == null) { - // update the whole list - getActivity().runOnUiThread(this); - return; + @Override + public void onDeath(int signal) { + getActivity().sendBroadcast(new Intent(SettingsFragment.SETTINGS_WIPE_DONE)); } - // update only a row, if it's displayed - getActivity().runOnUiThread(new Runnable() { - @Override - public void run() { - if (lv == null) - return; - synchronized (this) { - int start = lv.getFirstVisiblePosition(); - int end = Math.min(lv.getLastVisiblePosition(), list.size()); - for (int i = start; i <= end; i++) - if (target == list.get(i)) { - View view = lv.getChildAt(i - start); - getView(i, view, lv); - break; - } - } - } - }); - - } - - @Override - public void run() { - synchronized (this) { - list = System.getTargets(); + @Override + public void onEvent(Event e) { } - notifyDataSetChanged(); - } - - class TargetHolder { - ImageView itemImage; - TextView itemTitle; - TextView itemDescription; - TextView portCount; - LinearLayout portCountLayout; + }); + } catch (Exception e) { + System.errorLogging(e); } + } } + } - private class WipeReceiver extends ManagedReceiver { - private IntentFilter mFilter = null; + private class UpdateReceiver extends ManagedReceiver { + private IntentFilter mFilter = null; - public WipeReceiver() { - mFilter = new IntentFilter(); + public UpdateReceiver() { + mFilter = new IntentFilter(); - mFilter.addAction(SettingsFragment.SETTINGS_WIPE_START); - } + mFilter.addAction(UPDATE_CHECKING); + mFilter.addAction(UPDATE_AVAILABLE); + mFilter.addAction(UPDATE_NOT_AVAILABLE); + mFilter.addAction(UpdateInstaller.ERROR); + mFilter.addAction(UpdateInstaller.DONE); + } - public IntentFilter getFilter() { - return mFilter; - } + public IntentFilter getFilter() { + return mFilter; + } + private void onUpdateAvailable(final Update update, final boolean mandatory) { + getActivity().runOnUiThread(new Runnable() { @Override - public void onReceive(Context context, Intent intent) { - - if (intent.getAction().equals(SettingsFragment.SETTINGS_WIPE_START)) { - try { - String path; - - if (intent.hasExtra(SettingsFragment.SETTINGS_WIPE_DIR)) { - path = intent.getStringExtra(SettingsFragment.SETTINGS_WIPE_DIR); - } else { - path = System.getRubyPath() + "' '" + System.getMsfPath(); - } - - StopRPCServer(); - System.getTools().raw.async("rm -rf '" + path + "'", new Child.EventReceiver() { - @Override - public void onEnd(int exitCode) { - getActivity().sendBroadcast(new Intent(SettingsFragment.SETTINGS_WIPE_DONE)); - } + public void run() { + new ConfirmDialog(getString(R.string.update_available), + update.prompt, getActivity(), new ConfirmDialogListener() { + @Override + public void onConfirm() { + StopRPCServer(); + Intent i = new Intent(getActivity(), UpdateInstaller.class); + i.setAction(UpdateInstaller.START); + i.putExtra(UpdateInstaller.UPDATE, update); + + getActivity().startService(i); + mIsUpdateDownloading = true; + } - @Override - public void onDeath(int signal) { - getActivity().sendBroadcast(new Intent(SettingsFragment.SETTINGS_WIPE_DONE)); - } + @Override + public void onCancel() { + mIsUpdateDownloading = false; + if (!mandatory) { + return; + } - @Override - public void onEvent(Event e) { - } - }); - } catch (Exception e) { - System.errorLogging(e); - } + onInitializationError(getString(R.string.mandatory_update)); } + } + ).show(); } + }); } - private class UpdateReceiver extends ManagedReceiver { - private IntentFilter mFilter = null; - - public UpdateReceiver() { - mFilter = new IntentFilter(); - - mFilter.addAction(UPDATE_CHECKING); - mFilter.addAction(UPDATE_AVAILABLE); - mFilter.addAction(UPDATE_NOT_AVAILABLE); - mFilter.addAction(UpdateService.ERROR); - mFilter.addAction(UpdateService.DONE); - } - - public IntentFilter getFilter() { - return mFilter; - } + private void onUpdateAvailable(Update update) { + onUpdateAvailable(update, (update instanceof CoreUpdate) && !System.isCoreInstalled()); + } - private void onUpdateAvailable(final Update update, final boolean mandatory) { - getActivity().runOnUiThread(new Runnable() { - @Override - public void run() { - new ConfirmDialog(getString(R.string.update_available), - update.prompt, getActivity(), new ConfirmDialogListener() { - @Override - public void onConfirm() { - StopRPCServer(); - Intent i = new Intent(getActivity(), UpdateService.class); - i.setAction(UpdateService.START); - i.putExtra(UpdateService.UPDATE, update); - - getActivity().startService(i); - mIsUpdateDownloading = true; - } + private void onUpdateDone(Update update) { - @Override - public void onCancel() { - mIsUpdateDownloading = false; - if (!mandatory) { - return; - } + mIsUpdateDownloading = false; - onInitializationError(getString(R.string.mandatory_update)); - } - } - ).show(); - } - }); - } + System.reloadTools(); - private void onUpdateAvailable(Update update) { - onUpdateAvailable(update, (update instanceof CoreUpdate) && !System.isCoreInstalled()); - } + if ((update instanceof MsfUpdate) || (update instanceof RubyUpdate)) { + startRPCServer(); + } - private void onUpdateDone(Update update) { + if (update instanceof CoreUpdate) { + onCoreUpdated(); + } - mIsUpdateDownloading = false; + // restart update checker after a successful update + startUpdateChecker(); + } - System.reloadTools(); + private void onUpdateError(final Update update, final int message) { - if ((update instanceof MsfUpdate) || (update instanceof RubyUpdate)) { - startRPCServer(); - } + mIsUpdateDownloading = false; - if (update instanceof CoreUpdate) { - onCoreUpdated(); - } + if (update instanceof CoreUpdate) { + onInitializationError(getString(message)); + return; + } - // restart update checker after a successful update - startUpdateChecker(); + getActivity().runOnUiThread(new Runnable() { + @Override + public void run() { + new ErrorDialog(getString(R.string.error), + getString(message), getActivity()).show(); } + }); - private void onUpdateError(final Update update, final int message) { - - mIsUpdateDownloading = false; - - if (update instanceof CoreUpdate) { - onInitializationError(getString(message)); - return; - } - - getActivity().runOnUiThread(new Runnable() { - @Override - public void run() { - new ErrorDialog(getString(R.string.error), - getString(message), getActivity()).show(); - } - }); + System.reloadTools(); + } - System.reloadTools(); - } + @SuppressWarnings("ConstantConditions") + @Override + public void onReceive(Context context, Intent intent) { + String action = intent.getAction(); + Update update = null; + + if (intent.hasExtra(UpdateInstaller.UPDATE)) { + update = (Update) intent.getSerializableExtra(UpdateInstaller.UPDATE); + } + + switch (action) { + case UPDATE_CHECKING: + if (mEmptyTextView != null) + mEmptyTextView.setText(EMPTY_LIST_MESSAGE.replace( + "#STATUS#", getString(R.string.checking))); + break; + case UPDATE_NOT_AVAILABLE: + if (mEmptyTextView != null) + mEmptyTextView.setText(EMPTY_LIST_MESSAGE.replace( + "#STATUS#", getString(R.string.no_updates_available))); + + if (!System.isCoreInstalled()) { + onInitializationError(getString(R.string.no_core_found)); + } + break; + case UPDATE_AVAILABLE: + onUpdateAvailable(update); + break; + case UpdateInstaller.DONE: + onUpdateDone(update); + break; + case UpdateInstaller.ERROR: + int message = intent.getIntExtra(UpdateInstaller.MESSAGE, R.string.error_occured); + onUpdateError(update, message); + break; + } + } + } - @SuppressWarnings("ConstantConditions") - @Override - public void onReceive(Context context, Intent intent) { - String action = intent.getAction(); - Update update = null; + private class ConnectivityReceiver extends ManagedReceiver { + private static final int CHECK_DELAY = 2000; - if (intent.hasExtra(UpdateService.UPDATE)) { - update = (Update) intent.getSerializableExtra(UpdateService.UPDATE); - } + private final IntentFilter mFilter; + private TimerTask mTask = null; - switch (action) { - case UPDATE_CHECKING: - if (mEmptyTextView != null) - mEmptyTextView.setText(EMPTY_LIST_MESSAGE.replace( - "#STATUS#", getString(R.string.checking))); - break; - case UPDATE_NOT_AVAILABLE: - if (mEmptyTextView != null) - mEmptyTextView.setText(EMPTY_LIST_MESSAGE.replace( - "#STATUS#", getString(R.string.no_updates_available))); - - if (!System.isCoreInstalled()) { - onInitializationError(getString(R.string.no_core_found)); - } - break; - case UPDATE_AVAILABLE: - onUpdateAvailable(update); - break; - case UpdateService.DONE: - onUpdateDone(update); - break; - case UpdateService.ERROR: - int message = intent.getIntExtra(UpdateService.MESSAGE, R.string.error_occured); - onUpdateError(update, message); - break; - } - } + public ConnectivityReceiver() { + mFilter = new IntentFilter(); + mFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); } - private class ConnectivityReceiver extends ManagedReceiver { - private static final int CHECK_DELAY = 2000; - - private final IntentFilter mFilter; - private TimerTask mTask = null; + @Override + public IntentFilter getFilter() { + return mFilter; + } - public ConnectivityReceiver() { - mFilter = new IntentFilter(); - mFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); + private String ifacesToString() { + StringBuilder sb = new StringBuilder(); + for (String iface : mIfaces) { + if (sb.length() > 0) { + sb.append(", "); } + sb.append(iface); + } + return sb.toString(); + } - @Override - public IntentFilter getFilter() { - return mFilter; + @Override + public void onReceive(Context context, Intent intent) { + synchronized (this) { + if (mTask != null) { + mTask.cancel(); } + mTask = new TimerTask() { + @Override + public void run() { + check(); + } + }; + new Timer().schedule(mTask, CHECK_DELAY); + } + } - private String ifacesToString() { - StringBuilder sb = new StringBuilder(); - for (String iface : mIfaces) { - if (sb.length() > 0) { - sb.append(", "); - } - sb.append(iface); - } - return sb.toString(); + @Override + public void unregister() { + super.unregister(); + synchronized (this) { + if (mTask != null) { + mTask.cancel(); } + } + } + private void check() { + getActivity().runOnUiThread(new Runnable() { @Override - public void onReceive(Context context, Intent intent) { - synchronized (getActivity()) { - if (mTask != null) { - mTask.cancel(); - } - mTask = new TimerTask() { - @Override - public void run() { - check(); - } - }; - new Timer().schedule(mTask, CHECK_DELAY); - } - } + public void run() { + loadInterfaces(); - @Override - public void unregister() { - super.unregister(); - synchronized (getActivity()) { - if (mTask != null) { - mTask.cancel(); - } - } - } + String current = System.getIfname(); - private void check() { - synchronized (getActivity()) { - getActivity().runOnUiThread(new Runnable() { - @Override - public void run() { - loadInterfaces(); - - String current = System.getIfname(); - - Logger.debug(String.format("current='%s', ifaces=[%s], haveInterface=%s, isAnyNetInterfaceAvailable=%s", - current != null ? current : "(null)", - ifacesToString(), haveInterface(current), isAnyNetInterfaceAvailable)); - - if (haveInterface(current)) { - onConnectionResumed(); - } else if (current != null) { - onConnectionLost(); - } else if (isAnyNetInterfaceAvailable) { - onNetworkInterfaceChanged(); - } + Logger.debug(String.format("current='%s', ifaces=[%s], haveInterface=%s, isAnyNetInterfaceAvailable=%s", + current != null ? current : "(null)", + ifacesToString(), haveInterface(current), isAnyNetInterfaceAvailable)); - } - }); + if (haveInterface(current)) { + onConnectionResumed(); + } else if (current != null) { + onConnectionLost(); + } else if (isAnyNetInterfaceAvailable) { + onNetworkInterfaceChanged(); + } - mTask = null; - } } + }); + + synchronized (this) { + mTask = null; + } } + } } \ No newline at end of file diff --git a/cSploit/src/main/java/org/csploit/android/SettingsActivity.java b/cSploit/src/main/java/org/csploit/android/SettingsActivity.java index 5ff17402c5..803bfaa395 100644 --- a/cSploit/src/main/java/org/csploit/android/SettingsActivity.java +++ b/cSploit/src/main/java/org/csploit/android/SettingsActivity.java @@ -45,7 +45,4 @@ protected void onCreate(Bundle savedInstanceState) { } } - public void onBackPressed() { - f.onBackPressed(); - } } diff --git a/cSploit/src/main/java/org/csploit/android/SettingsFragment.java b/cSploit/src/main/java/org/csploit/android/SettingsFragment.java index ba6db23dd2..26dcd67166 100644 --- a/cSploit/src/main/java/org/csploit/android/SettingsFragment.java +++ b/cSploit/src/main/java/org/csploit/android/SettingsFragment.java @@ -32,7 +32,6 @@ import android.support.v7.preference.Preference; import android.support.v7.preference.PreferenceFragmentCompat; import android.support.v7.preference.TwoStatePreference; -import android.view.MenuItem; import android.view.View; import android.widget.Toast; @@ -71,7 +70,8 @@ public void onCreate(Bundle savedInstanceState) { getActivity().setTheme(R.style.PrefsTheme); super.onCreate(savedInstanceState); getActivity().getSupportFragmentManager().beginTransaction() - .replace(android.R.id.content, new PrefsFrag()) + .add(R.id.mainframe, new PrefsFrag()) + .addToBackStack(null) .commit(); } @@ -575,18 +575,6 @@ private void onMsfBranchesAvailable() { } } - @Override - public boolean onOptionsItemSelected(MenuItem item) { - switch (item.getItemId()) { - case android.R.id.home: - getActivity().onBackPressed(); - return true; - - default: - return super.onOptionsItemSelected(item); - } - } - @Override public void onDestroy() { if (mReceiver != null) { @@ -597,8 +585,4 @@ public void onDestroy() { } } - public void onBackPressed() { - getActivity().finish(); - getActivity().overridePendingTransition(R.anim.fadeout, R.anim.fadein); - } } diff --git a/cSploit/src/main/java/org/csploit/android/core/Plugin.java b/cSploit/src/main/java/org/csploit/android/core/Plugin.java index 8e411e307d..86a4a6a119 100644 --- a/cSploit/src/main/java/org/csploit/android/core/Plugin.java +++ b/cSploit/src/main/java/org/csploit/android/core/Plugin.java @@ -19,17 +19,18 @@ package org.csploit.android.core; import android.content.Context; +import android.graphics.drawable.Drawable; import android.os.Bundle; -import android.support.v7.app.AppCompatActivity; +import android.support.v4.app.Fragment; +import android.support.v4.content.ContextCompat; import android.view.MenuItem; +import android.view.View; import org.csploit.android.R; import org.csploit.android.net.Target; -import org.csploit.android.net.Target.Exploit; -import org.csploit.android.net.Target.Port; import org.csploit.android.net.metasploit.RPCClient; -public abstract class Plugin extends AppCompatActivity { +public abstract class Plugin extends Fragment { public static final int NO_LAYOUT = -1; private int mNameStringId = -1; @@ -80,26 +81,23 @@ public boolean hasLayoutToShow(){ return mLayoutId != -1; } - @Override - protected void onResume() { - super.onResume(); - } + public void onActionClick(Context context){ - @Override - protected void onPause() { - super.onPause(); - } + } - public void onActionClick(Context context){ + protected View findViewById(int id) { + return getActivity().findViewById(id); + } + protected Drawable getDrawable(int id) { + return ContextCompat.getDrawable(getActivity(), id); } @Override public void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); - setTitle(System.getCurrentTarget() + " > " + getString( mNameStringId ) ); - setContentView(mLayoutId); - getSupportActionBar().setDisplayHomeAsUpEnabled(true); + getActivity().setTitle(System.getCurrentTarget() + " > " + getString( mNameStringId ) ); + getActivity().setContentView(mLayoutId); } @Override @@ -107,7 +105,7 @@ public boolean onOptionsItemSelected(MenuItem item){ switch(item.getItemId()){ case android.R.id.home: - onBackPressed(); + onDetach(); return true; @@ -117,9 +115,9 @@ public boolean onOptionsItemSelected(MenuItem item){ } @Override - public void onBackPressed(){ - super.onBackPressed(); - overridePendingTransition(R.anim.slide_in_left, R.anim.slide_out_left); + public void onDetach() { + super.onDetach(); + getActivity().overridePendingTransition(R.anim.fadeout, R.anim.fadein); } public void onRpcChange(RPCClient currentValue) { } diff --git a/cSploit/src/main/java/org/csploit/android/core/System.java b/cSploit/src/main/java/org/csploit/android/core/System.java index 65e611323a..08ac6e47ee 100644 --- a/cSploit/src/main/java/org/csploit/android/core/System.java +++ b/cSploit/src/main/java/org/csploit/android/core/System.java @@ -34,6 +34,7 @@ import android.os.PowerManager; import android.os.PowerManager.WakeLock; import android.preference.PreferenceManager; +import android.support.annotation.Nullable; import android.util.SparseIntArray; import org.acra.ACRA; @@ -114,13 +115,13 @@ public class System { private static Network mNetwork = null; private static final SortedSet mTargets = new TreeSet<>(); private static Target mCurrentTarget = null; - private static Map mServices = null; - private static Map mPorts = null; - private static Map mVendors = null; - private static SparseIntArray mOpenPorts = null; + private static Map mServices = new HashMap<>(); + private static Map mPorts = new HashMap<>(); + private static Map mVendors = new HashMap<>(); + private static SparseIntArray mOpenPorts = new SparseIntArray(3); // registered plugins - private static ArrayList mPlugins = null; + private static ArrayList mPlugins = new ArrayList<>(); private static Plugin mCurrentPlugin = null; // toolbox singleton private static ToolBox mTools = null; @@ -144,23 +145,21 @@ public class System { private static boolean mCoreInitialized = false; - private static KnownIssues mKnownIssues = null; + private static KnownIssues mKnownIssues = new KnownIssues(); private static Observer targetListObserver = null; private final static LinkedList mSettingReceivers = new LinkedList(); - public static void init(Context context) throws Exception { + public static void setApplicationContext(Context context) { mContext = context; + } + + public static void init() throws Exception { try { Logger.debug("initializing System..."); mStoragePath = getSettings().getString("PREF_SAVE_PATH", Environment.getExternalStorageDirectory().toString()); mSessionName = "csploit-session-" + java.lang.System.currentTimeMillis(); - mKnownIssues = new KnownIssues(); - mPlugins = new ArrayList<>(); - mOpenPorts = new SparseIntArray(3); - mServices = new HashMap<>(); - mPorts = new HashMap<>(); // if we are here, network initialization didn't throw any error, lock wifi WifiManager wifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE); @@ -364,6 +363,10 @@ public static String getIfname() { return mIfname; } + public static String getDefaultIfname() { + return Network.getFirstUsableInterface(); + } + public static boolean reloadNetworkMapping() { try { uncaughtReloadNetworkMapping(); @@ -378,7 +381,7 @@ public static boolean reloadNetworkMapping() { private static void uncaughtReloadNetworkMapping() throws UnknownHostException, SocketException { mNetwork = new Network(mContext, mIfname); - mIfname = mNetwork.getInterface().getName(); + mIfname = mNetwork.getInterface(); reset(); @@ -601,30 +604,31 @@ public static void preloadServices() { } private static void preloadVendors() { - if (mVendors == null) { - try { - mVendors = new HashMap<>(); - @SuppressWarnings("ConstantConditions") - FileInputStream fstream = new FileInputStream(mContext.getFilesDir().getAbsolutePath() + "/tools/nmap/nmap-mac-prefixes"); + if(!mVendors.isEmpty()) { + return; + } - DataInputStream in = new DataInputStream(fstream); - BufferedReader reader = new BufferedReader(new InputStreamReader(in)); - String line; + try { + @SuppressWarnings("ConstantConditions") + FileInputStream fstream = new FileInputStream(mContext.getFilesDir().getAbsolutePath() + "/tools/nmap/nmap-mac-prefixes"); - while ((line = reader.readLine()) != null) { - line = line.trim(); - if (!line.startsWith("#") && !line.isEmpty()) { - String[] tokens = line.split(" ", 2); + DataInputStream in = new DataInputStream(fstream); + BufferedReader reader = new BufferedReader(new InputStreamReader(in)); + String line; - if (tokens.length == 2) - mVendors.put(NetworkHelper.getOUICode(tokens[0]), tokens[1]); - } - } + while ((line = reader.readLine()) != null) { + line = line.trim(); + if (!line.startsWith("#") && !line.isEmpty()) { + String[] tokens = line.split(" ", 2); - in.close(); - } catch (Exception e) { - errorLogging(e); + if (tokens.length == 2) + mVendors.put(NetworkHelper.getOUICode(tokens[0]), tokens[1]); + } } + + in.close(); + } catch (Exception e) { + errorLogging(e); } } @@ -633,7 +637,7 @@ public static String getSessionName() { } public static String getStoragePath() { - return mStoragePath; + return mStoragePath != null ? mStoragePath : Environment.getExternalStorageDirectory().toString(); } public static SharedPreferences getSettings() { @@ -1143,6 +1147,23 @@ public static Target getTargetByAddress(InetAddress address) { return null; } + /** + * retrieve a target from the global list by it's identifier + * @param id the target id + * @return the found target or {@code null} if not found + */ + @Nullable + public static Target getTargetById(String id) { + synchronized (mTargets) { + for(Target t : mTargets) { + if(t.getIdentifier().equals(id)) { + return t; + } + } + } + return null; + } + public static void registerPlugin(Plugin plugin) { if (mPlugins.contains(plugin)) { Logger.warning("registerPlugin() plugin " + plugin.getName() + " already added"); diff --git a/cSploit/src/main/java/org/csploit/android/gui/Console.java b/cSploit/src/main/java/org/csploit/android/gui/Console.java index 9ad404341f..3fc3d9145d 100644 --- a/cSploit/src/main/java/org/csploit/android/gui/Console.java +++ b/cSploit/src/main/java/org/csploit/android/gui/Console.java @@ -4,6 +4,7 @@ import android.os.Build; import android.os.Bundle; import android.support.design.widget.FloatingActionButton; +import android.support.v4.app.Fragment; import android.support.v7.app.AppCompatActivity; import android.text.Html; import android.view.KeyEvent; @@ -25,7 +26,7 @@ /** * this Activity allow user to run commands on pwned shells */ -public class Console extends AppCompatActivity { +public class Console extends Fragment { private EditText mInput; private TextView mOutput; @@ -38,7 +39,7 @@ private class ConsoleReceiver extends ShellSession.RpcShellReceiver { @Override public void onNewLine(final String line) { - Console.this.runOnUiThread(new Runnable() { + getActivity().runOnUiThread(new Runnable() { @Override public void run() { mOutput.append("\n" + line); @@ -49,10 +50,10 @@ public void run() { @Override public void onEnd(int exitCode) { if (exitCode != 0) - Toast.makeText(Console.this, "command returned " + exitCode, Toast.LENGTH_SHORT).show(); + Toast.makeText(getActivity(), "command returned " + exitCode, Toast.LENGTH_SHORT).show(); try { Thread.sleep(200); - Console.this.runOnUiThread(new Runnable() { + getActivity().runOnUiThread(new Runnable() { @Override public void run() { mOutput.append(Html.fromHtml("\nEnter Command:> ")); @@ -68,25 +69,23 @@ public void run() { @Override public void onRpcClosed() { - new FatalDialog("Connection lost", "RPC connection closed", Console.this).show(); + new FatalDialog("Connection lost", "RPC connection closed", getActivity()).show(); } @Override public void onTimedOut() { - new FatalDialog("Command timed out", "your submitted command generated an infinite loop or some connection error occurred.", Console.this).show(); + new FatalDialog("Command timed out", "your submitted command generated an infinite loop or some connection error occurred.", getActivity()).show(); } } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - setContentView(R.layout.console_layout); - getSupportActionBar().setDisplayHomeAsUpEnabled(true); - mInput = (EditText) findViewById(R.id.input); - mOutput = (TextView) findViewById(R.id.output); - mScrollView = (ScrollView) findViewById(R.id.outputscroll); - runButton = (FloatingActionButton) findViewById(R.id.myFAB); + mInput = (EditText) getActivity().findViewById(R.id.input); + mOutput = (TextView) getActivity().findViewById(R.id.output); + mScrollView = (ScrollView) getActivity().findViewById(R.id.outputscroll); + runButton = (FloatingActionButton) getActivity().findViewById(R.id.myFAB); // make TextView scrollable // mOutput.setMovementMethod(ScrollingMovementMethod.getInstance()); @@ -134,17 +133,15 @@ public boolean onKey(View v, int keyCode, KeyEvent event) { } @Override - public void onBackPressed() { - super.onBackPressed(); - overridePendingTransition(R.anim.slide_in_left, R.anim.slide_out_left); + public void onDetach() { + super.onDetach(); System.setCurrentSession(null); } @Override - public boolean onCreateOptionsMenu(Menu menu) { - MenuInflater inflater = getMenuInflater(); + public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { inflater.inflate(R.menu.console, menu); - return super.onCreateOptionsMenu(menu); + super.onCreateOptionsMenu(menu, inflater); } @Override @@ -155,10 +152,10 @@ public boolean onOptionsItemSelected(MenuItem item) { return true; case android.R.id.copy: if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.HONEYCOMB) { - android.text.ClipboardManager clipboard = (android.text.ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE); + android.text.ClipboardManager clipboard = (android.text.ClipboardManager) getActivity().getSystemService(Context.CLIPBOARD_SERVICE); clipboard.setText(mOutput.getText().toString()); } else { - android.content.ClipboardManager clipboard = (android.content.ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE); + android.content.ClipboardManager clipboard = (android.content.ClipboardManager) getActivity().getSystemService(Context.CLIPBOARD_SERVICE); android.content.ClipData clip = android.content.ClipData.newPlainText("Copied Text", mOutput.getText().toString()); clipboard.setPrimaryClip(clip); } diff --git a/cSploit/src/main/java/org/csploit/android/gui/MsfPreferences.java b/cSploit/src/main/java/org/csploit/android/gui/MsfPreferences.java index a7698c25f0..4b2c85614f 100644 --- a/cSploit/src/main/java/org/csploit/android/gui/MsfPreferences.java +++ b/cSploit/src/main/java/org/csploit/android/gui/MsfPreferences.java @@ -1,13 +1,13 @@ package org.csploit.android.gui; import android.os.Bundle; -import android.preference.CheckBoxPreference; -import android.preference.EditTextPreference; -import android.preference.ListPreference; -import android.preference.Preference; -import android.preference.PreferenceActivity; -import android.preference.PreferenceCategory; -import android.preference.PreferenceScreen; +import android.support.v7.preference.CheckBoxPreference; +import android.support.v7.preference.EditTextPreference; +import android.support.v7.preference.ListPreference; +import android.support.v7.preference.Preference; +import android.support.v7.preference.PreferenceCategory; +import android.support.v7.preference.PreferenceFragmentCompat; +import android.support.v7.preference.PreferenceScreen; import android.text.InputType; import android.util.Patterns; import android.widget.Toast; @@ -26,7 +26,7 @@ * activity fo setting exploit options. */ -public class MsfPreferences extends PreferenceActivity { +public class MsfPreferences extends PreferenceFragmentCompat { private Collection