这里统一回复下,昨天写了篇关于微信运动刷榜的文章,考虑到微信运动是一个传播正能量,引领健康,宣起了全民运动热潮的公益应用,微信运动方面也做了沟通,刷榜这种行为不益于微信运动的健康生态,所以删除。
作者想说的是,现在对自己的健康作弊,最后伤害的还是自己,运动不在于多少,在于问心无愧,每天多走一步,用真实的数据说话。
记步问题
关于如何统计每天的步数,自己统计,需要长时间后台刷新,不太可行。所以微信运动采取的是读取health里的数据。下面是我写的统计当天步数的代码,原理都是一样的:
func readTotalSteps(completion: ((Int) -> Void)) {
...
let predicate = HKQuery.predicateForSamplesWithStartDate(startDate, endDate: endDate, options: .None)
let sampleQuery = HKSampleQuery(sampleType: sampleType!, predicate: predicate, limit: 0, sortDescriptors: nil, resultsHandler: {
(sampleQuery, results, error ) -> Void in
if let queryError = error {
print( "There was an error while reading the samples: \(queryError.localizedDescription)")
}
var steps: Double = 0
if results?.count > 0 {
for result in results as! [HKQuantitySample] {
steps += result.quantity.doubleValueForUnit(HKUnit.countUnit())
}
}
completion(Int(steps))
})
healthKitStore.executeQuery(sampleQuery)
}
所以说,这样也就给了我们作弊的可能,因为我们也可以随意向heathlKit里面随意写入数据,而且是在不越狱的前提下,目前都是基于这种方法刷榜的。
如何防范
难道我们就这样放任不管吗,那些每天认认真真运动的人反而排在最后,这对微信运动的健康生态十分不益。
那我们该如何防范呢,我是从HKQuantitySample
入手的,对于每一个HKQuantitySample
类的result,都有一个source
属性,对应的是HKSource
,再看HKSource
:
/*!
@class HKSource
@abstract Represents the entity that created an object stored by HealthKit.
*/
@available(iOS 8.0, *)
class HKSource : NSObject, NSSecureCoding, NSCoding, NSCopying {
/*!
@property name
@abstract The name of the source represented by the receiver. If the source is an app, then the name is the
localized name of the app.
*/
var name: String { get }
/*!
@property bundleIdentifier
@abstract The bundle identifier of the source represented by the receiver.
*/
var bundleIdentifier: String { get }
/*!
@method defaultSource
@abstract Returns the source representing the calling application.
*/
class func defaultSource() -> HKSource
}
这样说,我们可以校验这两个属性值来筛选数据咯,name
指的是数据来源的名字,如果是手机自己添加的则是本机名,通过第三方应用添加的则对应其应用名,bundleIdentifier
地球人都知道。更改之前的代码如下:
func readTotalSteps(completion: ((Int) -> Void)) {
...
let sampleQuery = HKSampleQuery(sampleType: sampleType!, predicate: predicate, limit: 0, sortDescriptors: nil, resultsHandler: {
(sampleQuery, results, error ) -> Void in
...
var steps: Double = 0
if results?.count > 0 {
let deviceName = UIDevice.currentDevice().name
let healthBId = "com.apple.health"
for result in results as! [HKQuantitySample] {
let name = result.source.name
let bid = result.source.bundleIdentifier
if name == deviceName && bid.hasPrefix(healthBId) {
steps += result.quantity.doubleValueForUnit(HKUnit.countUnit())
}
}
}
completion(Int(steps))
})
这样就完美过滤其他数据来源,真实还原health数据,不知道以后微信运动会不会采取这种方式。
然而这种方式存在固然的缺陷,一些正规的第三方运动应用添加的数据也会被过滤掉,难道以后要加白名单机制?想出现在微信运动里的运动应用(小米运动之类的)需要向微信审核??
反过来想想
对于上面这种过滤,是否存在绕过呢?
对于验证数据来源名字是否是本机,这个我们可以将应用名改成本机名,本地操作,秒秒钟的事情,不成问题。然而对于那种分发上线的应用,这个就比较困难了,我不知道有什么方法或者不存在方法。
对于
bundle Identifier
的伪造与修改,这个也是本地操作,假面攻击就是与之相关,因为该漏洞(iOS 8.4已修复部分),health应用的bundle Identifier后面有了一串随机数,com.apple.health.EBE76334-789F-400D-9214-0581002D49CE
,我们获取它然后将自己的应用改成它,然后企业签名,再插入数据。
这里说说题外话,所谓的假面攻击,就是通过使用相同的bundle ID,替换手机上已有从app store上下载安装的APP应用程序,替换后的APP可以获取该应用程序的的用户敏感数据,比如第三方邮件应用下邮件信息,也可以作为跳板,通过已知漏洞绕过应用层的sandbox保护,对系统层进行攻击。乌云上有详细的资料,后面给出链接。
多说一句
总之,只要加点小的限制,便会让大众随意刷榜的举动变的十分困难,刷榜的成本大大提高,不再具有普及性和传播性。
废话这么多,最后来句吐槽,难得github有个这么多star的项目,删了好心痛。。希望大家为本文点个赞。
阅读更多
想了解Masque Attack的下面给了三个链接:
假面攻击:你所有的iOS应用都在我们的手掌心
假面攻击(Masque Attack)详细分析与利用
三种新的针对IOS的假面攻击方法(Masque Attacks)—— 乌云知识库