1. 程式人生 > >android黑科技系列——爆破一款應用的簽名驗證問題

android黑科技系列——爆破一款應用的簽名驗證問題

equal 沒有 term 通過 攻防 都在 都是 什麽 tac

一、前言

在之前的文章中說過Android中的安全和破解是相輔相成的,為了防止被破解,很多應用做了一些防護策略,但是防護策略也是分等級,一般簡單的策略就是混淆代碼和簽名校驗,而對於簽名校驗很多應用都是會做的,一般現在就兩種方式:

第一種:簽名校驗不通過直接退出程序,也就是你會發現回編譯二次打包運行失敗的現象

第二種:簽名校驗不通過不觸發程序指定邏輯,導致沒有錯誤信息,也進不了應用的現象

關於Android中應用防護策略的文章可以看這裏:Android中應用的攻防之戰 今天我們就來看一下簽名校驗的應用案例,在回編譯二次簽名之後運行進不去遊戲的問題,其實在之前已經分析過了一個簽名驗證的問題,那裏的問題是回編譯二次打包運行失敗的問題。不了解的同學可以去這裏看一下:Android中使用靜態方式破解apk應用;這種運行失敗的應用比較好解決,因為這種簽名校驗的一般都在應用的入口處,所以直接在入口處加一些日誌,通過打印日誌就可以看到,入口一般是Application的onCreate方法和attachBaseContext方法,而通過這個案例之後我們也學習到一個快速定位簽名校驗的方法的技巧:全局搜索signatures字符串,因為我們知道如果要做簽名驗證,必須調用系統的一個api方法:getPackageManager().getPackageInfo(getPackageName(), 64).signatures,所以在用Jadx工具反編譯apk之後,全局搜signatures字符串可以立馬定位到簽名校驗的方法。

二、案例分析

上面分析完了之前一個解決簽名校驗的案例,下面就用這個小遊戲作為簡單分析,這個遊戲在市場都可以下載到:

技術分享

本文研究的是V3.3版本的。我們下載遊戲之後,可以利用apktool進行反編譯,然後回編譯重簽名,安裝運行:

技術分享

遊戲可以運行成功,但是卡在這裏,進不了遊戲了,這時候我們就猜想他可能有簽名驗證邏輯,可能放在本地,也有可能放在服務端,我們利用上面說到的那個技巧:在Jadx中全局搜”signatures”字符串內容:

技術分享

這時候會發現有很多地方都在使用,其實可以推斷出,這個遊戲為了防止二次打包在很多地方都加了簽名驗證的邏輯,這樣對於破解也是增加一定的難度,因為這裏簽名校驗的地方太多了,所以沒法一個一個修改,所以咋們用另外一種方式高效率的解決問題:在運行遊戲的時候發現遊戲卡在進度條了,所以猜想和網絡請求有關,所以咋們就通過Fiddler抓包來分析他的請求信息:

技術分享

遊戲打開就這些請求,但是作為一個遊戲不可能就這點請求的,這個也是卡住的原因,我們可以這麽做,用一個正常的遊戲在抓包看看情況:

技術分享

這個是沒有二次打包簽名的請求信息,和上面二次打包簽名之後的請求相比較,多了很多請求,可以發現有一個get_user_info這個接口比較特殊,所以我們可以去Jadx全局搜這個請求接口:

技術分享

這裏看到定義了url的地方,然後在全局Find Usage的地方:

技術分享

點進去看方法調用:

技術分享

繼續查看這個方法的調用地方:

技術分享

這裏有四個地方調用這個方法,但是可以依次排除,最終定位到是com.wepie.snake.module.home.b.d.e()方法,那麽下面來看一下如何進行排除的,可以從下往上排除,看最下面一個方法:

技術分享

然後進入l.a方法中查看邏輯:

技術分享

這裏其實是個請求,請求接口是d.r的值:

技術分享

看到是這個接口信息,但是我們在用Fiddler抓包的時候並沒有看到這個請求:

技術分享

