Deaktivieren / Auf Scheinposition prüfen (GPS-Spoofing verhindern)

89

Suchen Sie nach dem besten Weg, um GPS-Spoofing unter Android zu verhindern / zu erkennen. Irgendwelche Vorschläge, wie dies erreicht wird und was getan werden kann, um es zu stoppen? Ich vermute, der Benutzer muss Scheinstandorte aktivieren, um GPS zu fälschen. Wenn dies getan wird, kann er dann GPS fälschen?

Ich denke, ich müsste nur erkennen, ob Mock Locations aktiviert sind. Irgendwelche anderen Vorschläge?

Chrispix
quelle
2
Ich denke, er fragt nach der Location Spoofing-Funktion, die in der DDMS-Ansicht in Eclipse verfügbar ist.
Shawn Walton
2
Ich habe ein standortbasiertes Spiel, bei dem ich nicht möchte, dass Leute betrügen, also kann ich Spoofing blockieren. Meines Wissens nach kann dies auf zwei Arten geschehen. Wenn Mock-Standorte aktiviert sind und ein benutzerdefiniertes Bild erstellt wird, das Spoofing auf niedriger Ebene ausführt und ignoriert die Spoofing-Einstellung in der Einstellungs-App. Versuchen Sie, den Settings.System Provider für MockLocations zu finden, oder prüfen Sie, ob er aktiviert wird (mit einem Listener in der Mitte der App).
Chrispix

Antworten:

124

Ich habe einige Nachforschungen angestellt und meine Ergebnisse hier geteilt. Dies kann für andere nützlich sein.

Zunächst können wir überprüfen, ob die Option MockSetting aktiviert ist

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;
}

Zweitens können wir überprüfen, ob andere Apps im Gerät vorhanden sind, die verwendet werden android.permission.ACCESS_MOCK_LOCATION(Location Spoofing Apps).

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;
}

Wenn beide oben genannten Methoden, erste und zweite, zutreffen, besteht eine gute Chance, dass der Standort gefälscht oder gefälscht wird.

Jetzt kann Spoofing mithilfe der API von Location Manager vermieden werden.

Wir können den Testanbieter entfernen, bevor wir die Standortaktualisierungen von beiden Anbietern (Netzwerk und GPS) anfordern.

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);

Ich habe gesehen, dass removeTestProvider (~) sehr gut über Jelly Bean und ab Version funktioniert. Diese API schien bis zum Ice Cream Sandwich unzuverlässig zu sein.

Jambaaz
quelle
Sehr interessante Beobachtungen. Besonders die letzte +1 für das Teilen.
Ar-g
2
Hinweis zur removeTestProvider-Methode. Wenn Sie zulassen, dass der Standortmanager im Hintergrund arbeitet, kann der Benutzer zur Mock-App gehen und den Mock-Standort neu starten. Ihr Standortmanager empfängt dann Scheinstandorte, bis Sie removeTestProvider erneut aufrufen.
Timur_C
4
Ihre App muss die android.permission.ACCESS_MOCK_LOCATIONErlaubnis für removeTestProviderzu arbeiten, die ich denke , der größte Nachteil ist.
Timur_C
17
Danke für die Antwort! Nur ein Punkt: In Android 6.0 ist ALLOW_MOCK_LOCATION veraltet. Und tatsächlich gibt es auch kein Kontrollkästchen für die Scheinposition. Man kann überprüfen, ob der Standort falsch ist oder nicht, direkt vom Standortobjekt: location.isFromMockProvider ()
Silwester
2
@ Blackkara Ich habe es doch nicht benutzt. Früher habe ich eine maßgeschneiderte Kombination aus isMockSettingsON(), Location.isFromMockProvider()und areThereMockPermissionApps()mit einer schwarzen Liste der Anwendungen. Es gibt viele vorinstallierte System-Apps mit ACCESS_MOCK_LOCATION Berechtigung, beispielsweise auf HTC- und Samsung-Geräten. Eine Whitelist aller legitimen Apps wäre besser, aber eine schwarze Liste der beliebtesten Location-Spoofing-Apps hat in meinem Fall gut funktioniert. Außerdem habe ich überprüft, ob das Gerät gerootet ist.
Timur_C
44

Seit API 18 verfügt das Objekt Location über die Methode .isFromMockProvider (), sodass Sie gefälschte Speicherorte herausfiltern können.

Wenn Sie Versionen vor 18 unterstützen möchten, können Sie Folgendes verwenden:

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");
}
Fernando
quelle
Ich bin mir ziemlich sicher, dass Ihr zweiter Ausdruck rückwärts ist (geben Sie true zurück, wenn er false zurückgeben soll). Ich denke, es sollte sein:isMock = !Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ALLOW_MOCK_LOCATION).equals("0");
AjahnCharles
3
Bitte. Vielen Dank für die Veröffentlichung einer moderneren Antwort! Wirklich, das ist ab heute die richtige Antwort.
AjahnCharles
1
Wie können wir es ohne "Standort" -Objekt für SDK über 18 tun?
Ajit Sharma
35

