APP檢測GSM偽基站方案探索
GSM偽基站如果用于釣魚,危害就會很大。所以我就有一個想法,希望在APP層面檢測偽基站。因為偽基站隱蔽且容易流動,如果不在手機端檢測偽基站就不能及時發(fā)現(xiàn)異常。
雖然APP與偽基站對抗不在一個層級,但一定可以在APP層找到破綻——畢竟,偽基站要做到100%模擬正常基站難度也是很大的。比如通過OpenBTS、GNURadio和USRP實現(xiàn)的偽基站,默認都有好多獨有特性。


這就有點類似在應用層檢測系統(tǒng)的rootkit,雖然困難,但也并非完全不可能。我記得有一個簡易的檢測辦法,本地看系統(tǒng)開放了哪些端口,然后遠程掃描開放端口,兩個數(shù)據(jù)不一致,那就是有rootkit了。
可見,100%的虛擬現(xiàn)實是非常困難的。那么回到這個場景,偽基站的破綻在哪里?
嘗試
第一步很容易想到從OS層面能拿到的基站信息入手,看看獲得的信息能否有效甄別假基站。
Android SDK里面提供了類android.telephony.gsm.GsmCellLocation來獲取基站信息,可以得到Cid、Lac、Psc、hashCode,不過這些信息都很容易隨意偽造,看來得換個思路。
接下來我們又想到,在偽基站里電話和短信是不通的。雖然偽基站可以實現(xiàn)劫持,但是我目前見過的網(wǎng)上公開案例來看,偽基站都沒有做這個事。撥打電話這個操作太重,我們就在APP層發(fā)短信。如果網(wǎng)絡信息變化后,短信不能正常發(fā)出就說明可能存在偽基站。
發(fā)短信會涉及到費用,感覺不是很靠譜。不過我們想到給運營商號碼發(fā)是免費的,比如移動就給10086,聯(lián)通就給10001,電信的2G不是GSM,就先不管了。
于是,我們設想的方法是一旦發(fā)現(xiàn)基站信息發(fā)生變化,APP就發(fā)送一條短信給運營商,運營商收到后會答復,我們就看一定時間內(nèi)是否有固定的回復內(nèi)容,如無就認為當前接入的是偽基站。
不過后來考慮到收發(fā)短信權(quán)限太敏感,同時Android4.4及以后版本對APP的短信權(quán)限做了更嚴格地控制,所以這個方案我們也放棄了。
最后我們聚焦到網(wǎng)絡上。APP一旦發(fā)現(xiàn)基站信息發(fā)生變化,就調(diào)用GPRS獲取IP,如果得不到IP,就認為是偽基站——當然偽基站也可以搞個DHCP分配IP,如果發(fā)生對抗,我們還可以繼續(xù)從IP的范圍、網(wǎng)關(guān)IP等信息再來深入對抗。
demo演示
老規(guī)矩,在Android上實現(xiàn)了一個demo,以下是測試效果圖。后面這個demo會放到騰訊安全應急響應中心官網(wǎng)“實驗室”欄目,歡迎大家關(guān)注。

一些想法
這個方法還沒有考慮周全。比如漫游到境外的情況;還有,目前見到的偽基站都是發(fā)了短信后迅速將用戶踢出網(wǎng)絡,用戶則會重新回到正常網(wǎng)絡,整個過程只有短短幾分鐘,所以實際檢測效果還待測試。
如果有安裝量大的手機終端軟件,倒可以把手機附近的基站信息都上報到云端,如果偽基站出現(xiàn),或許就可以及時發(fā)現(xiàn)。
后記
仍然感謝其他小伙伴popey、HuangJacky和riusksk的工作。
最后,一個有意思的想法是,如果這個“現(xiàn)實”世界是在一個“虛擬機”里運行的,你能從“應用層”找到破綻嗎?