#雲棲大會# 移動安全專場——APP加固新方向(演講速記)



主持人導語:

近些年來,移動APP數量呈現爆炸式的增長,黑產也從原來的PC端轉移到了移動端,伴隨而來的逆向攻擊手段也越來越高明。在解決加固產品容易被脫殼的方案中,代碼混淆技術是對抗逆向攻擊最有效的方式之一。但目前的移動端加固技術真能抵禦黑客的攻擊嗎?

本報告將分享阿里巴巴集團安全部應用加固能力養成記,重點介紹Android加固對於端上的業務風險控制是如何做到自動化部署和分析,更快捷的感知安全風險,以便快速做出響應,減少不必要的業務損失。

有請阿里巴巴安全專家亂武。

 



嘉賓演講正文:

    非常感謝各位來賓來到這裏,歡迎來到雲棲大會移動安全論壇。

    今天講的大的標題叫【APP加固新方向】,副標題主要講阿里巴巴對Android加固的基礎介紹,以及在開發這個產品過程中遇到的一些問題和一些複雜場景的適配過程。由於大會給我的時間是25分鐘到30分鐘,整個安卓加固方面涉及的技術點還蠻多的,爲了讓這次的分享有一個比較聚焦的點,所以這次的分享主要是講Android java代碼方面的保護,也就是說編譯成Android安裝文件之後,Dex文件方面的一些基礎保護點。

    我這次分享的主要有三個部分,第一部分主要是要介紹一下Android java代碼保護的技術。第二部分介紹一下應用加固在複雜業務場景下的挑戰以及遇到的一些問題。第三部分說一下未來對於Android java代碼保護的一些思路,跟大家分享一下,也許大家將來會碰到,或者有相應的一些啓發。

    第一部分主要講Android java代碼的技術保護,剛纔主持人做了一個小的問卷調查,這裏不少同學不是開發,我大概介紹一下這個上下文。

    本身安卓手機大家不陌生,蘋果和安卓,目前是業內主流的兩大智能操作系統。安卓本身的開發環境是用java語言開發的,它有一個特點。由於java語言生成的文件是在虛擬機裏面執行的,必然要保留大量的語義,虛擬機能夠認識可執行文件的時候保留了很多的語義。這就帶來一個問題,既然編譯生成這種Dex格式,保留了大量的語義,而這種格式谷歌對外完全公開的,惡意者通過反編譯達到看到原來Java代碼的這種目的。不管是阿里巴巴還是其他安全加固的友商,對安卓java代碼的一個保護,也就是安卓上面Dex文件的保護,從加固服務產生到現在一直是重點。

    我簡單介紹一下Android java代碼以及Dex代碼保護迭代介紹,業內主要總結了四代的保護方案。

    第一代加固本身這種方案剛出來的時候,大概是2013到2014年之間,本身這個加固方案對於安卓本身的可執行文件,也就是Dex文件的保護,相當於是在打包的時候,就是生成整個安卓安裝應用包的時候會對Dex進行加密。加密算法各種各樣,可以用AES,也可以用其它的。在運行的時候通過一個自定義的類加載器進行解密,真正在運行的時候是完整的原來應用開發者編譯出來的Dex文件。這種加固的特點一目瞭然,你拿到文件的時候,既不知道密鑰,也不知道加密算法,看不出來文件的整個邏輯,這個時候一定程度上能夠防住,通過一些開源的工具逆向分析這個Dex文件。

    缺點也很明顯,因爲它簡單,因爲運行時用一個自定義的類加載器在加載的時候解密,把這點攔掉,就把這個殼脫了。

    那通過一段時間的發展以後,又出現了第二代的保護方案,就是類級別的Dex保護。我前面介紹了其實Dex文件來說,它的格式是公開的,公開就意味着這裏面的某些類、某些函數保護的code在哪一個位置,其實所有人都能夠知道。所以第二代的保護方案,相當於把Dex裏面要保護的核心函數抽離出來生成另外一個文件,利用一個虛擬機類加載機制。本身虛擬機有一個特點,它必然會掉到這個類裏面的一個方法,我們已經在打包的時候,將這些核心函數保留在已知的位置,通過這個函數調用我們的修複函數,然後將所有的業務邏輯進行修復。這樣的一個方案,其實主要的原理還是利用虛擬機類加載機制的特點來達到一定保護的效果。當然這種保護有一個特點,我們如果簡單來說,即便是我把它抽離了,最後運行的指令是谷歌支持的Dex標準指令,這點大家要注意。

    第三代跟前面兩代完全不同,因爲谷歌的Dex指令是開源的,不管第一代第二代,內存中運行的都是谷歌的標準指令,所以從原理上一定有辦法將這個指令完全逆向出來,然後把它反編譯出來。但是第三代就有一個質的區別了。其實第一步和第二代是一樣的,也是在編譯打包的時候將Dex的核心函數抽離的,抽離後,翻譯成一種自己定義的指令,用自己的一種編譯指令進行翻譯,把這個指令變一個種,變成其他的指令,這個時候運行的時候通過自己的解釋器來解釋執行,是自己定義的相關指令,這是跟第二代有質的區別的。我在內存中運行的指令,在某些保護的函數裏面就一定不是谷歌的標準指令了,這點能夠很有效的防止內存直接拷貝等破解方案。

    第四代,也是行業目前公認的方案,就是java 2C的保護方案,這種更簡單直接,它的原理很清晰,我們如果作爲一個開發者,在開發java代碼的時候,不管是原來傳統的PC上的java虛擬機還是谷歌的虛擬機,java代碼一定是可以翻譯成用C代碼來表示的。比如說寫一個java代碼的函數,從原理來說其實只要不嫌麻煩,我一定能夠利用虛擬機漏出的接口寫成C代碼,這種保護方案直接從根源上解決這個問題。你認爲核心要保護的函數,我們直接在編譯打包的時候將這些函數翻譯成C語言的代碼,然後再用編譯器編譯成一個so的文件,也就是這個CPU支持的一個二進制code,這樣達到了比較好的保護。

   這基本上就是我介紹目前安卓移動端對於java代碼保護的四代技術。

    因爲第一代和第二代技術相對比較簡單,我介紹一下第三代和第四代技術整個的框架流程圖。

    自定義解釋器的Dex保護方法第一部分應用打包和普通的是沒有什麼區別的,最終生成的也是安卓系統能夠認識的一個可執行的文件。但是到了第二步和第三步的時候就有點區別了,第二步要經過一個加固的工具鏈,因爲也是一個安卓的可知性的文件,首先要找到一個Dex文件,抽取核心函數指令,然後埋點一些hook接口,接下來打包還回apk文件,簽名後應用發佈。藍色的部分表示是在運行時,黃色的部分是沒有安裝到用戶手上,藍色的部分應用已經發布了,然後在用戶的手機上執行的一個邏輯。因爲第二步埋點了hook接口,就進入一個自定義的一個解釋器,根據傳譯的二進制的code翻譯成原來Dex文件想保護的java那個code的邏輯,完成了第三代的保護效果。真正在解釋的時候解釋執行的就是這種變種的指令,然後達到正常執行業務邏輯的效果,這是第三代的一個自定義解釋器Dex保護方案的介紹。

    說一下第四代java2C保護方法的介紹,前兩步也跟第三代是一樣的,就是開發者自己編譯好的一個安卓可安裝程序。不同的是,直接簡單粗暴將需要保護的Dex核心函數直接翻譯成C代碼。比如一個編譯好的Dex文件,直接把這個函數編譯成C代碼,可以自定義一個編譯器翻譯成一個C代碼。C代碼還是很成熟的,可以用各種各樣的編譯器,包括谷歌以及第三方編譯器,這樣完全去除了裏面的核心指令,就變成看這個手機或者這個架構支持的Dex文件。這裏面運行的時候又有不同,因爲這個時候是需要把SO給打進APP裏面,因爲這些代碼其實已經編成SO,要加到apk裏面,所以核心函數一般加一個native標籤,調到本身的SO裏面,後面的執行順理成章了,就是本地指令的執行保護函數,能夠達到完全的正常執行的業務邏輯。

    第一部分大概介紹完了,包括目前比較流行的新的技術,就是第三代和第四代,但是其實我這邊要說一下第三代和第四代的一些缺點。

    從剛纔的介紹看起來比較美好,但是到了第三代的自定義解釋器的時候,這個時候由於要hook系統的一些接口,普通的應用開發者要遇到很多碎片化的問題,對於加固要調用大量的系統私有api的安全服務來說,可能遇到的問題更顯突兀,所以基本上在第三代的自定義解釋器的保護方案,不是說不強,但可能遇到碎片化的東西比較多,到第四代其實反倒碎片化比較小,爲什麼大家比較推崇java2C的保護方案,是因爲把java代碼翻譯成C代碼再編譯成SO,是完全符合很多虛擬機的開發規範的,這樣的兼容性問題最小。當然這兩個場景也有一個問題,它編譯出來的函數可能會體積變大,可能執行效率變低,但是這些都是一些具體的細節,今天的時間有限,就不再詳細贅述了。

    第二部分介紹一下加固在複雜業務場景下的挑戰。

    安卓從幾年前大家也不是特別看好的一個智能操作系統到現在成爲全球第一大的智能操作系統來說,自身的操作系統是有一個不斷的迭代,包括今年最新發布的android O,我們能看到它的進步。在安卓上面開發各種業務其實現在已經變得很複雜了,就以我們阿里巴巴公司比較旗艦類型的應用,比如手機淘寶和支付寶的應用,應用開發的流程和開發使用的黑科技的各種技術,已經是不亞於傳統上面的一些PC上面一些比較複雜的客戶端開發的程度了,所以加固在服務於這些應用的時候,也面臨着一些複雜業務場景的挑戰,我做一些簡單的介紹,舉兩個例子。 

    Hotpatch應用場景,安卓應用如果是說在你的應用發佈以後,到了用戶的手機端上以後如果發現一些bug,按照傳統的方案有一種解決方式,用戶升級再更新一個版本、重新安裝一遍把這個問題解決了。但是在對於很多複雜的應用來說,比如說像手機淘寶或者天貓或者支付寶,它本身的一個安裝包就已經70多兆了,比如裏面有一個很小的bug,比如哪一個頁面顯示不對,讓用戶完全的升級一遍,重新下載包升級一下,用戶體驗不是很好,他們業務方開始研究一種技術,當我發現某一個地方某一段代碼有問題了,這個時候我就只修改這一部分代碼,而不需要用戶安裝整個發佈包。我們這個原始應用有三個類,分爲A/B/C,當我有問題的時候,比如我發現的問題是某一個代碼有bug了,假設B類有bug,我只需要把他弄成一個Dex文件,把這個下發下來,熱部署以後把原始APP裏面的Dex文件修改一下,讓它變成只有A和C這兩個類,然後再通過一些類加載器裏面尋找Dex的順序,達到首先執行我的熱部署後的這個文件,當需要調用B的時候再執行B這個類,達到修復這個原有程序業務邏輯bug的目的,或者我想更新達到更新的效果,當然這種方案目前在安卓上面運行的還是比較多的,包括阿里也有發佈熱補丁的。原來這種在蘋果上面也會應用,但整個來說蘋果不讓用了,谷歌想在明年P的版本可能會全面限制這種技術方案,但是目前來說發佈O的版本目前還沒有這個限制。但是這種方案其實在加固來說,從加固的原理來說有一點衝突,熱部署後的dex文件會出現一點問題,這是加固服務發展過程中發現的一個比較複雜場景的舉例。

    第二種場景大家更不陌生,由於業務發展越來越複雜,開發規模稍微大一點的應用,需要插件化的部署,比如手機淘寶集成了各種各樣的服務,這時候要多個團隊協作開發,這就無可避免要利用我們所謂的插件化的思想,然後分步開發。這時候傳統的加固面臨一個問題,最初我們主要是保護主Dex文件一些根目錄下的Dex文件,插件會埋到lib下面很深的地方,導致加固刺出現盲點,作爲一個通用化的一個加固方案很難做到將所有的Dex文件也保護,但是有些是比較核心的。剛纔我提的這兩個例子,不管是阿里巴巴還是很多友商,這個問題都得到很好的解決,具體的細節我就不贅述了。 

    最後一部分介紹一下業內認爲未來對於安卓java代碼一種保護手段的思路

    第四代java2C保護方案是用編譯器編譯成一個標準的SO文件,其實標準的SO文件開發者都很清楚,這種elf格式也是透明的,相當於本身這種格式也是完全有規範的,是透明的,也是可以逆向的。既然可以把DEX文件翻譯成c代碼,那麼也可以用支持vmp虛殼的編譯器在編譯成內置於vmp虛殼的保護的so。

    風險設備的控制,我們做安全來說從原理來說,如果不是特別計較成本的話,其實只要在端上運行的東西,特別谷歌開源運行的,其實原理上是能夠破解的,只不過你花費的時間長短和破解成本的高低,所以在手機淘寶和電商的超級應用,保護思路越來越從端上防護傾向於端和雲聯合的防護。在端上在打包的時候會埋入很多點,不管是安全adk還是本身加固工具鏈的方式,獲取一個端上唯一的標識,我們稱爲一個設備指紋。像下單這種行爲會加入這種設備指紋的請求,然後服務器通過這個指紋識別進行風險控制,比如我們認爲是惡意者操控的設備,可以加入黑名單,不會讓這個應用崩潰。比如你搶紅包搶不到,你買東西買不成功,給用戶一個反饋,這種其實保護效果是相當好的。



  

我的分享結束了,最後感謝大家的聆聽,謝謝。


——————————————

阿里聚安全-應用加固

通過對Android應用進行重新編譯、加殼保護、修改指令調用順序等手段來增強應用反破解能力。我們的加固功能注重加固強度與兼容性並重,避免一般加固功能盲目追求加固強度導致加固後完全不可用。

發佈了145 篇原創文章 · 獲贊 27 · 訪問量 26萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章