当前位置:网站首页>测试apk-异常管控WiFi Scan攻击者开发

测试apk-异常管控WiFi Scan攻击者开发

2022-06-22 01:12:00 法迪

1. 目的

基于《软件绿色联盟应用体验标准》中 WiFi scan 资源的定义,对 WiFi scan 后台持续扫描的测试apk。旨在触发手机中异常功耗管控机制。
wifi扫描异常

没有弹出消息通知,但是确实已经后台WiFi扫描很久。具体日志关键字为:APwActAnalysis: wifi scan app:xxx duration:xxx

2022-06-20 14:12:14.079 2456-3458/? I/APwMonitor: run monitor start. init: false screen off: false
2022-06-20 14:12:14.085 2456-3458/? I/APwMonitor: screen on skip visible app : com.huawei.android.launcher
2022-06-20 14:12:14.093 2456-3458/? D/APwActAnalysis: wifi scan app: com.sufadi.blockwifiscan level: 1 duration:69402
2022-06-20 14:12:14.097 2456-3458/? I/APwActAnalysis: can not process location privider app: com.huawei.lbs uid:1000
2022-06-20 14:12:14.117 2456-3458/? D/APwActAnalysis: wifi scan app: com.taobao.taobao level: 0 duration:1424
2022-06-20 14:12:14.142 2456-3458/? D/APwMonitor: run monitor end.

2. 测试步骤

H手机和T手机、其他手机进行安装该apk.
所有手机都需要设置应用为白名单。

2.1 手机白名单设置方法:

手机管家->应用启动设置:允许自启动、允许关联启动、允许后台启动

H手机白名单

2.2 测试环境

手动开启Wifi和GPS

2.3 运行本apk

亮屏后台的使用行为检测

2.4 运行本apk

测试:先把Wifi和GPS开关打开,本次亮屏后台WiFi扫描累积扫描超过3min钟,是否会弹出通知栏

3. apk 源码

本apk作用:后台无限制的WiFi扫描行为

3.1 UI

wifi扫描攻击者

3.2 核心逻辑

3.2.1 MainActivity

运行时权限申请

package com.sufadi.blocaknetlocation

import android.Manifest
import android.content.Intent
import android.content.pm.PackageManager
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.widget.Toast
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat

class MainActivity : AppCompatActivity() {

    companion object {
        val TAG = "blocaknetlocation_MainActivity"
        val REQUES_CODE_OK = 200
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        applyPermission()
    }

    fun applyPermission() {
        if(ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
            || ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED
            || ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_BACKGROUND_LOCATION) != PackageManager.PERMISSION_GRANTED){//未开启定位权限

            Log.d(TAG, "applyPermission")
            ActivityCompat.requestPermissions(this, arrayOf(
                Manifest.permission.ACCESS_FINE_LOCATION,
                Manifest.permission.ACCESS_COARSE_LOCATION), REQUES_CODE_OK)
        } else {
            Log.d(TAG, "startService BlockNetLocationService")
            startService(Intent(this, BlockNetLocationService::class.java))
        }
    }

    override fun onRequestPermissionsResult(
        requestCode: Int,
        permissions: Array<String>,
        grantResults: IntArray) {
        when (requestCode) {
            REQUES_CODE_OK-> if (grantResults.size == 2 &&
                grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                for (grant in grantResults) {
                    Log.d(TAG, "grant: $grant")
                }
                ActivityCompat.requestPermissions(this, arrayOf(
                    Manifest.permission.ACCESS_BACKGROUND_LOCATION), REQUES_CODE_OK)
                /*Toast.makeText([email protected], "未开启定位权限,请手动到设置去开启权限", Toast.LENGTH_LONG).show()
                finish()*/
            } else {
                Log.d(TAG, "startService BlockNetLocationService 1")
                startService(Intent(this, BlockNetLocationService::class.java))
            }
        }

        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
    }
}

3.3.2 权限配置

必须权限如下:

ACCESS_WIFI_STATE(用于扫描结束后读取wifi信息)
CHANGE_WIFI_STATE(用于扫描WiFi列表)
除必须权限外,根据系统版本,还有不同的限制。具体如下

Android 8.0 & 8.1
WifiManager.getScanResults() 方法的调用必须具备以下任一权限:

ACCESS_FINE_LOCATION
ACCESS_COARSE_LOCATION
CHANGE_WIFI_STATE
事实上,从6.0开始,WifiManager.getScanResults() 方法就需要定位权限了。见[硬件标识符访问权]

否则会抛异常SecurityException。

Android 9.0
WifiManager.startScan() 方法的调用必须满足以下所有条件:

拥有 ACCESS_FINE_LOCATION 或 ACCESS_COARSE_LOCATION 权限
拥有 CHANGE_WIFI_STATE 权限
打开定位服务
否则会抛异常SecurityException。

Android Q & later
在9.0版限制的基础上,对定位的要求升级为:必须拥有精确定位权限(ACCESS_FINE_LOCATION)

    <!-- 前台服务属性权限 -->
    <!-- GSP定位授权 -->
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
    <!-- 网络定位权限 -->
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION "/>
    <!-- 始终允许后台使用GPS -->
    <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION"/>

