Android應(yīng)用安全隱患現(xiàn)狀--資源文件加密/安全防護(hù)進(jìn)化史
前言
? ??有安全數(shù)據(jù)顯示,2014全年,Android用戶感染惡意程序3.19億人次,平均每天惡意程序感染量達(dá)到了87.5萬人次。同時,Android應(yīng)用被破解和盜版等事件也層出不窮。很明顯,Android平臺已經(jīng)成為惡意程序和破解者攻擊的眾矢之的,于是越來越多的Android開發(fā)者開始意識到應(yīng)用安全的重要性。
一、什么是“打包黨”
? ??他們專門對最熱門或新秀APP下手,先將其破解,然后再以植入木馬、插入廣告、篡改支付鏈接等形式封裝成新的APP,這個過程也叫做二次打包。更有開發(fā)者爆料,專業(yè)“打包黨”的月收入超過百萬,這簡直是對正版開發(fā)者最赤裸的攻擊和挑釁。
? ??尼瑪!一寸代碼一寸血,一寸光陰一寸金,全白費(fèi)了!
二、“打包黨”一般都做些什么
植入木馬,惡意扣費(fèi)
? ??“打包黨”謀取暴利的形式多樣,如在APP中植入木馬程序,用戶下載后,通過惡意扣費(fèi)、竊取用戶賬號和密碼等方式來獲取利益。為了蒙蔽用戶和節(jié)約成本,二次打包的APP通常和正版基本沒有差異,用戶在毫不知情的情況下使用后,一旦遭遇經(jīng)濟(jì)損失,最終開發(fā)者就要為此背黑鍋,還會使正版APP的品牌形象受損。
植入廣告,賺取廣告費(fèi)
? ??當(dāng)一個團(tuán)隊辛辛苦苦開發(fā)的APP,有了幾十萬、上百萬的用戶時,可能已經(jīng)成為了“打包黨”捕獵的對象。他們會在二次打包的過程中以植入或替換廣告的形式來賺取廣告收入,廣告有按展示次數(shù)、點擊次數(shù)、安裝激活量等不同的計費(fèi)形式。以展示次數(shù)為例,為了謀取更多利益,二次打包的APP會頻繁的對用戶進(jìn)行廣告提醒,給用戶造成騷擾,體驗感極差,但“打包黨”并不care,他們只關(guān)心怎樣盡可能多的賺到錢。
? ??可以想象,一邊是團(tuán)隊拼命的開發(fā)和推廣,另一邊則坐收漁翁之利,不勞而獲。APP越火爆,給“打包黨”帶來的利益就越多,完全淪為了“打包黨”賺錢的工具。
直接截取開發(fā)者的財路
? ??除了游戲和軟件類APP,隨著移動支付類應(yīng)用的火熱,“打包黨”還瞄準(zhǔn)了支付類APP?!按虬h”破解正版APP后,再修改App的付費(fèi)鏈接參數(shù),用戶支付的費(fèi)用直接進(jìn)入“打包黨”的口袋,完全切斷了開發(fā)者的財路。
? ??辛辛苦苦一整年,轉(zhuǎn)眼回到解放前!
三、安卓apk的文件結(jié)構(gòu)
? ??AndroidManifest.xml:Android主配置文件,編譯過程中由文本格式轉(zhuǎn)化為二進(jìn)制AXML文件格式。
? ??Classes.dex:java代碼編譯后產(chǎn)生的一種類似字節(jié)碼的文件。
? ??res:資源文件,其中的.xml文件在編譯過程中由文本格式轉(zhuǎn)化為二進(jìn)制AXML文件格式。
? ??META-INF:簽名文件。
? ??lib: native代碼編譯后的so。
? ??其他文件夾:由開發(fā)者自己添加的文件
? ??Android apk的核心邏輯主要存在于classes.dex中,通常破解者在進(jìn)行破解和二次打包時,會對classes.dex和AndroidManifest.xml文件進(jìn)行操作,所以對這兩個文件進(jìn)行保護(hù)尤為重要。
四、apk二次打包的四個步驟
? ??1.反編譯
? ??反編譯java:classes.dex反編譯成中間文件(smali、jar)。
? ??反編譯布局文件:Axml文件反編譯成xml文件。
? ??2.修改
? ??修改smali文件。
? ??修改xml文件。
? ??3.重新編譯
? ??修改后的smali編譯成classes.dex。
? ??修改后的xml編譯成Axml。
? ??4.重簽名
? ??一款山寨版APP由此誕生!
五、Android APP 防破解進(jìn)化史 原始社會時期——代碼混淆
? ??最早的應(yīng)用保護(hù)當(dāng)屬代碼混淆,谷歌官方發(fā)布的sdk中就包含ProGuard這種混淆工具。混淆工具會把你用java語言編寫的代碼的類名、變量名混淆為自己定義的格式,這樣可以增加破解者在破解時閱讀難度。但代碼混淆只是簡單的改變類名或者變量的名,只要能找dex,反編譯為smali或者java,花些時間還是可以輕松破解的。如果說不用混淆工具我們破解一個apk需要2兩天,那么用了這個工具,破解者可能需要4天,只是時間成本增加了。
奴隸社會時期——自我校驗
? ??經(jīng)過漫長的混淆時期,開發(fā)者發(fā)現(xiàn)他們的應(yīng)用還是照常被破解。于是新的保護(hù)方式又出現(xiàn)了——自我校驗。
簡單說,自我校驗就是在程序中加一些對自己應(yīng)用的完整性校驗,可以借助簽名、或計算自己應(yīng)用dex的md5值等等來完成。有些開發(fā)者直接把校驗功能加入到dex中,有些則是通過http協(xié)議請求相關(guān)服務(wù)來得到校驗。有了這種校驗,應(yīng)用在被二次打包的時候會無法運(yùn)行。
? ??那這種方法的弊端是什么?舉一個有意思的例子。在懸崖的拐彎處都會有一個路標(biāo),用來正確指示方向。但如果有人故意搞破壞,把路標(biāo)指示方向弄反,那開車的人被誤導(dǎo)后,順著錯誤的方向行駛,就會發(fā)生不幸的悲劇。
? ??這個例子的意思是,計算機(jī)在執(zhí)行指令的時候也是按照預(yù)先定義好的邏輯(開發(fā)者寫的)去執(zhí)行,然而如果破解者對開發(fā)者校驗的地方近進(jìn)行了修改,那么計算機(jī)也會按照新的邏輯執(zhí)行,這種保護(hù)措施風(fēng)險很大,所以也就逐漸沒落了。
封建社會時期——dex文件變形
? ??經(jīng)歷了兩個時代,開發(fā)者也逐漸提高了保護(hù)技能。于是很多做java出身的開發(fā)者,在經(jīng)過無數(shù)日夜的努力下?lián)u身一變成為了c、c++專家。越來越多的邏輯被寫入到c層,并且所有的校驗也被移到c層,混淆也同樣存在。同時,開發(fā)者開始對dex文件AndroidManifest文件做變形處理,這樣做的好處是既能保證應(yīng)用能正常運(yùn)行,也能使一些反編譯工具如apktool在反編譯時奔潰。但對dex文件和manifest文件的變形同樣有它的弱點?;臼烂嫔系膁ex變形都可以通過baksmali來得到smali,這樣破解者就可繼續(xù)分析。而manifset文件格式官方有明確的規(guī)范,破解者按照規(guī)范去解析,遇到不正確字節(jié)可以推敲,最終還是可以將其還原。
資本主義社會時期
? ??這是一個移動互聯(lián)網(wǎng)高速發(fā)展的時期,但盜版和二次打包等問題也日益凸顯,在這個開放的時期,為了滿足開發(fā)者保護(hù)應(yīng)用的迫切需要,相繼出現(xiàn)了一些基于Android APP加固的第三方產(chǎn)品,通常他們的基本做法有:
? ??1.Dex保護(hù)
? ??(1)隱藏dex文件
? ??既然dex文件中包含了核心邏輯,那么把dex隱藏,再通過另外的方式加載起來,是不是就能達(dá)到保護(hù)dex的目的了呢?于是這成為一些第三方加固產(chǎn)品保護(hù)應(yīng)用的方式。他們通過加密甚至壓縮(早期是不存在壓縮的,只是單純的加密)方式把dex轉(zhuǎn)換為另外一個文件。而被加固后的apk里面的dex則是那些第三方加固產(chǎn)品用來啟動和加載隱藏dex的入口,也就是殼。
? ??(2)對dex文件進(jìn)行變形
? ??這里所說的變形,不同于封建社會時期提到的變形。這種辦法不隱藏dex,而是讓dex保留在外面,但是當(dāng)破解者去分析這個dex的時候,會發(fā)現(xiàn)dex里面的內(nèi)容是不完整的。
? ??(3)對dex結(jié)構(gòu)進(jìn)行變形
? ??一些第三方加固產(chǎn)品開始嘗試這種方式,他們的保護(hù)方案中可能抽取了DexCode中的部分,然后對字節(jié)碼指令添加nop,或者連ClassDataItem和DexCode一同抽取,或者對上面提到的三個部分都做處理。抽取完之后,還要做修正、修復(fù)等工作,總之很煩鎖。因為dex運(yùn)行時有很多關(guān)于dex的校驗,即使校驗通過還有一些偏移問題。
? ??Dex都被抽取修改后為什么還能運(yùn)行呢?那是因為在運(yùn)行之前或者運(yùn)行之中對這個內(nèi)存中的dex做修正。修正工作也很復(fù)雜,一般選擇在運(yùn)行之前做修正,這樣可以減少很大的工作量,甚至可能還需要借助hook來幫忙。
? ??2.So保護(hù)
? ??(1)修改Elf頭、節(jié)表
? ??我們知道so其實是一個ELF文件,ELF文件有著自己的格式。有些第三方加固保護(hù)是對so文件進(jìn)行保護(hù),他們的做法是稍微修改一下ELF頭或者節(jié)表信息,因為這并不會影響程序的正常運(yùn)行。圖3和圖4是對ELF文件頭中的節(jié)頭表信息做了修改后,再用010 Editor打開,顯示的異常界面:
? ??接著我們用ida打開該ELF文件,發(fā)現(xiàn)該文件根本無法打開(一直卡在那里),如圖5和圖6所示:
? ??其次,還有修改程序頭表這種保護(hù)方式,如圖7 所示,對PT_NOTE段做了一些修改。在該段的屬性值中填充了一些無效的數(shù)字,導(dǎo)致逆向工具無法正常解析。由于系統(tǒng)并不會對PT_NOTE段進(jìn)行分析,防御逆向工具的同時保證了該文件能被系統(tǒng)正常加載。
圖7
? ??(2)選擇開源加殼工具
? ??最常用的當(dāng)屬UPX殼,因為它支持arm架構(gòu)的ELF加固。在加殼之后再對原文件做一些處理,這樣對破解者的分析工作又增加了一些難度。
? ??(3)進(jìn)程防調(diào)試、或增加調(diào)試難度
? ??有時候靜態(tài)分析是非常局限的,這個時候動態(tài)分析的好處就體現(xiàn)出來了,然而動態(tài)分析的核心就是調(diào)試,而調(diào)試一個進(jìn)程首先要ptrace這個進(jìn)程,如果能有效的防止進(jìn)程被ptrace,就能有效的防止動態(tài)調(diào)試。當(dāng)然還有其他反調(diào)試技術(shù),或者增加調(diào)試難度等等。
社會主義時期
? ??這個時期,技術(shù)的發(fā)展與普及讓人人都是開發(fā)者成為可能。而破解者的破解技術(shù)和手段也在隨之變化。單一的應(yīng)用保護(hù)措施已經(jīng)無法有效的應(yīng)對破解者的攻擊,所以還需要從多重維度和深度對應(yīng)用進(jìn)行加固保護(hù)。
? ??在上面的資本主義時期提到的幾種保護(hù)措施中,遺留了很多問題,比如:
? ??1.隱藏dex遺留的問題
? ??首先dex是被完整隱藏起來的,一旦破解者得到了dex,就等于破解完成了一半。如果破解了加殼原理,就可以輕易做出脫殼機(jī)。另外就是實現(xiàn)自定義rom,這種方式可謂最為簡單,只需要在相關(guān)的點加一些代碼,然后編譯一個自己的rom,這樣在虛擬機(jī)中就可以順利的脫殼了。還有就是利用Inject原理將目標(biāo)進(jìn)程注入,代碼進(jìn)行hook系統(tǒng)函數(shù)來達(dá)到脫殼的目的。
? ??2.Dex結(jié)構(gòu)變形帶來的弊端
? ??隨著安卓5.0的發(fā)布,Art步入我們的視野。Art可以直接將dex編譯為本地指令運(yùn)行。
? ??可是它編譯時需要完整的dex,這怎么辦?或許有些第三方加固產(chǎn)品選擇了根本不編譯,當(dāng)然開發(fā)者和用戶不知道,因為它表現(xiàn)出來的是程序可以正確運(yùn)行,但是系統(tǒng)在Art模式下運(yùn)行的更快這種優(yōu)勢就永遠(yuǎn)得不到體現(xiàn)了。
? ??所以Dex結(jié)構(gòu)變形遺留的問題很明顯,即兼容性和Art模式下的編譯問題。
? ??3.ELF簡單修改遺留問題
? ??對應(yīng)修改ELF頭和節(jié)頭表信息的技巧很容易被識破和修復(fù),所以只能防住初級破解者。
? ??4.UPX方面的劣勢
? ??雖然upx是最為so加殼的首選,但是upx代碼邏輯復(fù)雜,很難達(dá)到定制,特別是讓它同時支持多種架構(gòu)。