這里統(tǒng)一回復(fù)下燃观,昨天寫了篇關(guān)于微信運動刷榜的文章,考慮到微信運動是一個傳播正能量壳繁,引領(lǐng)健康,宣起了全民運動熱潮的公益應(yīng)用荔棉,微信運動方面也做了溝通闹炉,刷榜這種行為不益于微信運動的健康生態(tài),所以刪除江耀。
作者想說的是剩胁,現(xiàn)在對自己的健康作弊,最后傷害的還是自己祥国,運動不在于多少,在于問心無愧晾腔,每天多走一步舌稀,用真實的數(shù)據(jù)說話。
記步問題
關(guān)于如何統(tǒng)計每天的步數(shù)灼擂,自己統(tǒng)計壁查,需要長時間后臺刷新,不太可行剔应。所以微信運動采取的是讀取health里的數(shù)據(jù)睡腿。下面是我寫的統(tǒng)計當(dāng)天步數(shù)的代碼语御,原理都是一樣的:
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里面隨意寫入數(shù)據(jù)应闯,而且是在不越獄的前提下,目前都是基于這種方法刷榜的挂捻。
如何防范
難道我們就這樣放任不管嗎碉纺,那些每天認(rèn)認(rèn)真真運動的人反而排在最后,這對微信運動的健康生態(tài)十分不益刻撒。
那我們該如何防范呢骨田,我是從HKQuantitySample
入手的,對于每一個HKQuantitySample
類的result声怔,都有一個source
屬性态贤,對應(yīng)的是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
}
這樣說醋火,我們可以校驗這兩個屬性值來篩選數(shù)據(jù)咯悠汽,name
指的是數(shù)據(jù)來源的名字,如果是手機自己添加的則是本機名胎撇,通過第三方應(yīng)用添加的則對應(yīng)其應(yīng)用名介粘,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))
})
這樣就完美過濾其他數(shù)據(jù)來源晚树,真實還原h(huán)ealth數(shù)據(jù)姻采,不知道以后微信運動會不會采取這種方式。
然而這種方式存在固然的缺陷爵憎,一些正規(guī)的第三方運動應(yīng)用添加的數(shù)據(jù)也會被過濾掉慨亲,難道以后要加白名單機制?想出現(xiàn)在微信運動里的運動應(yīng)用(小米運動之類的)需要向微信審核宝鼓?刑棵?
反過來想想
對于上面這種過濾,是否存在繞過呢愚铡?
對于驗證數(shù)據(jù)來源名字是否是本機蛉签,這個我們可以將應(yīng)用名改成本機名,本地操作沥寥,秒秒鐘的事情碍舍,不成問題。然而對于那種分發(fā)上線的應(yīng)用邑雅,這個就比較困難了片橡,我不知道有什么方法或者不存在方法。
對于
bundle Identifier
的偽造與修改淮野,這個也是本地操作捧书,假面攻擊就是與之相關(guān)吹泡,因為該漏洞(iOS 8.4已修復(fù)部分),health應(yīng)用的bundle Identifier后面有了一串隨機數(shù)经瓷,com.apple.health.EBE76334-789F-400D-9214-0581002D49CE
爆哑,我們獲取它然后將自己的應(yīng)用改成它,然后企業(yè)簽名了嚎,再插入數(shù)據(jù)泪漂。
這里說說題外話,所謂的假面攻擊歪泳,就是通過使用相同的bundle ID萝勤,替換手機上已有從app store上下載安裝的APP應(yīng)用程序,替換后的APP可以獲取該應(yīng)用程序的的用戶敏感數(shù)據(jù)呐伞,比如第三方郵件應(yīng)用下郵件信息敌卓,也可以作為跳板,通過已知漏洞繞過應(yīng)用層的sandbox保護伶氢,對系統(tǒng)層進行攻擊趟径。烏云上有詳細(xì)的資料,后面給出鏈接癣防。
多說一句
總之蜗巧,只要加點小的限制,便會讓大眾隨意刷榜的舉動變的十分困難蕾盯,刷榜的成本大大提高幕屹,不再具有普及性和傳播性。
廢話這么多级遭,最后來句吐槽望拖,難得github有個這么多star的項目,刪了好心痛挫鸽。说敏。希望大家為本文點個贊。
閱讀更多
想了解Masque Attack的下面給了三個鏈接:
假面攻擊:你所有的iOS應(yīng)用都在我們的手掌心
假面攻擊(Masque Attack)詳細(xì)分析與利用
三種新的針對IOS的假面攻擊方法(Masque Attacks)—— 烏云知識庫