Es scheint, dass der einzige Weg, dies zu tun, darin besteht, Location Spoofing zu verhindern, das MockLocations verhindert. Der Nachteil ist, dass einige Benutzer Bluetooth-GPS-Geräte verwenden, um ein besseres Signal zu erhalten. Sie können die App nicht verwenden, da sie die Scheinpositionen verwenden müssen.

Dazu habe ich Folgendes getan:

// 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;
Chrispix
quelle
4
Dies ist jedoch kein Kinderspiel. Benutzer auf einem nicht gerooteten Gerät können weiterhin einen Scheinspeicherort mit einer Zeit in der Zukunft festlegen, dann Scheinstandorte deaktivieren und der Scheinort ist weiterhin aktiv. Schlimmer noch, sie können den Scheinstandort den gleichen Anbieternamen wie Network / Gps nennen und er zieht anscheinend davon ab.
Chrispix
2
Darüber hinaus erfordert Fake GPS nicht die Scheinstandorteinstellung auf gerooteten Geräten.
Paul Lammertsma
Konnte immer überprüfen, ob die fake.gps App nicht installiert ist :)
Chrispix
11
Sie können return !xanstelle von verwenden if(x) return false; else return true.
CodesInChaos
Tatsächlich ändert der falsche Standort die Einstellung des falschen Standorts auch auf gerooteten Geräten.
PageNotFound
24

Stolperte ein paar Jahre später über diesen Thread. 2016 werden die meisten Android-Geräte eine API-Stufe> = 18 haben und sollten sich daher auf Location.isFromMockProvider () verlassen, wie von Fernando hervorgehoben .

Ich habe ausgiebig mit Fake / Mock-Standorten auf verschiedenen Android-Geräten und Distributionen experimentiert. Leider ist .isFromMockProvider () nicht 100% zuverlässig. Hin und wieder wird ein gefälschter Ort nicht als Schein gekennzeichnet . Dies scheint auf eine fehlerhafte interne Fusionslogik in der Google Location API zurückzuführen zu sein.

Ich habe einen ausführlichen Blog-Beitrag darüber geschrieben , wenn Sie mehr erfahren möchten. Zusammenfassend lässt sich sagen, dass Sie, wenn Sie Standortaktualisierungen über die Standort-API abonnieren, eine gefälschte GPS-App einschalten und das Ergebnis jeder Location.toString () auf der Konsole drucken , Folgendes sehen:

Geben Sie hier die Bildbeschreibung ein

Beachten Sie, dass im Stream der Standortaktualisierungen ein Standort dieselben Koordinaten wie die anderen hat, jedoch nicht als Schein gekennzeichnet ist und eine viel schlechtere Standortgenauigkeit aufweist.

Um dieses Problem zu beheben, schrieb ich eine Utility - Klasse, wird zuverlässig unterdrücken Mock Standorte auf alle modernen Android - Versionen (API Level 15 und höher):

LocationAssistant - Problemlose Standortaktualisierungen für Android

Grundsätzlich "misstraut" es Nicht-Scheinorten, die sich innerhalb von 1 km vom letzten bekannten Scheinort befinden, und bezeichnet sie auch als Schein. Dies geschieht so lange, bis eine erhebliche Anzahl von nicht nachgebildeten Standorten eingetroffen ist. Der LocationAssistant kann nicht nur Scheinstandorte ablehnen, sondern entlastet Sie auch von den meisten Problemen beim Einrichten und Abonnieren von Standortaktualisierungen.

Verwenden Sie es wie folgt, um nur echte Standortaktualisierungen zu erhalten (dh Verspottungen zu unterdrücken):

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()wird jetzt nur noch mit realen Standortinformationen aufgerufen. Es gibt einige weitere Listener-Methoden, die Sie implementieren müssen, aber im Kontext Ihrer Frage (wie Sie GPS-Spoofing verhindern können) ist dies im Grunde genommen alles.

Natürlich können Sie mit einem verwurzelten Betriebssystem immer noch Möglichkeiten finden, Standortinformationen zu fälschen, die normale Apps nicht erkennen können.

