看啥推荐读物
专栏名称: 欧阳大哥2013
目录
相关文章推荐
今天看啥  ›  专栏  ›  欧阳大哥2013

iOS防黑产虚假定位检测技术

欧阳大哥2013  · 掘金  ·  · 2021-03-11 09:09
阅读 13

iOS防黑产虚假定位检测技术

我们的很多应用中都会使用到系统的定位功能,通过定位功能就可以知道手机当前所在的位置,进而获得当前所在的城市,进而进行一些特定的基于地理位置的推荐或者消息推送。还有一些应用会借助当前的位置进行考勤打卡处理。出行软件会借助定位进行线路选择和导航处理。因此基于定位的应用无处不在。而那些基于定位产生收益的应用更是严重依赖定位系统的正确性。

有收益就意味这有人会应用不正当的手段来获取不正当的利益。既然定位这么重要,那么如果能够模拟出当前的位置或者模拟出特定的位置,黑产人员就可以利用一些漏洞来获取不当的利益。如何打击黑产就成为应用安全和风控部门的重要任务。

在iOS中获取当前定位位置的框架叫CoreLocation.framework。我们可以通过CLLocation来得到一个经纬度坐标信息,具体如何获取的这里就不详细介绍了。CLLocation对象明面上所携带的信息只有经纬度、海拔、方向、速度、精确度等几个属性。

我们知道手机上定位数据的产生主要来源于手机和GPS卫星通讯产生的位置,或者手机和基站通信时根据基站和手机的距离算出当前的坐标位置,或者手机连接wifi时根据wifi站点和手机的距离算出当前的坐标位置,也就是每个坐标位置都应该有一个数据来源。 在Android系统中我们就很容易拿到坐标的源,但是在iOS系统中我们是无法拿到每个坐标的源的,至少公开层面是拿不到的。

目前黑产主要通过3个手段来实现坐标位置的模拟的:

  1. 在越狱设备中通过方法交换的形式来拦截CLLocationManager对象的delegate属性中的- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations 实现来返回虚假的定位数据。

  2. 在未越狱的设备上通过电脑和手机进行USB连接,电脑通过特殊协议向手机上的DTSimulateLocation服务发送模拟的坐标数据来实现虚假定位,目前Xcode上内置位置模拟就是借助这个技术来实现的。

  3. 在未越狱的设备上通过符合MFI认证的蓝牙设备和手机连接,并通过MFI蓝牙设备向手机发送虚假的定位数据来实现定位模拟。比较有代表意义的就是市面上的:位置精灵app

上面的3种方法中,前面越狱设备上的虚假定位数据还好检测,而后面两种基于非越狱的虚拟定位数据的模拟因为是系统层面的,所以我们的应用根本无法检测得到。

真的就这样无能为力,让黑产肆意的产生无法被发现的虚拟定位数据吗?当然不是。因为这些虚拟的定位数据并不是真实的定位源所产生的数据,如果我们能够找到每个定位坐标的来源,并发现这些虚假定位数据的特征,问题就迎刃而解了。其实所有的这些信息就藏在前面提到的CLLocation对象中。

在每个CLLocation对象中有一个内部的私有数据成员:_internal 这个内部的私有属性是一个内部类CLLocationInternal的实例。而这个内部类CLLocationInternal中有一个结构体CLLocationInfo指针数据成员:fLocationCLLocationInfo结构体定义如下:

