app安全:如何應對介面劫持、介面劫持如何檢測

seven123發表於2020-12-01

寫這篇文章是因為,公司的專案對安全性要求較高一些,所以每年都會不定時把app提交到三方檢測機構進行安全檢測,其中有一項就是介面劫持風險,那麼接下來,就一步步教大家怎麼解決這個問題。

介面劫持的原理

android系統中,程式可以列舉當前執行的程式而不需要宣告任何許可權,如果攻擊者註冊一個receiver,響應android.intent.action.BOOT_COMPLETED,使得開啟啟動一個service;在這個service中啟動一個計時器,不停列舉當前程式中是否有預設的程式啟動,如果發現有預設程式,則使用FLAG_ACTIVITY_NEW_TASK啟動自己的釣魚介面,而正常應用的介面則隱藏在釣魚介面的後面。

IIS7網站監控可以及時防控網站風險,快速準確監控網站是否遭到各種劫持攻擊,網站在全國是否能正常開啟(檢視域名是否被牆),精準的DNS汙染檢測,具備網站開啟速度檢測功能,第一時間知道網站是否被黑、被入侵、被改標題、被掛黑鏈。精益求精的產品,缺陷為零資料提供!
它可以做到以下功能:1、檢測網站是否被黑2、檢測網站是否被劫持3、檢測域名是否被牆4、檢測DNS是否被汙染5、網站真實的完全開啟時間(獨家)6、擁有獨立監控後臺,24小時定時監控域名官方地址:官方圖:

 

 

解決辦法

這是系統漏洞,在應用程式中很難去防止這種介面支援。但應用程式自身可以增加一些防範實施。
防範實施:
1. 開啟守護程式,當發現應用程式不在棧頂時,在螢幕最上層建立一個懸浮小視窗(提示資訊與客戶確定),以提醒使用者。
2. 使用搶佔式,即與劫持程式搶佔棧頂。
3. 在應用切到後臺時,在通知欄彈出通知提示。

以上三種防範措施都是可取的,但是其中第二種,搶佔式的搶佔棧頂這種做法,頻繁出現的話,使用者會非常反感,於是,我們最終的方案是結合第一種和第三種方法來處理:app被切到後臺後Toast彈框並在通知欄顯示一條通知。(提醒使用者,app被切到後臺執行)

具體實施

1. 在Activity的各生命週期中啟動或者停止服務(在onResume中開啟service,在onStart和onDestory中關閉service)

示例:

 

 

@Override

protected void onPause() {

 

    Intent intent = new Intent();

    intent.putExtra("pageName", this.getComponentName()

            .getPackageName());

    intent.putExtra("className", this.getComponentName().getClassName());

    intent.setClass(this, AppStatusService.class);

    startService(intent);

}

 

public void onResume() {

 

    Intent intent = new Intent();

    intent.putExtra("pageName", this.getComponentName().getPackageName());

    intent.putExtra("className", this.getComponentName().getClassName());

    intent.setClass(this, AppStatusService.class);

    stopService(intent);

}

 

@Override

public void onDestroy() {

    Intent intent = new Intent();

    intent.setClass(this, AppStatusService.class);

    stopService(intent);

}

·  1

·  2

·  3

·  4

·  5

·  6

·  7

·  8

·  9

·  10

·  11

·  12

·  13

·  14

·  15

·  16

·  17

·  18

·  19

·  20

·  21

·  22

·  23

·  24

·  25

·  26

·  27

·  28

·  29

2. 編寫具體的Service邏輯

/**

 * 應用是否在前臺執行

 *

 * @return true:在前臺執行;false:已經被切到後臺了

 */

