activity劫持反劫持(1)
1、Activity調度機制
android為了提高使用者的使用者體驗,對於不同的應用程式之間的切換,基本上是無縫。他們切換的只是一個activity,讓切換的到前台顯示,另一個應用則被覆蓋到後台,不可見。Activity 的概念相當於一個與使用者互動的介面。而Activity的調度是交由Android系統中的AmS管理的。AmS即 ActivityManagerServiceActivity管理服務),各個應用想啟動或停止一個進程,都是先報告給AmS。 當AmS收到要啟動 或停止Activity的訊息時,它先更新內部記錄,再通知相應的進程運行或停止指定的Activity。當新的Activity啟動,前一個 Activity就會停止,這些Activity都保留在系統中的一個Activity曆史棧中。每有一個Activity啟動,它就壓入曆史棧頂,並在 手機上顯示。當使用者按下back鍵時,頂部Activity彈出,恢複前一個Activity,棧頂指向當前的Activity。
2、Android設計上的缺陷——Activity劫持
如果在啟動一個Activity時,給它加入一個標誌位FLAG_ACTIVITY_NEW_TASK,就能使它置於棧頂並立馬呈現給使用者。
但是這樣的設計卻有一個缺陷。如果這個Activity是用於盜號的偽裝Activity呢?
在 Android系統當中,程式可以枚舉當前啟動並執行進程而不需要聲明其他許可權,這樣子我們就可以寫一個程式,啟動一個背景服務,這個服務不斷地掃描當前運 行的進程,當發現目標進程啟動時,就啟動一個偽裝的Activity。如果這個Activity是登入介面,那麼就可以從中擷取使用者的帳號密碼。
一個運行在背景服務可以做到如下兩點:1,決定哪一個activity運行在前台 2,運行自己app的activity到前台。
這樣,惡意的開發人員就可以對應程式進行攻擊了,對於有登陸介面的應用程式,他們可以偽造一個一模一樣的介面,普通使用者根本無法識別是真的還是假。使用者輸入使用者名稱和密碼之後,惡意程式就可以悄無聲息的把使用者資訊上傳到伺服器了。這樣是非常危險的。
實現原理:如 果我們註冊一個receiver,響應android.intent.action.BOOT_COMPLETED,使得開啟啟動一個service;這 個service,會啟動一個計時器,不停枚舉當前進程中是否有預設的進程啟動,如果發現有預設進程,則使用 FLAG_ACTIVITY_NEW_TASK啟動自己的釣魚介面,截獲正常應用的登入憑證。
3、樣本
下面是範例程式碼。
- [html] view plaincopy
-
- <?xml version="1.0" encoding="utf-8"?>
-
- <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-
- package="com.sinaapp.msdxblog.android.activityhijacking"
-
- android:versionCode="1"
-
- android:versionName="1.0" >
-
-
-
- <uses-sdk android:minSdkVersion="4" />
-
-
-
- <uses-permission android:name="android.permission.INTERNET" />
-
- <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
-
-
-
- <application
-
- android:name=".HijackingApplication"
-
- android:icon="@drawable/icon"
-
- android:label="@string/app_name" >
-
- <activity
-
- android:name=".activity.HijackingActivity"
-
- android:theme="@style/transparent"
-
- 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=".activity.sadstories.JokeActivity" />
-
- <activity android:name=".activity.sadstories.QQStoryActivity" />
-
- <activity android:name=".activity.sadstories.AlipayStoryActivity" />
-
-
-
- <receiver
-
- android:name=".receiver.HijackingReceiver"
-
- android:enabled="true"
-
- android:exported="true" >
-
- <intent-filter>
-
- <action android:name="android.intent.action.BOOT_COMPLETED" />
-
- </intent-filter>
-
- </receiver>
-
-
-
- <service android:name=".service.HijackingService" >
-
- </service>
-
- </application>
-
-
-
- </manifest>
在 以上的代碼中,聲明了一個服務service,用於枚舉當前啟動並執行進程。其中如果不想開機啟動的話,甚至可以把以上receiver部分的代碼,及聲明開 機啟動的許可權的這一行代碼 <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />去掉,僅僅需要訪問網路的許可權向外發送擷取到的帳號密碼),單從AndroidManifest檔案是看不出任何異常的。