struct CLLocationInfo {
#if defined(__i386__) || defined(__x86_64__)
    int padding1;
#endif
    int suitability;    //定位的magic数
    CLLocationCoordinate2D coordinate;   //经纬度
    CLLocationAccuracy horizontalAccuracy;   //水平精确度
    CLLocationDistance altitude;    //海拔
    CLLocationAccuracy verticalAccuracy;  //垂直精确度 
#if defined(__i386__) || defined(__x86_64__)
    double padding2;
    double padding3;
#endif
    CLLocationSpeed speed;   //速度
    CLLocationAccuracy speedAccuracy;  //速度精确度
    CLLocationDirection course;   //方向
    CLLocationAccuracy courseAccuracy;  //方向精确度
    double timestamp;  //时间戳
    int confidence;   //置信值?
    double lifespan;   //有效期限?
    int type;   //定位数据来源类型
   CLLocationCoordinate2D rawCoordinate;  //原始经纬度
    CLLocationDirection rawCourse;    //原始方向
    int floor;     //楼层
#if !defined(__i386__)
    unsigned int integrity; //信息完整度? :75=High 50=Medium  25=Low  0=None
    int referenceFrame; //参考坐标系:2=ChinaShifted 1=wgs84 0=unknown
    int rawReferenceFrame;  //原始参考坐标系
#endif
};
复制代码

定位对象内部结构

可以在上述的结构体中看到很多隐藏的数据信息。CLLocation对象中的那些对外公开的属性其实都是通过读取这个结构体的成员数据来返回的。在上述的结构体中有一个很重要的数据成员type。这个数据成员就是用来标明当前定位的数据是怎么产生的,也就是定位来源。具体的取值如下:

所表示的意义备注
0unknown应用程序生成的定位数据,一般在越狱设备下,通过虚拟定位程序来生成。
1gpsGPS生成的定位数据
2nmea
3accessory蓝牙等外部设备模拟定位生成的定位数据
4wifiWIFI定位生成的数据
5skyhookWIFI定位生成的数据
6cell手机基站定位生成的数据
7lacLAC生成的定位数据
8mcc
9gpscoarse
10pipeline
11max

上述表格的类型定义来源于苹果的定位服务locationd中

从上面的类型定义中可以看出:只要是我们手动创建的CLLocation对象其type值都是0。只要是通过蓝牙等外设生成的定位对象type值都是3。如果是系统正常生成的定位对象则type值通常为1或者4或者6三个值。当然我们不能单纯通过type类判定某个定位数据是否是虚拟定位数据,而是应该通过更多的特征值来判断。下面的表格分别列举出了:正常、手动或越狱拦截、DTSimulateLocation服务模拟、蓝牙设备模拟 一共四种情况下CLLocationInfo结构体中各成员的数据值:

结构体成员中文描述正常手动或越狱拦截DTSimulateLocation服务模拟蓝牙设备模拟
suitabilitymagic数65535655356553565535
coordinate经纬度正常值指定值模拟值模拟值
horizontalAccuracy水平精确度正常值或-1指定值或05模拟值
altitude海拔正常值或-1指定值或00模拟值
verticalAccuracy垂直精确度正常值或-1指定值或-1小于0模拟值
speed速度正常值或-1指定值或-1小于0模拟值
speedAccuracy速度精确度正常值或-1-1小于0模拟值
course方向正常值或-1指定值或-1小于0模拟值
courseAccuracy方向精确度正常值或-1-1小于0模拟值
timestamp时间戳系统生成系统生成或指定系统生成系统生成
confidence置信值?正常值010095
lifespan有效期限?正常值或-1-1-110
type定位数据来源类型上面的枚举值013
rawCoordinate原始经纬度正常值0模拟值模拟值
rawCourse原始方向正常值或-1-1-1模拟值
floor楼层2147483647214748364721474836472147483647
integrity信息完整度?正常值0050
referenceFrame参考坐标系枚举值00或11
rawReferenceFrame原始参考坐标系枚举值001

上述的表格中可以看出不同的定位方法所产生的数据是不一样的,我们可以根据这些特征值来进一步分析本次定位对象所生成的数据是模拟的定位数据还是真实的定位数据。同时我们还可以借助这个完整的结构体来分析正常定位情况下的一些更加详细的定位信息。比如那些不对外公布的属性:speedAccuracy、courseAccuracy、confidence、lifespan、integrity 等的值来更进一步的分析当前定坐标的有效性或者完整性等方面的信息。


更多文章请关注欧阳大哥的:简书掘金账号




原文地址:访问原文地址
快照地址: 访问文章快照