所以這個地方可以過濾了,其他三個地方的分析結果類似。所以通過這種方式定位到了方法調用的地方:

技術分享

我們在查找這個e方法調用的地方:

技術分享

在這裏被調用了,通過調用結果發現,有第一個判斷:

技術分享

這裏有一個字符串比較相等的邏輯,很有可能是比較簽名信息的,可以查看h.a這個方法:

技術分享

這裏貌似有一個字符串的構造算法,我們為了看到最終的字符串內容,可以新建一個簡單的Java項目,然後把這個方法打印一下看看結果:

技術分享

看到這個最終生成的字符串內容是:678a930b9829b54a44f92a840916f7d1,然後再看一下equals的o.a的方法:

技術分享

這個方法是獲取應用簽名信息的,然後用MD5計算結果。所以到這裏我們就知道校驗簽名邏輯是,獲取應用的簽名信息,然後MD5一下,和”678a930b9829b54a44f92a840916f7d1“字符串進行比較。那麽我們二次簽名之後,這個判斷肯定就是false了,所以後續的邏輯就不走了,沒有後面的請求,發現卡在開始界面了。

那麽問題找到了,改起來就比較簡單了,直接反編譯遊戲,然後找到這個 com.wepie.snake.helper.f.o.a()方法對應的smali代碼:

技術分享

把這個方法直接返回”678a930b9829b54a44f92a840916f7d1“字符串即可。有的同學說這個怎麽改?是手動編寫samli代碼嗎?肯定不是的,咋們可以先寫一個簡單的返回這個字符串的方法,然後反編譯得到這段smali代碼就可以了,可千萬別自己手動的去編寫,除非你有這個耐心和毅力,反正我沒有。替換完成之後,咋們就回編譯,二次簽名運行安裝遊戲,可惜的是還是卡住了,所以還得回去看代碼:

技術分享

咋們修改了一次簽名校驗方法,進入了第一層簽名判斷,繼續往下看代碼:

技術分享

這裏又有一個判斷,點進去查看邏輯:

技術分享

果然,這裏又有了一次簽名校驗方法,所以還得手動的修改,修改方法和上面類似,把這個p方法改一下即可:

技術分享

修改成功之後,再次回編譯重簽名安裝運行,可惜的是還是卡住了,進不了遊戲,這時候我們在次抓包看看:

技術分享

這次比之前多了一個config_v3_android請求,但是還是沒有get_user_info的請求!所以還得去看代碼邏輯,不過從請求結果來看,我們之前的兩次簽名校驗修改已經有效果了,繼續看下面的代碼:

技術分享

這裏可以看到,有一個設置進度條的邏輯,而且有一個tag=999的日誌,貌似是取配置信息的進度條,那麽我們可以查看這個日誌信息:

技術分享

看到了這個日誌信息之後,發現有開始取config到獲取成功config了,但是後面就沒有日誌了,所以這裏猜想應該是在本地解析這個配置信息的時候還有判斷,咋們全局搜一個字符串信息”getConfigAndroid“:

技術分享

第一條信息就是我們想要的,點擊進入:

技術分享

果然這裏還有一個判斷,進入查看:

技術分享

又是一次簽名校驗的邏輯,好吧,還得再一次改這個com.wepie.snake.helper.b.a.i()方法了:

技術分享

修改成功之後,再次回編譯二次簽名安裝運行即可,這次終於運行成功,進入遊戲界面了。

三、簽名校驗破解方案

好了,到這裏我們來總結一下關於如何解決應用二次簽名校驗的問題:

第一步:先在Jadx中打開應用之後,全局搜字符串內容:”signatures”,這個就可以定位到獲取應用簽名信息的地方了,然後可以依次跟蹤校驗的地方了。

