org.csploit.android.plugins.PortScanner.java Source code

Java tutorial

Introduction

Here is the source code for org.csploit.android.plugins.PortScanner.java

Source

/*
 * This file is part of the dSploit.
 *
 * Copyleft of Simone Margaritelli aka evilsocket <evilsocket@gmail.com>
 *
 * dSploit is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * dSploit is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with dSploit.  If not, see <http://www.gnu.org/licenses/>.
 */
package org.csploit.android.plugins;

import android.content.ActivityNotFoundException;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.v4.content.ContextCompat;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

import org.csploit.android.R;
import org.csploit.android.core.ChildManager;
import org.csploit.android.core.Logger;
import org.csploit.android.core.Plugin;
import org.csploit.android.core.System;
import org.csploit.android.gui.dialogs.ConfirmDialog;
import org.csploit.android.gui.dialogs.ConfirmDialog.ConfirmDialogListener;
import org.csploit.android.gui.dialogs.ErrorDialog;
import org.csploit.android.gui.dialogs.InputDialog;
import org.csploit.android.gui.dialogs.InputDialog.InputDialogListener;
import org.csploit.android.net.Network;
import org.csploit.android.net.Target;
import org.csploit.android.net.Target.Port;
import org.csploit.android.tools.NMap;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

public class PortScanner extends Plugin {
    private TextView mTextDoc = null;
    private EditText mTextParameters = null;
    private FloatingActionButton mScanFloatingActionButton = null;
    private ProgressBar mScanProgress = null;
    private boolean mRunning = false;
    private ArrayList<String> mPortList = new ArrayList<>();
    private ArrayAdapter<String> mListAdapter = null;
    private Receiver mScanReceiver = null;
    private String mCustomPorts = null;
    private Menu mMenu = null;
    private static final String CUSTOM_PARAMETERS = "PortScanner.Prefs.CustomParameters";
    private static final String CUSTOM_PARAMETERS_TEXT = "PortScanner.Prefs.CustomParameters.Text";
    private SharedPreferences mPreferences = null;
    private Map<Integer, String> urlFormats = new HashMap<>();
    private boolean mShowCustomParameters = false;

    public PortScanner() {
        super(R.string.port_scanner, R.string.port_scanner_desc,

                new Target.Type[] { Target.Type.ENDPOINT, Target.Type.REMOTE }, R.layout.plugin_portscanner,
                R.drawable.action_scanner);
        urlFormats.put(80, "http://%s/");
        urlFormats.put(443, "https://%s/");
        urlFormats.put(21, "ftp://%s");
        urlFormats.put(22, "ssh://%s");
        urlFormats.put(23, "telnet://%s/");
        urlFormats.put(0, "telnet://%s:%d/"); ///< default
    }

    /**
     * Sets visible the custom parameters text field, and loads the saved parameters
     */
    private void displayParametersField() {
        mTextDoc.setVisibility(View.VISIBLE);
        mTextParameters.setVisibility(View.VISIBLE);
        mTextParameters.setText(mPreferences.getString(CUSTOM_PARAMETERS_TEXT, ""));

        mShowCustomParameters = true;
        saveCustomParameters();
    }

    /**
     * Hides the custom parameters text field, saving the typed parameters
     */
    private void hideParametersField() {
        mShowCustomParameters = false;
        saveCustomParameters();

        mTextDoc.setVisibility(View.GONE);
        mTextParameters.setVisibility(View.GONE);
    }

    /**
     * Saves customs parameters entered by the user
     */
    private void saveCustomParameters() {
        SharedPreferences.Editor edit = mPreferences.edit();
        edit.putBoolean(CUSTOM_PARAMETERS, mShowCustomParameters);
        edit.putString(CUSTOM_PARAMETERS_TEXT, mTextParameters.getText().toString());
        edit.commit();
    }

    private void setStoppedState() {
        if (mProcess != null) {
            mProcess.kill();
            mProcess = null;
        }
        saveCustomParameters();

        mScanProgress.setVisibility(View.INVISIBLE);
        mRunning = false;
        mScanFloatingActionButton.setImageDrawable(ContextCompat.getDrawable(this, R.drawable.ic_play_arrow_24dp));

        if (mPortList.size() == 0)
            Toast.makeText(this, getString(R.string.no_open_ports), Toast.LENGTH_LONG).show();
    }

    private void setStartedState() {
        createPortList();

        try {
            if (mShowCustomParameters) {
                mProcess = System.getTools().nmap.customScan(System.getCurrentTarget(), mScanReceiver,
                        mTextParameters.getText().toString());
            } else {
                mProcess = System.getTools().nmap.synScan(System.getCurrentTarget(), mScanReceiver, mCustomPorts);
            }

            mRunning = true;
        } catch (ChildManager.ChildNotStartedException e) {
            System.errorLogging(e);
            Toast.makeText(PortScanner.this, getString(R.string.child_not_started) + "\n" + e.getLocalizedMessage(),
                    Toast.LENGTH_LONG).show();
        }
        mScanFloatingActionButton.setImageDrawable(ContextCompat.getDrawable(this, R.drawable.ic_stop_24dp));
    }

