Подтвердить что ты не робот

Отключить/проверить местоположение макета (запретить спуфинг gps)

Глядя на поиск лучшего способа предотвратить/обнаружить спуфинг GPS на Android. Любые предложения о том, как это делается, и что можно сделать, чтобы остановить его? Я предполагаю, что пользователь должен включить ложные местоположения, чтобы обмануть GPS, если это будет сделано, тогда они могут обмануть GPS?

Я думаю, мне нужно будет просто определить, включены ли Mock Locations? Любые другие предложения?

4b9b3361

Ответ 1

Я провел некоторое расследование и поделился своими результатами здесь, это может быть полезно для других.

Сначала мы можем проверить, включена ли опция MockSetting.

public static boolean isMockSettingsON(Context context) {
    // returns true if mock location enabled, false if not enabled.
    if (Settings.Secure.getString(context.getContentResolver(),
                                Settings.Secure.ALLOW_MOCK_LOCATION).equals("0"))
        return false;
    else
        return true;
}

Во-вторых, мы можем проверить, есть ли в устройстве другие приложения, которые используют android.permission.ACCESS_MOCK_LOCATION (Приложения для Spoofing)

public static boolean areThereMockPermissionApps(Context context) {
    int count = 0;

    PackageManager pm = context.getPackageManager();
    List<ApplicationInfo> packages =
        pm.getInstalledApplications(PackageManager.GET_META_DATA);

    for (ApplicationInfo applicationInfo : packages) {
        try {
            PackageInfo packageInfo = pm.getPackageInfo(applicationInfo.packageName,
                                                        PackageManager.GET_PERMISSIONS);

            // Get Permissions
            String[] requestedPermissions = packageInfo.requestedPermissions;

            if (requestedPermissions != null) {
                for (int i = 0; i < requestedPermissions.length; i++) {
                    if (requestedPermissions[i]
                        .equals("android.permission.ACCESS_MOCK_LOCATION")
                        && !applicationInfo.packageName.equals(context.getPackageName())) {
                        count++;
                    }
                }
            }
        } catch (NameNotFoundException e) {
            Log.e("Got exception " , e.getMessage());
        }
    }

    if (count > 0)
        return true;
    return false;
}

Если оба метода выше, первый и второй являются истинными, тогда есть хорошие шансы, что местоположение может быть подделанным или поддельным.

Теперь с помощью API-интерфейса Location Manager можно избежать спуфинга.

Мы можем удалить поставщика теста, прежде чем запрашивать обновления местоположения как у поставщиков (сеть и GPS).

LocationManager lm = (LocationManager) getSystemService(LOCATION_SERVICE);

try {
    Log.d(TAG ,"Removing Test providers")
    lm.removeTestProvider(LocationManager.GPS_PROVIDER);
} catch (IllegalArgumentException error) {
    Log.d(TAG,"Got exception in removing test  provider");
}

lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 0, locationListener);

Я видел, что removeTestProvider (~) отлично работает над версией Jelly Bean и далее. Этот API оказался ненадежным до Ice Cream Sandwich.

Ответ 2

Кажется, что единственный способ сделать это - предотвратить спуфинг места, предотвращающий MockLocations. С другой стороны, есть некоторые пользователи, которые используют Bluetooth-устройства GPS для получения лучшего сигнала, они не смогут использовать приложение, поскольку они должны использовать макет местоположения.

Чтобы сделать это, я сделал следующее:

// returns true if mock location enabled, false if not enabled.
if (Settings.Secure.getString(getContentResolver(),
       Settings.Secure.ALLOW_MOCK_LOCATION).equals("0")) 
       return false; 
       else return true;

Ответ 3

Поскольку API 18, объект Location имеет метод .isFromMockProvider(), чтобы вы могли отфильтровывать поддельные местоположения.

Если вы хотите поддерживать версии до 18, можно использовать что-то вроде этого:

boolean isMock = false;
if (android.os.Build.VERSION.SDK_INT >= 18) {
    isMock = location.isFromMockProvider();
} else {
    isMock = !Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ALLOW_MOCK_LOCATION).equals("0");
}

Ответ 4

Наткнулся на эту ветку пару лет спустя. В 2016 году большинство устройств Android будут иметь уровень API> = 18 и, следовательно, должны полагаться на Location.isFromMockProvider(), как указал Фернандо.

Я много экспериментировал с поддельными/фиктивными местоположениями на разных устройствах Android и дистрибутивах. К сожалению, .isFromMockProvider() не является надежным на 100%. Время от времени поддельное местоположение не будет помечено как ложное. Похоже, это связано с ошибочной внутренней логикой слияния в Google Location API.

Я написал подробный пост в блоге об этом, если вы хотите узнать больше. Подводя итог, если вы подписываетесь на обновления местоположения из Location API, затем включаете поддельное приложение GPS и распечатываете результат каждого Location.toString() на консоль, вы увидите что-то вроде этого:

enter image description here

Обратите внимание, что в потоке обновлений местоположений одно местоположение имеет те же координаты, что и другие, но не помечается как макет и имеет гораздо более низкую точность определения местоположения.

Чтобы исправить эту проблему, я написал служебный класс, который будет надежно подавлять местоположения Mock во всех современных версиях Android (API уровня 15 и выше):

LocationAssistant - без проблем обновления местоположения на Android

По сути, он "не доверяет" не фиктивным местам, которые находятся в пределах 1 км от последнего известного макета, а также помечает их как макет. Это происходит до тех пор, пока не появится значительное количество не фиктивных мест. LocationAssistant может не только отклонять фиктивные местоположения, но и освобождает вас от большинства хлопот, связанных с настройкой и подпиской на обновления местоположений.