第二步:在第一步搜索結果比較多的情況下,我們可以通過應用運行效果采用這兩種方式:

  • 第一種方式:如果應用運行失敗,那麽可能是在應用入口處作了簽名校驗邏輯,如果校驗失敗就退出程序。一般入口處是在Application的onCreate方法和attachBaseContext方法。
  • 第二種方式:如果應用可以運行,但是卡在某一個地方,我們可以采用抓包技術來分析應用運行到哪一步卡住了,因為現在的應用都會有請求的,如果是卡住了,那麽請求就會和原始包的請求不同,可以根據不同的請求結果來跟蹤代碼邏輯,就比如本文的案例。

上面就是本人總結的簽名校驗的大致解決步驟和方法,但是肯定還有其他場景,比如有的應用會把簽名放到native層,但是這些校驗邏輯都是可以做處理的,也有的應用把簽名信息放到服務端進行校驗,這個也是可以處理的。放在native層的話,最終也是通過java層做連接訪問的,只要到了java層,那麽就可以找到校驗方法的地方,放在服務端校驗,還是可以通過抓包查看請求來解決的。

四、簽名校驗破解後續

從上面看其實在給應用做防護的時候,簽名校驗這種方式不是百分百的安全,只能防止一些破解小白。其實本文的案例中可以發現,這個應用其實想通過多個地方的簽名校驗來做到全局校驗,本文中可以看到我們做了三次的簽名校驗方法代碼修改才成功的,而且後續版本也不排除他們還會繼續增加,以及在其他地方邏輯處也做了簽名校驗判斷。

從本文中也可以看到如果一個應用在很多地方都做了簽名校驗,那麽我們手動修改會顯得很麻煩,其實這裏有這個思路:獲取應用的簽名方法是固定的:getPackageManager().getPackageInfo(getPackageName(), 64).signatures,我們可以直接修改應用的Application信息,通過反射機制,把校驗對象的字符串內容設置到signatures中,說白了就是用反射來修改應用的簽名信息,這樣在應用中所有獲取簽名的地方都是我們設置的指定簽名值,也就是比對的那個常量字符串內容,所有的簽名校驗方法都是返回true了。這個思路本文不再嘗試了,感興趣的同學可以嘗試。就是一個反射調用即可。有的同學可能在想怎麽不用Xposed進行hook應用的簽名獲取方法那樣不就更簡單了。這裏一定要註意呀,我們為什麽要解決簽名校驗,就是因為我們想二次簽名打包,而Xposed進行hook的時候是不需要二次打包的,主要hook點找到,不用進行二次打包安裝就可以實現破解了。這兩種方式思路是不同的,要註意哈!

五、給應用安全防護的意見

通過本文案例,其實對於現在應用防護有這些建議:首先關於應用簽名校驗這塊邏輯,可以做的更安全點,就是在native層用反射調用系統獲取簽名的方法,然後直接在native層進行比較,如果發現簽名不正確,就退出程序,全部放在native層做,這樣安全系數會高點!

但是這種也不是最安全的,安全點也就是考慮加固方案了,現在加固平臺很多,選擇企業版加固,對於破解難度那是肯定會加大的。但是加固有一個弊端,就是崩潰率的問題,因為了解加固原理的同學都知道,現在加固平臺都會涉及到so邏輯,而Android因為機型和系統版本復雜,導致兼容性不好,會有一定的加固崩潰率的,而對於一些用戶量比較多的應用和遊戲,他們無法忍受這種崩潰率,那麽就放棄加固了。但是加固還是一個相對安全的策略!

嚴重聲明:本文的目的只有一個,通過一個案例來分析現在應用的簽名校驗邏輯,如何破解這種校驗方式,如果有人利用本文內容進行任何商業目的和非法牟利,帶來的任何法律責任將由操作者本人承擔,和本文作者沒有任何關系,所以還是由衷的希望大家秉著技術學習的目的閱讀此文,非常感謝!

六、總結

本文通過一個案例分析了應用簽名信息校驗的防護策略破解,最後也總結了現在這種簽名校驗防護策略的弊端和改進的地方,如何做到安全系數比較高的防護。但是也不是最安全的,因為沒有絕對的安全!安全和逆向是相互進步!共同促進社會進步和技術革新!

android黑科技系列——爆破一款應用的簽名驗證問題