3.3.3 核心逻辑

WiFi扫描的实现步骤
注册系统广播接收器,触发扫描动作【WifiManager.startScan()】
系统扫描结束后会发送广播,等待接收广播
收到广播后,获取扫描结果【WifiManager.getScanResults()】

package com.sufadi.blockwifiscan

import android.annotation.SuppressLint
import android.app.Notification
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.Service
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.net.wifi.WifiManager
import android.os.Handler
import android.os.IBinder
import android.os.Message
import android.util.Log

class BlockWiFiScanService: Service() {

    companion object {
        val TAG = "BlockWiFiScanService"
        val FORGROUND_ID = 0x11
        lateinit var wifiManager: WifiManager
        val MSG_SCAN_WIFI = 888
    }


    override fun onBind(p0: Intent?): IBinder? {
        return null
    }

    override fun onCreate() {
        super.onCreate()
        Log.d(TAG, "onCreate")
        startMyForeground()

        init()
        initReciver()
    }

    override fun onDestroy() {
        super.onDestroy()
        stopForeground(true)
    }


    private fun startMyForeground() {
        Log.d(TAG, "startMyForeground show notification")
        Log.d(TAG, "PhoneDataService startMyForeground sdk :" + android.os.Build.VERSION.SDK_INT)
        val nb = Notification.Builder(this)

        if (android.os.Build.VERSION.SDK_INT >= 26) {
            val CHANNEL_ONE_ID = "channel_id_foreground"
            val CHANNEL_ONE_NAME = "Channel One"
            var notificationChannel: NotificationChannel? = null

            notificationChannel = NotificationChannel(
                CHANNEL_ONE_ID,
                CHANNEL_ONE_NAME, NotificationManager.IMPORTANCE_LOW
            )

            nb.setChannelId(CHANNEL_ONE_ID)

            val manager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
            manager.createNotificationChannel(notificationChannel)
        }

        nb.setSmallIcon(R.mipmap.ic_launcher)
        nb.setContentTitle(getString(R.string.notification_title))
        nb.setContentText(getString(R.string.notification_Content))

        try {
            startForeground(FORGROUND_ID, nb.build())
        } catch (e: Exception) {
            e.printStackTrace()
        }

    }

    private fun initReciver() {
        val intentFilter = IntentFilter()
        intentFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)
        registerReceiver(wifiScanReceiver, intentFilter)
    }

    private fun init() {
        wifiManager = getSystemService(Context.WIFI_SERVICE) as WifiManager
        wifiManager.startScan()
        innerHandle.sendEmptyMessage(MSG_SCAN_WIFI)
        //wifiManager.registerScanResultsCallback(SynchronousExecutor(), mScanResultsCallback)
    }



    fun scanSuccess() {
        val results = wifiManager.scanResults
        Log.d(TAG, "scanSuccess: $results")
    }

    fun scanFailure() {
        val results = wifiManager.scanResults
        Log.d(TAG, "scanFailure: $results")
    }

    val innerHandle: Handler = @SuppressLint("HandlerLeak")
    object : Handler() {
        override fun handleMessage(msg: Message) {
            super.handleMessage(msg)
            when(msg?.what) {
                MSG_SCAN_WIFI -> {
                    val success = wifiManager.startScan()
                    if (!success) {
                        // scan failure handling
                        //scanFailure()
                    }
                    Log.d(TAG, "startWiFiScan isScanAlwaysAvailable:${wifiManager.isScanAlwaysAvailable}")


                    val results = wifiManager.scanResults
                    Log.d(TAG, "scanResults: $results")
                    sendEmptyMessageDelayed(MSG_SCAN_WIFI, 10000)
                }
                else -> {

                }
            }
        }
    }

    val wifiScanReceiver = object : BroadcastReceiver() {

        override fun onReceive(context: Context, intent: Intent) {
            val success = intent.getBooleanExtra(WifiManager.EXTRA_RESULTS_UPDATED, false)
            if (success) {
                scanSuccess()
            } else {
                scanFailure()
            }
        }
    }

}

3.3.4 华为异常检测日志

没有弹出消息通知,但是确实已经后台WiFi扫描很久。具体日志关键字为:APwActAnalysis: wifi scan app:xxx duration:xxx

2022-06-20 14:12:14.079 2456-3458/? I/APwMonitor: run monitor start. init: false screen off: false
2022-06-20 14:12:14.085 2456-3458/? I/APwMonitor: screen on skip visible app : com.huawei.android.launcher
2022-06-20 14:12:14.093 2456-3458/? D/APwActAnalysis: wifi scan app: com.sufadi.blockwifiscan level: 1 duration:69402
2022-06-20 14:12:14.097 2456-3458/? I/APwActAnalysis: can not process location privider app: com.huawei.lbs uid:1000
2022-06-20 14:12:14.117 2456-3458/? D/APwActAnalysis: wifi scan app: com.taobao.taobao level: 0 duration:1424
2022-06-20 14:12:14.142 2456-3458/? D/APwMonitor: run monitor end.
原网站

版权声明
本文为[法迪]所创,转载请带上原文链接,感谢
https://blog.csdn.net/su749520/article/details/125372405