Для получения только реальных обновлений местоположения (т.е. Подавления насмешек) используйте его следующим образом:

public class MyActivity extends Activity implements LocationAssistant.Listener {

    private LocationAssistant assistant;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ...
        // You can specify a different accuracy and interval here.
        // The last parameter (allowMockLocations) must be 'false' to suppress mock locations.  
        assistant = new LocationAssistant(this, this, LocationAssistant.Accuracy.HIGH, 5000, false);
    }

    @Override
    protected void onResume() {
        super.onResume();
        assistant.start();
    }

    @Override
    protected void onPause() {
        assistant.stop();
        super.onPause();
    }

    @Override
    public void onNewLocationAvailable(Location location) {
        // No mock locations arriving here
    }

    ...
}

onNewLocationAvailable() теперь будет вызываться только с информацией о реальном местоположении. Есть еще несколько методов прослушивания, которые вам нужно реализовать, но в контексте вашего вопроса (как предотвратить подделку GPS) это в основном так.

Конечно, с рутованной ОС вы все еще можете найти способы подделки информации о местоположении, которые невозможно обнаружить обычным приложениям.

Ответ 5

Если вам удалось узнать общее местоположение ячеек, вы можете проверить, соответствует ли текущая ячейковая башня указанному местоположению (в пределах поля ошибки чего-то большого, например, 10 или более миль).

Например, если ваше приложение разблокирует функции только в том случае, если пользователь находится в определенном месте (например, в вашем магазине), вы можете проверить gps, а также сотовые башни. В настоящее время ни одно приложение для спуфинга gps также не обманывает сотовые башни, поэтому вы можете увидеть, просто ли кто-то по всей стране пытается подделать свой путь в свои специальные функции (например, я думаю о приложении Mobile Mobile для Disney для примера).

Таким образом, приложение Llama управляет местоположением по умолчанию, так как проверка идентификаторов ячеек ячеек значительно менее интенсивна, чем gps. Это не полезно для очень конкретных мест, но если дом и работа находятся в нескольких милях от него, он может легко различать два общих местоположения.

Конечно, для этого требуется, чтобы пользователь имел сигнал ячейки. И вам нужно будет знать все идентификаторы ячеек в этой зоне - у всех поставщиков сети - или вы рискуете ложным отрицанием.

Ответ 6

Этот скрипт работает для всей версии Android, и я нахожу его после многих поисков

LocationManager locMan;
    String[] mockProviders = {LocationManager.GPS_PROVIDER, LocationManager.NETWORK_PROVIDER};

    try {
        locMan = (LocationManager) getSystemService(Context.LOCATION_SERVICE);

        for (String p : mockProviders) {
            if (p.contentEquals(LocationManager.GPS_PROVIDER))
                locMan.addTestProvider(p, false, false, false, false, true, true, true, 1,
                        android.hardware.SensorManager.SENSOR_STATUS_ACCURACY_HIGH);
            else
                locMan.addTestProvider(p, false, false, false, false, true, true, true, 1,
                        android.hardware.SensorManager.SENSOR_STATUS_ACCURACY_LOW);

            locMan.setTestProviderEnabled(p, true);
            locMan.setTestProviderStatus(p, android.location.LocationProvider.AVAILABLE, Bundle.EMPTY,
                    java.lang.System.currentTimeMillis());
        }
    } catch (Exception ignored) {
        // here you should show dialog which is mean the mock location is not enable
    }

Ответ 7

Вы можете добавить дополнительную проверку на основе триангуляции вышек сотовой связи или информации о точках доступа Wi-Fi, используя Google Maps Geolocation API

Самый простой способ получить информацию о CellTowers

final TelephonyManager telephonyManager = (TelephonyManager) appContext.getSystemService(Context.TELEPHONY_SERVICE);
String networkOperator = telephonyManager.getNetworkOperator();
int mcc = Integer.parseInt(networkOperator.substring(0, 3));
int mnc = Integer.parseInt(networkOperator.substring(3));
String operatorName = telephonyManager.getNetworkOperatorName();
final GsmCellLocation cellLocation = (GsmCellLocation) telephonyManager.getCellLocation();
int cid = cellLocation.getCid();
int lac = cellLocation.getLac();

Вы можете сравнить свои результаты с сайтом

Чтобы получить информацию о точках доступа Wi-Fi

final WifiManager mWifiManager = (WifiManager) appContext.getApplicationContext().getSystemService(Context.WIFI_SERVICE);

if (mWifiManager != null && mWifiManager.getWifiState() == WifiManager.WIFI_STATE_ENABLED) {

    // register WiFi scan results receiver
    IntentFilter filter = new IntentFilter();
    filter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);

    BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                List<ScanResult> results = mWifiManager.getScanResults();//<-result list
            }
        };

        appContext.registerReceiver(broadcastReceiver, filter);

        // start WiFi Scan
        mWifiManager.startScan();
}

Ответ 8

попробуйте этот код очень просто и полезно

  public boolean isMockLocationEnabled() {
        boolean isMockLocation = false;
        try {
            //if marshmallow
            if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                AppOpsManager opsManager = (AppOpsManager) getApplicationContext().getSystemService(Context.APP_OPS_SERVICE);
                isMockLocation = (opsManager.checkOp(AppOpsManager.OPSTR_MOCK_LOCATION, android.os.Process.myUid(), BuildConfig.APPLICATION_ID)== AppOpsManager.MODE_ALLOWED);
            } else {
                // in marshmallow this will always return true
                isMockLocation = !android.provider.Settings.Secure.getString(getApplicationContext().getContentResolver(), "mock_location").equals("0");
            }
        } catch (Exception e) {
            return isMockLocation;
        }
        return isMockLocation;
    }