首先給各位無(wú)良媒體記者跪了。七夕那天剛從公司拿到樣本的時(shí)候還以為是主管隨便到網(wǎng)上扒了個(gè)木馬demo給我練手,第二天看新聞才知道這小玩具已經(jīng)搞得滿城風(fēng)雨,媒體竟然稱它為“超級(jí)手機(jī)病毒”(-_-#)不得不感嘆混安全圈想裝逼簡(jiǎn)直太容易了。在此強(qiáng)烈譴責(zé)這種夸張報(bào)道,不僅向公眾傳遞錯(cuò)誤信息,也會(huì)影響孩子的價(jià)值觀。短短今天說(shuō)這個(gè)apk沒(méi)有任何研究?jī)r(jià)值,雖然技術(shù)是非常拙劣,但是其利用短信不會(huì)審核惡意鏈接的性質(zhì)傳播的方式倒是令人眼前一亮。
下面就來(lái)瞧瞧這個(gè)“XX神器”的真面目
從惡意鏈接上下載到“XXshenqi.apk”,考慮到是惡意應(yīng)用,先不急著安裝,反編譯一下看看這到底是個(gè)什么玩意。
直接拖進(jìn)APKIDE,查看AndroidManifest.xml:
乍一看,似乎除了聲明了發(fā)送短信和讀取聯(lián)系人的權(quán)限比較可疑,沒(méi)其他什么特點(diǎn)。組件部分也只有Activity,沒(méi)有Service,沒(méi)有BroadcastReceiver,并不具備木馬特征。觀察到主Activity是WelcomeActivity,那就先進(jìn)這個(gè)Activity看看在搞什么名堂。
這個(gè)木馬并沒(méi)有做代碼混淆,直接反編譯WelcomeActivity就能看到Java源代碼,首先看到的東西很令人驚訝:
不需要仔細(xì)看就知道是在群發(fā)短信,但是真正讓人驚訝的是這段代碼里居然藏了一個(gè)手機(jī)號(hào)(っ °Д °;)っ把自己的ID藏在病毒里的事情中已經(jīng)見(jiàn)怪不怪了,這種赤裸裸暴露自己手機(jī)號(hào)的還是第一次見(jiàn)(;?_?)別急,下面還有更臥槽的。
這一句話就是木馬傳播的核心,獲取通訊錄并向聯(lián)系人發(fā)送包含該木馬下載鏈接的短信。通常在QQ或者郵件里發(fā)送惡意鏈接的話都會(huì)被檢查,而現(xiàn)在的短信卻不具備檢查內(nèi)容的安全機(jī)制,這是該木馬最大的亮點(diǎn)。
WelcomeActivity開(kāi)啟群發(fā)短信的進(jìn)程后,繼續(xù)啟動(dòng)MainActivity,在MainActivity里找到三個(gè)if語(yǔ)句:
不難看出,這就是登陸按鈕的事件處理,三個(gè)if語(yǔ)句以各種理由拒絕用戶登陸,這樣做的原因就只有一個(gè),這個(gè)所謂的登錄窗口是假的,這個(gè)“XX神器”根本沒(méi)有任何功能,當(dāng)然沒(méi)辦法讓人登陸了。
那MainActivty的主要目的是干什么呢?找到retrieveApkFromAssets方法:
可以看到,該方法從assets文件夾里釋放了一個(gè)文件。那就趕緊到assets文件夾下找到這個(gè)文件吧ヽ(`Д′)?
居然聲稱自己的包名前綴是com.android (;?_?)
反編譯這個(gè)apk,打開(kāi)AndroidManifest.xml,看看到底在搞什么名堂:
看到這些基本上什么都懂了,“XXshenqi.apk”其實(shí)是個(gè)外殼,其真正目的是釋放隱藏在assets文件夾下的com.android.Trogoogle.apk,這才是木馬本體。
查看smali目錄,發(fā)現(xiàn)有如下幾個(gè)包:
簡(jiǎn)略看了看源碼,其他幾個(gè)包跟com包雜亂無(wú)章的代碼風(fēng)格不一樣,應(yīng)該是作者找的開(kāi)源包,只有com包才是木馬功能真正的實(shí)現(xiàn)部分,所以只需要把精力放在這個(gè)包上就可以了。
查看com包的源碼,首先注意到的是BroadcastAutoBoot,這是個(gè)接收開(kāi)機(jī)事件的BroadcastReceiver:
可以看到收到開(kāi)機(jī)事件后,啟動(dòng)了ListenMessageService,這是木馬常用的開(kāi)機(jī)自啟方式。
跟進(jìn)ListenMessageService看看,注意到以下兩個(gè)方法:
private String ReadAllMessage(Context paramContext):
private void ReadCONTACTS(Context paramContext, String paramString)
在ReadAllMessage中找到下面這一行:
在ReadCONTACTS中找到下面一行:
不難判斷出ReadAllMessage的目的是讀取所有短信,ReadCONTACTS則是讀取通話記錄。
繼續(xù)往下看,跟蹤onStart(),看看服務(wù)啟動(dòng)后做了哪些事情,注意下面這一行是關(guān)鍵:
ListenMessageService.this.getContentResolver().registerContentObserver(Uri.parse("content://sms"), true, new ListenMessageService.SmsObserver(ListenMessageService.this, new ListenMessageService.SmsHandler(ListenMessageService.this, ListenMessageService.this)));
ListenMessageService啟動(dòng)后注冊(cè)了一個(gè)ContentObserver監(jiān)視短信數(shù)據(jù)庫(kù),處理Handler為L(zhǎng)istenMessageService.SmsHandler,繼續(xù)跟進(jìn)實(shí)現(xiàn)處理Uri改變的onChange()方法,發(fā)現(xiàn)下面關(guān)鍵行:
木馬通過(guò)監(jiān)視短信收件箱,當(dāng)手機(jī)收到短信時(shí)將其截獲,并且發(fā)送到181****7397這個(gè)號(hào)碼。
繼續(xù)看:
木馬特別留意了186****9904這個(gè)號(hào)碼的短信,將其視為命令消息,繼續(xù)往下找到處理邏輯:
該短信共有5個(gè)操作命令:
readmessage:發(fā)送郵件命令,啟動(dòng)MySendEmailService,將收件箱和發(fā)件箱的短信以郵件形式發(fā)送
sendmessage:發(fā)送短信命令,能控制該手機(jī)發(fā)送任意短信到任意號(hào)碼
test:測(cè)試命令,將“【數(shù)據(jù)庫(kù)截獲】TEST數(shù)據(jù)截獲(廣播失效)”以短信發(fā)送至186****9904
makemessage:偽造任意地址、任意內(nèi)容的短信
??sendlink:讀取聯(lián)系人信息,以郵件方式發(fā)送
在此明晰了該木馬的大體架構(gòu),該木馬利用指定號(hào)碼發(fā)送短信,控制肉雞將隱私信息以郵件形式發(fā)送到自己的郵箱。
一個(gè)有趣的細(xì)節(jié)是,木馬作者將自己的QQ郵箱和密碼全部暴露在了代碼里(;?_?),拿到密碼后,興沖沖地去登陸這個(gè)郵箱,卻發(fā)現(xiàn)密碼已經(jīng)被改了,估計(jì)是被前輩們搶先了吧。
有關(guān)這個(gè)木馬的關(guān)鍵點(diǎn)就講到這兒,有興趣的朋友可以自己找樣本分析,代碼沒(méi)做混淆,肉眼就能看懂。雖然木馬使用的技術(shù)很小兒科,但是能其利用短信廣泛傳播的特點(diǎn)令人深思,余弦前輩說(shuō):很多時(shí)候,工程化能力遠(yuǎn)比單點(diǎn)技術(shù)研究重要多了。