iOS 检测模拟位置
iOS detect mock locations
目前我正在开发一款应用程序,其中地理定位功能是其最重要的功能。实际上,我们非常关心模拟 GPS 值。我在 iOS 和 Android 上阅读了很多关于模拟位置的评论,其中大多数倾向于解释未越狱的 iOS 设备无法模拟位置,但事实是我我创建了另一个项目,使用 GPX 文件模拟该项目的位置,当执行时,整个系统认为我在另一个城市。我所有的 locationManager 回调都告诉我,我正处于具有正确时间戳的模拟位置,伪造整个信息就像它是真实的一样。这完全违背了我们应用程序的目的,因为用户可以在去过的地方伪造。
有什么方法可以检测并防止这种行为吗?我假设一个封闭的目标,攻击者必须是开发人员才能使这个漏洞发挥作用,但唉,它仍然存在
我认为不可能检测到位置模拟器。
伪装位置的更简单方法是使用外部蓝牙或串行连接到 GPS simulator that outputs NMEA sentences。尽管您确实需要 Android phone 到 运行 模拟器,但您不需要开发者帐户。
iPhone 将自动检测外部 GPS,CLLocationManager
将使用外部 GPS 源代替自己的内部 GPS。这对于地图和导航应用程序的实验室测试非常方便。
问题:有什么方法可以检测并防止这种行为?
实际上有 2 个不同的问题:(1) 如何检测,以及 (2) 如何预防?
(1) 的答案:模拟位置行为与回调时的真实位置行为完全不同 locationManager:didUpdateLocations:
[模拟位置] 回调 returns 几乎在调用 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 Час: Індокитай
[real locations] 回拨需要几秒(如果先运行),然后随机重拨。即使您根本不移动,您也可以看到这些位置之间发生重大变化的时间。这是一个例子:
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 上模拟位置:
不幸的是,它仍然允许模拟位置。
您可能知道的更多问题here。
希望对你有帮助。
为了详细说明@KennyHo 的回答,我发现真实位置反馈和模拟位置反馈之间还有另一个区别。
一个模拟位置,正如我注意到的,总是returns这些位置的值组合properties/options:
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.
中欺骗您的应用程序
也可以使用 software-defined 收音机和 GitHub 的 gps-sdr-sim 来欺骗 iPhone。
您使用 gps-sdr-sim 生成包含 GPS 信号的 I/Q 文件,并使用 SDR 传输这些样本 over-the-air。
这种欺骗更难检测。
自 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)然后会更新我的答案。
目前我正在开发一款应用程序,其中地理定位功能是其最重要的功能。实际上,我们非常关心模拟 GPS 值。我在 iOS 和 Android 上阅读了很多关于模拟位置的评论,其中大多数倾向于解释未越狱的 iOS 设备无法模拟位置,但事实是我我创建了另一个项目,使用 GPX 文件模拟该项目的位置,当执行时,整个系统认为我在另一个城市。我所有的 locationManager 回调都告诉我,我正处于具有正确时间戳的模拟位置,伪造整个信息就像它是真实的一样。这完全违背了我们应用程序的目的,因为用户可以在去过的地方伪造。
有什么方法可以检测并防止这种行为吗?我假设一个封闭的目标,攻击者必须是开发人员才能使这个漏洞发挥作用,但唉,它仍然存在
我认为不可能检测到位置模拟器。
伪装位置的更简单方法是使用外部蓝牙或串行连接到 GPS simulator that outputs NMEA sentences。尽管您确实需要 Android phone 到 运行 模拟器,但您不需要开发者帐户。
iPhone 将自动检测外部 GPS,CLLocationManager
将使用外部 GPS 源代替自己的内部 GPS。这对于地图和导航应用程序的实验室测试非常方便。
问题:有什么方法可以检测并防止这种行为?
实际上有 2 个不同的问题:(1) 如何检测,以及 (2) 如何预防?
(1) 的答案:模拟位置行为与回调时的真实位置行为完全不同 locationManager:didUpdateLocations:
[模拟位置] 回调 returns 几乎在调用 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 Час: Індокитай
[real locations] 回拨需要几秒(如果先运行),然后随机重拨。即使您根本不移动,您也可以看到这些位置之间发生重大变化的时间。这是一个例子:
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 上模拟位置:
您可能知道的更多问题here。 希望对你有帮助。
为了详细说明@KennyHo 的回答,我发现真实位置反馈和模拟位置反馈之间还有另一个区别。
一个模拟位置,正如我注意到的,总是returns这些位置的值组合properties/options:
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.
也可以使用 software-defined 收音机和 GitHub 的 gps-sdr-sim 来欺骗 iPhone。 您使用 gps-sdr-sim 生成包含 GPS 信号的 I/Q 文件,并使用 SDR 传输这些样本 over-the-air。 这种欺骗更难检测。
自 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)然后会更新我的答案。