123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645 |
- package de.tudarmstadt.informatik.hostage;
- import java.util.ArrayList;
- import java.util.HashMap;
- import java.util.LinkedList;
- import java.util.List;
- import org.apache.http.HttpEntity;
- import org.apache.http.HttpResponse;
- import org.apache.http.client.HttpClient;
- import org.apache.http.client.methods.HttpGet;
- import org.apache.http.impl.client.DefaultHttpClient;
- import org.apache.http.util.EntityUtils;
- import org.json.JSONObject;
- import android.app.NotificationManager;
- import android.app.PendingIntent;
- import android.app.Service;
- import android.content.BroadcastReceiver;
- import android.content.Context;
- import android.content.Intent;
- import android.content.IntentFilter;
- import android.content.SharedPreferences;
- import android.content.SharedPreferences.Editor;
- import android.net.ConnectivityManager;
- import android.net.DhcpInfo;
- import android.net.NetworkInfo;
- import android.net.Uri;
- import android.net.wifi.WifiInfo;
- import android.net.wifi.WifiManager;
- import android.os.AsyncTask;
- import android.os.Binder;
- import android.os.IBinder;
- import android.preference.PreferenceManager;
- import android.support.v4.app.NotificationCompat;
- import android.support.v4.app.TaskStackBuilder;
- import android.support.v4.content.LocalBroadcastManager;
- import android.util.Log;
- import android.widget.Toast;
- import de.tudarmstadt.informatik.hostage.commons.HelperUtils;
- import de.tudarmstadt.informatik.hostage.location.MyLocationManager;
- import de.tudarmstadt.informatik.hostage.persistence.HostageDBOpenHelper;
- import de.tudarmstadt.informatik.hostage.protocol.Protocol;
- import de.tudarmstadt.informatik.hostage.ui.activity.MainActivity;
- import static de.tudarmstadt.informatik.hostage.commons.HelperUtils.*;
- /**
- * Background service running as long as at least one protocol is active.
- * Service controls start and stop of protocol listener. Notifies GUI about
- * events happening in the background. Creates Notifications to inform the user
- * what it happening.
- *
- * @author Mihai Plasoianu
- * @author Lars Pandikow
- * @author Wulf Pfeiffer
- */
- public class Hostage extends Service {
- private HashMap<String, Boolean> mProtocolActiveAttacks;
- public class LocalBinder extends Binder {
- public Hostage getService() {
- return Hostage.this;
- }
- }
- /**
- * Task to find out the external IP.
- *
- */
- private class SetExternalIPTask extends AsyncTask<String, Void, String> {
- @Override
- protected String doInBackground(String... url) {
- String ipAddress = null;
- try {
- HttpClient httpclient = new DefaultHttpClient();
- HttpGet httpget = new HttpGet(url[0]);
- HttpResponse response;
- response = httpclient.execute(httpget);
- HttpEntity entity = response.getEntity();
- entity.getContentLength();
- String str = EntityUtils.toString(entity);
- JSONObject json_data = new JSONObject(str);
- ipAddress = json_data.getString("ip");
- } catch (Exception e) {
- e.printStackTrace();
- }
- return ipAddress;
- }
- @Override
- protected void onPostExecute(String result) {
- connectionInfoEditor.putString(getString(R.string.connection_info_external_ip), result);
- connectionInfoEditor.commit();
- notifyUI(this.getClass().getName(), new String[] { getString(R.string.broadcast_connectivity) });
- }
- }
- private static Context context;
- /**
- * Returns the application context.
- *
- * @return context.
- */
- public static Context getContext() {
- return Hostage.context;
- }
- private LinkedList<Protocol> implementedProtocols;
- private ArrayList<Listener> listeners = new ArrayList<Listener>();
- private NotificationCompat.Builder builder;
- private SharedPreferences connectionInfo;
- private Editor connectionInfoEditor;
- private final IBinder mBinder = new LocalBinder();
- /**
- * Receiver for connectivity change broadcast.
- *
- * @see MainActivity#BROADCAST
- */
- private BroadcastReceiver netReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- String bssid_old = connectionInfo.getString(getString(R.string.connection_info_bssid), "");
- String bssid_new = getBSSID(context);
- if (bssid_new == null || !bssid_new.equals(bssid_old)) {
- deleteConnectionData();
- updateConnectionInfo();
- getLocationData();
- notifyUI(this.getClass().getName(), new String[] { getString(R.string.broadcast_connectivity) });
- }
- }
- };
- public List<Listener> getListeners() {
- return listeners;
- }
- /**
- * Determines the number of active connections for a protocol running on its
- * default port.
- *
- * @param protocolName
- * The protocol name
- * @return Number of active connections
- */
- public int getNumberOfActiveConnections(String protocolName) {
- int port = getDefaultPort(protocolName);
- return getNumberOfActiveConnections(protocolName, port);
- }
- /**
- * Determines the number of active connections for a protocol running on the
- * given port.
- *
- * @param protocolName
- * The protocol name
- * @param port
- * Specific port
- * @return Number of active connections
- */
- public int getNumberOfActiveConnections(String protocolName, int port) {
- for (Listener listener : listeners) {
- if (listener.getProtocolName().equals(protocolName) && listener.getPort() == port) {
- return listener.getHandlerCount();
- }
- }
- return 0;
- }
- /**
- * Determines if there any listener is currently running.
- *
- * @return True if there is a running listener, else false.
- */
- public boolean hasRunningListeners() {
- for (Listener listener : listeners) {
- if (listener.isRunning())
- return true;
- }
- return false;
- }
- /**
- * Determines if a protocol with the given name is running on its default
- * port.
- *
- * @param protocolName
- * The protocol name
- * @return True if protocol is running, else false.
- */
- public boolean isRunning(String protocolName) {
- int port = getDefaultPort(protocolName);
- return isRunning(protocolName, port);
- }
- public boolean isRunningAnyPort(String protocolName){
- for(Listener listener: listeners){
- if(listener.getProtocolName().equals(protocolName)){
- if(listener.isRunning()) return true;
- }
- }
- return false;
- }
- /**
- * Determines if a protocol with the given name is running on the given
- * port.
- *
- * @param protocolName
- * The protocol name
- * @param port
- * Specific port
- * @return True if protocol is running, else false.
- */
- public boolean isRunning(String protocolName, int port) {
- for (Listener listener : listeners) {
- if (listener.getProtocolName().equals(protocolName) && listener.getPort() == port) {
- return listener.isRunning();
- }
- }
- return false;
- }
- /**
- * Notifies the GUI about a event.
- *
- * @param sender
- * Source where the event took place.
- * @param key
- * Detailed information about the event.
- */
- public void notifyUI(String sender, String[] values) {
- createNotification();
- // Send Notification
- if (sender.equals(Handler.class.getName()) && values[0].equals(getString(R.string.broadcast_started))) {
- this.mProtocolActiveAttacks.put(values[1], true);
- attackNotification();
- }
- // Inform UI of Preference Change
- Intent intent = new Intent(getString(R.string.broadcast));
- intent.putExtra("SENDER", sender);
- intent.putExtra("VALUES", values);
- Log.i("Sender", sender);
- LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
- }
- @Override
- public IBinder onBind(Intent intent) {
- return mBinder;
- }
- @Override
- public void onCreate() {
- super.onCreate();
- Hostage.context = getApplicationContext();
- implementedProtocols = getImplementedProtocols();
- connectionInfo = getSharedPreferences(getString(R.string.connection_info), Context.MODE_PRIVATE);
- connectionInfoEditor = connectionInfo.edit();
-
- mProtocolActiveAttacks = new HashMap<String, Boolean>();
- createNotification();
- registerNetReceiver();
- updateConnectionInfo();
- getLocationData();
- }
- @Override
- public void onDestroy() {
- cancelNotification();
- unregisterNetReceiver();
- super.onDestroy();
- }
- @Override
- public int onStartCommand(Intent intent, int flags, int startId) {
- // We want this service to continue running until it is explicitly
- // stopped, so return sticky.
- return START_STICKY;
- }
- /**
- * Starts the listener for the specified protocol. Creates a new
- * HoneyService if no matching HoneyListener is found.
- *
- * @param protocolName
- * Name of the protocol that should be started.
- */
- public boolean startListener(String protocolName) {
- return startListener(protocolName, getDefaultPort(protocolName));
- }
- /**
- * Starts the listener for the specified protocol and port. Creates a new
- * HoneyService if no matching HoneyListener is found.
- *
- * @param protocolName
- * Name of the protocol that should be started.
- * @param port
- * The port number in which the listener should run.
- */
- public boolean startListener(String protocolName, int port) {
- for (Listener listener : listeners) {
- if (listener.getProtocolName().equals(protocolName) && listener.getPort() == port) {
- if (!listener.isRunning()) {
- if (listener.start()) {
- // Toast.makeText(getApplicationContext(), protocolName
- // + " SERVICE STARTED!", Toast.LENGTH_SHORT).show();
- return true;
- }
- Toast.makeText(getApplicationContext(), protocolName + " SERVICE COULD NOT BE STARTED!", Toast.LENGTH_SHORT).show();
- return false;
- }
- }
- }
- Listener listener = createListener(protocolName, port);
- if (listener != null) {
- if (listener.start()) {
- // Toast.makeText(getApplicationContext(), protocolName +
- // " SERVICE STARTED!", Toast.LENGTH_SHORT).show();
- return true;
- }
- }
- Toast.makeText(getApplicationContext(), protocolName + " SERVICE COULD NOT BE STARTED!", Toast.LENGTH_SHORT).show();
- return false;
- }
- /**
- * Starts all listeners which are not already running.
- */
- public void startListeners() {
- for (Listener listener : listeners) {
- if (!listener.isRunning()) {
- listener.start();
- }
- }
- // Toast.makeText(getApplicationContext(), "SERVICES STARTED!",
- // Toast.LENGTH_SHORT).show();
- }
- /**
- * Stops the listener for the specified protocol.
- *
- * @param protocolName
- * Name of the protocol that should be stopped.
- */
- public void stopListener(String protocolName) {
- stopListener(protocolName, getDefaultPort(protocolName));
- }
- /**
- * Stops the listener for the specified protocol.
- *
- * @param protocolName
- * Name of the protocol that should be stopped.
- * @param port
- * The port number in which the listener is running.
- */
- public void stopListener(String protocolName, int port) {
- for (Listener listener : listeners) {
- if (listener.getProtocolName().equals(protocolName) && listener.getPort() == port) {
- if (listener.isRunning()) {
- listener.stop();
- mProtocolActiveAttacks.remove(protocolName);
- }
- }
- }
- // Toast.makeText(getApplicationContext(), protocolName +
- // " SERVICE STOPPED!", Toast.LENGTH_SHORT).show();
- }
-
- public void stopListenerAllPorts(String protocolName){
- for(Listener listener: listeners){
- if(listener.getProtocolName().equals(protocolName)){
- if(listener.isRunning()){
- listener.stop();
- mProtocolActiveAttacks.remove(protocolName);
- }
- }
- }
- }
- /**
- * Stops all running listeners.
- */
- public void stopListeners() {
- for (Listener listener : listeners) {
- if (listener.isRunning()) {
- listener.stop();
- mProtocolActiveAttacks.remove(listener.getProtocolName());
- }
- }
- // Toast.makeText(getApplicationContext(), "SERVICES STOPPED!",
- // Toast.LENGTH_SHORT).show();
- }
- /**
- * Updates the notification when a attack is registered.
- */
- private void attackNotification() {
- SharedPreferences defaultPref = PreferenceManager.getDefaultSharedPreferences(this);
- String strRingtonePreference = defaultPref.getString("pref_notification_sound", "content://settings/system/notification_sound");
- builder = new NotificationCompat.Builder(this).setContentTitle(getString(R.string.app_name)).setTicker("Honeypot under attack!")
- .setContentText("Honeypot under attack!").setSmallIcon(R.drawable.ic_service_red).setAutoCancel(true).setWhen(System.currentTimeMillis())
- .setSound(Uri.parse(strRingtonePreference));
- Intent launchIntent = new Intent(getApplicationContext(), MainActivity.class);
- TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
- stackBuilder.addParentStack(MainActivity.class);
- Intent intent = MainActivity.getInstance().getIntent();
- intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
- intent.setAction("SHOW_HOME");
- stackBuilder.addNextIntent(intent);
- PendingIntent resultPendingIntent = PendingIntent.getActivity(MainActivity.context, 0, intent, 0);
- builder.setContentIntent(resultPendingIntent);
- if (defaultPref.getBoolean("pref_vibration", false)) {
- builder.setVibrate(new long[] { 100, 200, 100, 200 });
- }
- NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
- mNotificationManager.notify(1, builder.build());
- }
- /**
- * Cancels the Notification
- */
- private void cancelNotification() {
- NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
- mNotificationManager.cancel(1);
- }
- /**
- * Creates a HoneyListener for a given protocol on a specific port. After
- * creation the HoneyListener is not started. Checks if the protocol is
- * implemented first.
- *
- * @param protocolName
- * Name of the protocol
- * @param port
- * Port on which to start the HoneyListener
- * @return Returns the created HoneyListener, if creation failed returns
- * null.
- */
- private Listener createListener(String protocolName, int port) {
- for (Protocol protocol : implementedProtocols) {
- if (protocolName.equals(protocol.toString())) {
- Listener listener = new Listener(this, protocol, port);
- listeners.add(listener);
- return listener;
- }
- }
- return null;
- }
- /**
- * Creates a Notification in the notification bar.
- */
- private void createNotification() {
- HostageDBOpenHelper dbh = new HostageDBOpenHelper(this);
- boolean activeHandlers = false;
- boolean bssidSeen = false;
- boolean listening = false;
- for (Listener listener : listeners) {
- if (listener.isRunning())
- listening = true;
- if (listener.getHandlerCount() > 0) {
- activeHandlers = true;
- }
- if (dbh.bssidSeen(listener.getProtocolName(), getBSSID(getApplicationContext()))) {
- bssidSeen = true;
- }
- }
- builder = new NotificationCompat.Builder(this).setContentTitle(getString(R.string.app_name)).setWhen(System.currentTimeMillis());
- if (!listening) {
- builder.setSmallIcon(R.drawable.ic_launcher);
- builder.setContentText("HosTaGe is not active.");
- } else if (activeHandlers) {
- builder.setSmallIcon(R.drawable.ic_service_red);
- builder.setContentText("Network is infected!");
- } else if (bssidSeen) {
- builder.setSmallIcon(R.drawable.ic_service_yellow);
- builder.setContentText("Network has been infected in previous session!");
- } else {
- builder.setSmallIcon(R.drawable.ic_service_green);
- builder.setContentText("Everything looks fine!");
- }
- Intent launchIntent = new Intent(getApplicationContext(), MainActivity.class);
- TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
- stackBuilder.addParentStack(MainActivity.class);
- Intent intent = MainActivity.getInstance().getIntent();
- intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
- intent.setAction("SHOW_HOME");
- stackBuilder.addNextIntent(intent);
- PendingIntent resultPendingIntent = PendingIntent.getActivity(MainActivity.context, 0, intent, 0); //stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
- builder.setContentIntent(resultPendingIntent);
- builder.setOngoing(true);
- NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
- mNotificationManager.notify(1, builder.build());
- }
- /**
- * Deletes all session related data.
- */
- private void deleteConnectionData() {
- connectionInfoEditor.clear();
- connectionInfoEditor.commit();
- }
- /**
- * Returns the default port number, if the protocol is implemented.
- *
- * @param protocolName
- * The name of the protocol
- * @return Returns the default port number, if the protocol is implemented.
- * Else returns -1.
- */
- private int getDefaultPort(String protocolName) {
- for (Protocol protocol : implementedProtocols) {
- if (protocolName.equals(protocol.toString())) {
- return protocol.getPort();
- }
- }
- return -1;
- };
- /**
- * Returns an LinkedList<String> with the names of all implemented
- * protocols.
- *
- * @return ArrayList of
- * {@link de.tudarmstadt.informatik.hostage.protocol.Protocol
- * Protocol}
- */
- private LinkedList<Protocol> getImplementedProtocols() {
- String[] protocols = getResources().getStringArray(R.array.protocols);
- String packageName = Protocol.class.getPackage().getName();
- LinkedList<Protocol> implementedProtocols = new LinkedList<Protocol>();
- for (String protocol : protocols) {
- try {
- implementedProtocols.add((Protocol) Class.forName(String.format("%s.%s", packageName, protocol)).newInstance());
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- return implementedProtocols;
- }
- /**
- * Starts an Instance of MyLocationManager to set the location within this
- * class.
- */
- private void getLocationData() {
- MyLocationManager locationManager = new MyLocationManager(this);
- locationManager.getUpdates(60 * 1000, 3);
- };
- // Notifications
- /**
- * Register broadcast receiver for connectivity changes
- */
- private void registerNetReceiver() {
- // register BroadcastReceiver on network state changes
- IntentFilter intent = new IntentFilter();
- intent.addAction(ConnectivityManager.CONNECTIVITY_ACTION); // "android.net.conn.CONNECTIVITY_CHANGE"
- registerReceiver(netReceiver, intent);
- }
- /**
- * Unregister broadcast receiver for connectivity changes
- */
- private void unregisterNetReceiver() {
- unregisterReceiver(netReceiver);
- }
-
- public boolean hasProtocolActiveAttacks(String protocol){
- if(!mProtocolActiveAttacks.containsKey(protocol)) return false;
- return mProtocolActiveAttacks.get(protocol);
- }
- public boolean hasActiveAttacks(){
- for(boolean b: mProtocolActiveAttacks.values()){
- if(b) return true;
- }
- return false;
- }
- /**
- * Updates the connection info and saves them in the the SharedPreferences
- * for session data.
- *
- * @param context
- * Needs a context to get system resources.
- * @see MainActivity#CONNECTION_INFO
- */
- private void updateConnectionInfo() {
- ConnectivityManager connManager = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
- NetworkInfo networkInfo = connManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
- if (networkInfo == null || !networkInfo.isConnected()) {
- return; // no connection
- }
- final WifiManager wifiManager = (WifiManager)context.getSystemService(Context.WIFI_SERVICE);
- final WifiInfo connectionInfo = wifiManager.getConnectionInfo();
- if (connectionInfo == null) {
- return; // no wifi connection
- }
- final DhcpInfo dhcpInfo = wifiManager.getDhcpInfo();
- if (dhcpInfo == null) {
- return;
- }
- String ssid = connectionInfo.getSSID();
- if (ssid.startsWith("\"") && ssid.endsWith("\"")) { // trim those quotes
- ssid = ssid.substring(1, ssid.length() - 1);
- }
- SharedPreferences pref = context.getSharedPreferences(getString(R.string.connection_info), Context.MODE_PRIVATE);
- Editor editor = pref.edit();
- editor.putString(getString(R.string.connection_info_ssid), ssid);
- editor.putString(getString(R.string.connection_info_bssid), connectionInfo.getBSSID());
- editor.putInt(getString(R.string.connection_info_internal_ip), dhcpInfo.ipAddress);
- editor.putInt(getString(R.string.connection_info_subnet_mask), dhcpInfo.netmask);
- editor.commit();
- SetExternalIPTask async = new SetExternalIPTask();
- async.execute(new String[] { "http://ip2country.sourceforge.net/ip2c.php?format=JSON" });
- this.mProtocolActiveAttacks.clear();
- }
- }
|