KlaasNotFound
quelle
Sie sollten den verknüpften Blog-Beitrag kurz zusammenfassen (wo schlägt isFromMockProvider fehl?).
AjahnCharles
@ CodeConfident - danke für die Bemerkung! Ich bin mir nicht sicher, was ich hinzufügen soll. Der zweite Absatz meiner Antwort ist die Zusammenfassung des Blogposts. .isFromMockProvider schlägt sporadisch und unvorhersehbar fehl. In dem Artikel beschreibe ich nur detaillierter die Schritte, die ich unternommen habe, um dies zu entdecken und zu beheben.
KlaasNotFound
Nun, ich war gezwungen, zu Ihrem Artikel zu springen, um zu verstehen, was für mich gegen die Absicht von SO verstößt. Mein bester Vorschlag wäre: (1) Fügen Sie Ihr Bild ein, das den zwielichtigen Ort zeigt (nicht als Schein markiert), und (2) notieren Sie schnell Ihre Logik, um sie zu beseitigen (ignorieren Sie innerhalb von 1 km von einem Schein)
AjahnCharles
Ok, gotcha. Ich denke, im Kontext des OP sind die Einzelheiten, warum .isFromMockProvider () unzuverlässig ist, nicht allzu relevant. Aber ich werde versuchen, die Details hinzuzufügen, die Sie für das Gesamtbild erwähnt haben. Danke für die Rückmeldung!
KlaasNotFound
1
Was passiert, wenn der Nutzer den Google Play Service nicht installiert hat?
Yuriy Chernyshov
6

Wenn Sie zufällig die allgemeine Position von Zelltürmen kennen, können Sie überprüfen, ob der aktuelle Zellturm mit der angegebenen Position übereinstimmt (innerhalb einer Fehlergrenze von etwas Großem, z. B. 10 oder mehr Meilen).

Wenn Ihre App beispielsweise Funktionen nur dann entsperrt, wenn sich der Benutzer an einem bestimmten Ort befindet (z. B. in Ihrem Geschäft), können Sie sowohl GPS- als auch Mobilfunkmasten überprüfen. Derzeit fälscht keine GPS-Spoofing-App auch die Mobilfunkmasten, sodass Sie sehen können, ob jemand im ganzen Land einfach versucht, sich in Ihre speziellen Funktionen hineinzuversetzen (ich denke zum Beispiel an die Disney Mobile Magic-App).

Auf diese Weise verwaltet die Llama-App standardmäßig den Standort, da die Überprüfung der IDs des Mobilfunkmastes viel weniger batterieintensiv ist als das GPS. Es ist nicht sehr nützlich für ganz bestimmte Orte, aber wenn Haus und Arbeit mehrere Meilen entfernt sind, kann es sehr leicht zwischen den beiden allgemeinen Orten unterscheiden.

Dies würde natürlich erfordern, dass der Benutzer überhaupt ein Zellensignal hat. Und Sie müssten alle IDs der Mobilfunkmasten in der Region kennen - bei allen Netzwerkanbietern - oder Sie laufen Gefahr, ein falsches Negativ zu erhalten.

Stephen Schrauger
quelle
1
Danke, das ist eine ziemlich gute Idee. Ich muss das vielleicht untersuchen. Vielen Dank
Chrispix
3

Versuchen Sie diesen Code, es ist sehr einfach und nützlich

  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;
    }
Mostafa Pirhayati
quelle
Dies ist eine viel bessere Version der obigen isMockLocationEnabled-Methode.
Setzamora
AppOpsManager.checkOp () löst eine SecurityException aus, wenn die App so konfiguriert wurde, dass sie bei dieser Operation abstürzt. Wie: java.lang.SecurityException: Paketname von UID 11151 darf MOCK_LOCATION nicht ausführen. Mit dieser Methode wird erkannt, ob Ihre App Standorte verspotten kann. Aber nicht "wenn empfangene Standorte verspottet werden".
Sergio
@Sergio mit "Wenn Ihre App Standorte verspotten kann" meinen Sie, wenn die aktuelle App die Berechtigung hat, Standorte zu verspotten, oder?
Victor Laerte
@ VictorLaerte Ich habe zuletzt einen Kontext eines Themas: / Richtig. Die Frage war jedoch: "Wie kann festgestellt werden, ob ein empfangener Standort verspottet ist oder von einem Scheinanbieter stammt?" Oder wie man gefälschte Orte ignoriert.
Sergio
2

Dieser Scrip funktioniert für alle Android-Versionen und ich finde ihn nach vielen Suchen

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
    }
Ali
quelle
1

Mithilfe der Google Maps Geolocation-API können Sie zusätzliche Überprüfungen basierend auf der Triangulation des Zellturms oder Informationen zu WLAN-Zugangspunkten hinzufügen

Der einfachste Weg, um Informationen über CellTowers zu erhalten

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();

Sie können Ihre Ergebnisse mit der Website vergleichen

Informationen zu Wifi Access Points erhalten

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();
}
yoAlex5
quelle