    private void createPortList() {
        mPortList.clear();

        for (Port p : System.getCurrentTarget().getOpenPorts()) {
            int pNumber = p.getNumber();
            String resolvedProtocol = System.getProtocolByPort(pNumber);
            String str;

            if (resolvedProtocol != null)
                str = pNumber + " ( " + resolvedProtocol + " )";
            else
                str = p.getProtocol().toString().toLowerCase() + " : " + pNumber;

            if (!mPortList.contains(str))
                mPortList.add(str);
        }

    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        SharedPreferences themePrefs = getSharedPreferences("THEME", 0);
        Boolean isDark = themePrefs.getBoolean("isDark", false);
        if (isDark)
            setTheme(R.style.DarkTheme);
        else
            setTheme(R.style.AppTheme);
        super.onCreate(savedInstanceState);

        mPreferences = System.getSettings();
        mTextDoc = (TextView) findViewById(R.id.scanDoc);
        mTextParameters = (EditText) findViewById(R.id.scanParameters);
        mScanFloatingActionButton = (FloatingActionButton) findViewById(R.id.scanToggleButton);
        mScanProgress = (ProgressBar) findViewById(R.id.scanActivity);

        mShowCustomParameters = mPreferences.getBoolean(CUSTOM_PARAMETERS, false);

        if (mShowCustomParameters)
            displayParametersField();
        else
            hideParametersField();

        mScanFloatingActionButton.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                if (mRunning) {
                    setStoppedState();
                } else {
                    setStartedState();
                }
            }
        });

        ListView mScanList = (ListView) findViewById(R.id.scanListView);

        createPortList();

        final Target target = System.getCurrentTarget();
        final String cmdlineRep = target.getCommandLineRepresentation();

        mScanReceiver = new Receiver(target);

        mListAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, mPortList);
        mScanList.setAdapter(mListAdapter);
        mScanList.setOnItemLongClickListener(new OnItemLongClickListener() {
            @Override
            public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
                int portNumber = target.getOpenPorts().get(position).getNumber();

                if (!urlFormats.containsKey(portNumber)) {
                    portNumber = 0;
                }

                final String url = String.format(urlFormats.get(portNumber), cmdlineRep, portNumber);

                new ConfirmDialog("Open", "Open " + url + " ?", PortScanner.this, new ConfirmDialogListener() {
                    @Override
                    public void onConfirm() {
                        try {
                            Intent browser = new Intent(Intent.ACTION_VIEW, Uri.parse(url));

                            PortScanner.this.startActivity(browser);
                        } catch (ActivityNotFoundException e) {
                            System.errorLogging(e);

                            new ErrorDialog(getString(R.string.error), getString(R.string.no_activities_for_url),
                                    PortScanner.this).show();
                        }

                    }

                    @Override
                    public void onCancel() {
                    }
                }).show();

                return false;
            }
        });
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.port_scanner, menu);
        mMenu = menu;
        mMenu.findItem(R.id.scanner_custom_parameters)
                .setChecked(mPreferences.getBoolean(CUSTOM_PARAMETERS, false));

        return super.onCreateOptionsMenu(menu);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case R.id.scanner_custom_parameters:
            if (item.isChecked())
                hideParametersField();
            else
                displayParametersField();

            item.setChecked(!item.isChecked());
            return true;
        case R.id.select_ports:

            new InputDialog(getString(R.string.select_ports), getString(R.string.enter_ports_list), this,
                    new InputDialogListener() {
                        @Override
                        public void onInputEntered(String input) {
                            input = input.trim();

                            if (!input.isEmpty()) {
                                String[] ports = input.split("[^\\d]+");
                                for (String port : ports) {
                                    try {
                                        if (port.isEmpty())
                                            throw new Exception(getString(R.string.invalid_port_) + port + "'.");

                                        else {
                                            int iport = Integer.parseInt(port);
                                            if (iport <= 0 || iport > 65535)
                                                throw new Exception(getString(R.string.port_must_be_greater));
                                        }
                                    } catch (Exception e) {
                                        new ErrorDialog("Error", e.toString(), PortScanner.this).show();
                                        return;
                                    }
                                }

                                mCustomPorts = "";
                                for (int i = 0, last = ports.length - 1; i < ports.length; i++) {
                                    mCustomPorts += ports[i];
                                    if (i != last)
                                        mCustomPorts += ",";
                                }

                                if (mCustomPorts.isEmpty()) {
                                    mCustomPorts = null;
                                    new ErrorDialog(getString(R.string.error), getString(R.string.invalid_ports),
                                            PortScanner.this).show();
                                }

                                hideParametersField();
                                mMenu.findItem(R.id.scanner_custom_parameters).setChecked(false);

                                Logger.debug("mCustomPorts = " + mCustomPorts);
                            } else
                                new ErrorDialog(getString(R.string.error), getString(R.string.empty_port_list),
                                        PortScanner.this).show();
                        }
                    }).show();

            return true;

        default:
            return super.onOptionsItemSelected(item);
        }
    }

    @Override
    public void onBackPressed() {
        setStoppedState();
        super.onBackPressed();
        overridePendingTransition(R.anim.fadeout, R.anim.fadein);
    }

    private class Receiver extends NMap.SynScanReceiver {

        private final Target target;

        public Receiver(Target target) {
            this.target = target;
        }

        @Override
        public void onStart(String commandLine) {
            super.onStart(commandLine);

            PortScanner.this.runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    mRunning = true;
                    mScanProgress.setVisibility(View.VISIBLE);
                }
            });
        }

        @Override
        public void onEnd(int exitCode) {
            super.onEnd(exitCode);

            PortScanner.this.runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    setStoppedState();
                }
            });
        }

        @Override
        public void onPortFound(final int port, String protocol) {
            String resolvedProtocol = System.getProtocolByPort(port);

            target.addOpenPort(port, Network.Protocol.fromString(protocol));

            final String entry = (resolvedProtocol != null ? port + " ( " + resolvedProtocol + " )"
                    : protocol + " : " + port);

            if (!mPortList.contains(entry)) {
                PortScanner.this.runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        mPortList.add(entry);
                        mListAdapter.notifyDataSetChanged();
                    }
                });
            }
        }
    }
}