iOS 检测模拟位置

问题描述 投票:0回答:6

目前我正在开发一款应用程序,其中地理定位功能是其最重要的功能。实际上,我们非常关心模拟 GPS 值。我读过很多关于在 iOS 和 Android 上模拟位置的评论,其中大多数都倾向于解释未越狱的 iOS 设备无法模拟位置,但事实是我创建了另一个项目,使用 GPX 文件进行模拟在该项目上设置位置并在执行时,整个系统都认为我在另一个城市。我所有的 locationManager 回调都告诉我,我正处于具有正确时间戳的模拟位置,伪造整个信息就像它是真实的一样。这完全违背了我们应用程序的目的,因为用户可以在去过的地方伪造。

有什么方法可以检测并防止这种行为?我假设一个封闭的目标,攻击者必须是开发人员才能使这个漏洞发挥作用,但唉,它仍然存在

ios security gps core-location
6个回答
12
投票

为了详细说明@KennyHo 的回答,我发现真实位置反馈和模拟位置反馈之间还有另一个区别。

A simulated location,正如我所注意到的,总是返回这些位置属性/选项的值组合:

horizontalAccuracy: 5
verticalAccuracy: -1
altitude: 0.000000
speed: -1

真实位置会在99%的情况下给出不同的组合,例如

horizontalAccuracy: 5
verticalAccuracy: 10
altitude: +/- 0.4243232
speed: -1

请注意,模拟位置可能具有与上述组合不同的组合,但前提是用户使用 xcode Automation target test。但是,用户只能将位置模拟到具有开发身份的已签名应用程序(必须拥有该应用程序)。这意味着除了你之外,没有人可以用不同的

altitude
verticalAccuracy
伪造一个位置来欺骗你在 xcode 中的应用程序。


9
投票

问题:有什么方法可以检测并防止这种行为吗?

实际上有2个不同的问题:(1)如何检测,以及(2)如何预防?

(1)的答案:模拟位置行为与真实位置行为在回调 locationManager:didUpdateLocations:

[simulated locations] 回调几乎在调用 startUpdatingLocation 后立即返回,然后每隔一秒重复调用一次。如果我们选择固定位置,位置也都是相同的。这是一个例子:

location: <+51.50998000,-0.13370000> +/- 5.00m (speed -1.00 mps / course -1.00) @ 30.03.15 14:12:48 Час: Індокитай
location: <+51.50998000,-0.13370000> +/- 5.00m (speed -1.00 mps / course -1.00) @ 30.03.15 14:12:49 Час: Індокитай
location: <+51.50998000,-0.13370000> +/- 5.00m (speed -1.00 mps / course -1.00) @ 30.03.15 14:12:50 Час: Індокитай
location: <+51.50998000,-0.13370000> +/- 5.00m (speed -1.00 mps / course -1.00) @ 30.03.15 14:12:51 Час: Індокитай
location: <+51.50998000,-0.13370000> +/- 5.00m (speed -1.00 mps / course -1.00) @ 30.03.15 14:12:52 Час: Індокитай
location: <+51.50998000,-0.13370000> +/- 5.00m (speed -1.00 mps / course -1.00) @ 30.03.15 14:12:53 Час: Індокитай
location: <+51.50998000,-0.13370000> +/- 5.00m (speed -1.00 mps / course -1.00) @ 30.03.15 14:12:54 Час: Індокитай

[真实位置]需要几秒钟(如果是第一次运行)回拨然后随机重新呼叫。即使您根本不移动,您也可以看到这些位置之间发生重大变化的时间。这是一个例子:

location: <+10.77219361,+106.70597441> +/- 67.39m (speed -1.00 mps / course -1.00) @ 30.03.15 14:16:26 Час: Індокитай
location: <+10.77213011,+106.70591088> +/- 65.00m (speed -1.00 mps / course -1.00) @ 30.03.15 14:16:31 Час: Індокитай
location: <+10.77219507,+106.70587790> +/- 65.00m (speed -1.00 mps / course -1.00) @ 30.03.15 14:16:38 Час: Індокитай
location: <+10.77214753,+106.70587741> +/- 65.00m (speed -1.00 mps / course -1.00) @ 30.03.15 14:16:49 Час: Індокитай

(2)的答案:为了防止,我现在只是解决问题,我们需要查找至少 3 个位置来确定它是模拟位置还是真实位置。

提醒,这只是检测模拟位置的临时解决方案。将来,Apple 可能会改变这种行为。

顺便说一句,我还尝试在方案中禁止在 xCode 上模拟位置: enter image description here 不幸的是,它仍然允许模拟位置。

您可能知道的更多问题在这里。 希望它有所帮助。


7
投票

自 iOS15 到来以来,苹果在

CLLocation
中引入了两个新属性:

    /*
     * isSimulatedBySoftware
     *
     * Discussion:
     *  Set to YES if this location was detected as being generated by a software simulator, such as Xcode
     */
    open var isSimulatedBySoftware: Bool { get }

    
    /*
     * isProducedByAccessory
     *
     * Discussion:
     *  Set to YES if this location was generated from an external accessory, such as CarPlay or an MFi accessory
     */
    open var isProducedByAccessory: Bool { get }

这两个物业位于:

/*
 *  sourceInformation
 *
 *  Discussion:
 *    Contains information about the source of this location.
 */
@available(iOS 15.0, *)
open var sourceInformation: CLLocationSourceInformation? { get }

我已经使用第三方应用程序和 xcode 等虚拟位置生成器对此进行了测试,

isSimulatedBySoftware
在每种情况下都是如此。我将订购一个外部 GPS 设备以确保另一个也能正常工作(希望 :D)然后更新我的答案。


3
投票

我不相信可以检测位置模拟器。

伪造位置的更简单方法是使用外部蓝牙或串行连接到输出 NMEA 语句GPS 模拟器。尽管您确实需要 Android 手机来运行模拟器,但您不需要开发者帐户。

iPhone 将自动检测外部 GPS,

CLLocationManager
将使用外部 GPS 源代替自己的内部 GPS。它对于地图和导航应用程序的实验室测试非常方便。


2
投票

还可以使用来自 GitHub 的软件定义无线电和 gps-sdr-sim 来欺骗 iPhone。 您使用 gps-sdr-sim 生成包含 GPS 信号的 I/Q 文件,并使用 SDR 通过空中传输这些样本。 这种欺骗更难检测。


0
投票

我还遇到了在 iOS 设备上检测模拟位置的问题。其中一名测试用户能够通过使用模拟软件伪造其位置。但是,我通过使用“isSimulatedBySoftware”和“isProducedByAccessory”属性找到了一个解决方案。

以下代码对我有用:

let locationManager = CLLocationManager()
        if #available(iOS 15.0, *) {
            // use UICollectionViewCompositionalLayout
            let isLocationSimulated = locationManager.location?.sourceInformation?.isSimulatedBySoftware ?? false
            let isProducedByAccess = locationManager.location?.sourceInformation?.isProducedByAccessory ?? false
            
            let info = CLLocationSourceInformation(softwareSimulationState: isLocationSimulated, andExternalAccessoryState: isProducedByAccess)
            
            if info.isSimulatedBySoftware == true || info.isProducedByAccessory == true{
                result(true)
            } else {
                result(false)
            }
        }
        else{
            result(false)
        }

此外,我为 Flutter 开发人员创建了一个可以检测虚假位置的包/插件。该软件包可在 https://pub.dev/packages/detect_fake_location.

© www.soinside.com 2019 - 2024. All rights reserved.