private boolean isAppOnForeground() {

    List<RunningAppProcessInfo> appProcesses = activityManager.getRunningAppProcesses();

    if (appProcesses != null) {

        for (RunningAppProcessInfo appProcess : appProcesses) {

            if (appProcess.importance == RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {

                if (appProcess.processName.equals(packageName)) {

                    return true;

                }

            }

        }

    }

    return false;

}

/**

 * 定義一個timerTask來發通知和彈出Toast

 */

TimerTask timerTask = new TimerTask() {

 

    @Override

    public void run() {

        if (!isAppOnForeground()) {

 

            isAppBackground = true;

            //發通知

            showNotification();

            //彈出Toast提示

            MainActivity.mCurrentActivity.runOnUiThread(new Runnable() {

                @Override

                public void run() {

                    Toast.makeText(getApplicationContext(),

                            getApplicationContext().getString(R.string.pervent_hijack_mes), Toast.LENGTH_SHORT)

                            .show();

                }

            });

            mTimer.cancel();

        }

    }

};

/**

 * 彈出通知提示

 */

private void showNotification() {

    NotificationManager notificationManager = (NotificationManager) getSystemService(

            android.content.Context.NOTIFICATION_SERVICE);

    Notification notification = new Notification(R.drawable.icon, "xx銀行", System.currentTimeMillis());

    notification.defaults |= Notification.DEFAULT_VIBRATE;// 設定震動

    notification.defaults |= Notification.DEFAULT_LIGHTS;// 設定LED燈提醒

    notification.flags |= Notification.FLAG_NO_CLEAR;// 通知不可被狀態列的清除按鈕清除掉

    notification.flags |= Notification.FLAG_ONGOING_EVENT;// 通知放置在 正在執行

 

    Intent intent = new Intent();

    intent.setAction(Intent.ACTION_MAIN);

    intent.putExtra("notification", "notification");

    intent.setClassName(packageName, className);

 

    // 修改vivo手機點選通知欄不返回

    intent.addCategory(Intent.CATEGORY_LAUNCHER);

 

    // 增加Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED用於正常的從後臺再次返回到原來退出時的頁面中

    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);

    PendingIntent pendingInt = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);

 

    String temp = "";

    notification.setLatestEventInfo(this, "xx手機銀行", "手機銀行已經被切到後臺執行" + temp, pendingInt);

    // 設定服務的級別,使其不容易被kill掉,解決後臺返回前臺黑屏的問題

    startForeground(1, notification);

}

·  1

·  2

·  3

·  4

·  5

·  6

·  7

·  8

·  9

·  10

·  11

·  12

·  13

·  14

·  15

·  16

·  17

·  18

·  19

·  20

·  21

·  22

·  23

·  24

·  25

·  26

·  27

·  28

·  29

·  30

·  31

·  32

·  33

·  34

·  35

·  36

·  37

·  38

·  39

·  40

·  41

·  42

·  43

·  44

·  45

·  46

·  47

·  48

·  49

·  50

·  51

·  52

·  53

·  54

·  55

·  56

·  57

·  58

·  59

·  60

·  61

·  62

·  63

·  64

·  65

·  66

·  67

·  68

·  69

·  70

·  71

·  72

3. 在onStart中執行timer

        @Override

public void onStart(Intent intent, int startId) {

    try {

        Bundle bundle = null;

        if (intent != null) {

            bundle = intent.getExtras();

        }

        if (bundle != null) {

            className = bundle.getString("className");

        }

        // 透過計時器延遲執行

        mTimer.schedule(timerTask, 50, 50);

 

    } catch (Exception e) {

        e.printStackTrace();

    }

}

·  1

·  2

·  3

·  4

·  5

·  6

·  7

·  8

·  9

·  10

·  11

·  12

·  13

·  14

·  15

·  16

·  17

具體效果如圖:

  app安全:如何應對介面劫持、介面劫持如何檢測

補充內容

根據importance的不同來判斷前臺或後臺
RunningAppProcessInfo 裡面的常量IMOPORTANCE就是上面所說的前臺後臺,其實IMOPORTANCE是表示這個app程式的重要性,因為系統回收時候,會根據IMOPORTANCE來回收程式的。具體可以去看文件。
public static final int IMPORTANCE_BACKGROUND = 400//後臺
public static final int IMPORTANCE_EMPTY = 500//空程式
public static final int IMPORTANCE_FOREGROUND =100//在螢幕最前端、可獲取到焦點 可理解為Activity生命週期的OnResume();
public static final int IMPORTANCE_SERVICE = 300//在服務中
public static final int IMPORTANCE_VISIBLE = 200//在螢幕前端、獲取不到焦點可理解為Activity生命週期的OnStart();

 


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69989270/viewspace-2738638/,如需轉載,請註明出處,否則將追究法律責任。

相關文章