1. 程式人生 > >android黑科技系列——分析某直播App的協議加密原理以及調用加密方法進行協議參數構造

android黑科技系列——分析某直播App的協議加密原理以及調用加密方法進行協議參數構造

輸出結果 防護 返回 不能 定義類 多個 類型 所在 文件中

一、前言

隨著直播技術火爆之後,各家都出了直播app,早期直播app的各種請求協議的參數信息都沒有做任何加密措施,但是慢慢的有人開始利用這個後門開始弄刷粉關註工具,可以讓一個新生的小花旦分分鐘變成網紅。所以介於這個問題,直播App開始對網絡請求參數做了加密措施。所以就是本文分析的重點。逆向領域不僅只有脫殼操作,一些加密解密操作也是很有研究的目的。

二、抓包查看加密協議

本文就看一款直播app的協議加密原理,以及如何獲取加密之後的信息,我們如何通過探針技術,去調用他的加密函數功能。首先這裏找突破點,毋庸置疑,直接抓包即可,我們進入主播頁面,點擊關註之後,看Fiddler中的抓包數據:

技術分享

我們會發現,請求參數中,有些重要信息,比如用戶的id,設備的imei值等。不過最重要也是我們關心的就是s_sg字段了,因為這個字段就是請求參數信息的一個簽名信息。也是服務端需要進行比對的信息。如果發現不對或者沒這個字段,那麽就認為這次請求操作是非法的。所以我們只要得到這個字段的正確值,才能模擬訪問此次操作的網絡請求。

三、分析加密流程

找到突破口了,就是這個字段s_sg,用Jadx打開app的dex文件,打開dex文件之後,全局搜索s_sg字符串:

技術分享

這裏看到只有一處出現了這個字段值,我們點進去查看:

技術分享

看到這個方法,很興奮,感覺就是加密協議的功能,而且字段都能對上,我們把這個加密方法直接拷貝出來,寫一個demo之後模擬加密之後的信息,悲傷的是發現數據是對不上的,而且看看這個方法所在的類:

技術分享

盡然是一個和網頁交互的類,說明應該不是這個地方進行請求加密了。這個突破口就斷了。

註意:這裏說的是dex文件,不是apk文件,因為Jadx打開apk文件會解析資源文件,如果一個app有很多資源文件,那麽Jadx打開就會卡死,所以很多同學問我為什麽Jadx打開apk文件就出現卡死狀態,主要是因為解析資源文件導致的。所以為了防止卡死,直接解壓出dex文件,然後打開就不會卡死了。

我們繼續上面的抓包信息,就是請求的url地址,再去Jadx全局搜索:

技術分享

找到了,點進去查看:

技術分享

然後全局搜索這個”USER_RELATION_FOLLOW”字符串:

技術分享

搜到結果,點進去進行查看:

技術分享

這裏看到了,用了註解方式來構造請求信息,而這裏的核心類就是InkeDefaultBuilder,全局搜索這個類:

技術分享

可惜沒搜到,因為這個app進行拆包操作,有多個dex文件:

技術分享

所以我們需要用Jadx繼續打開他的第二個dex文件進行搜索:技術分享

果然,在第二個dex中找到了這個類。

註意:

這裏需要註意,對於Jadx打開dex或者apk文件之後,跟蹤發現找不到一些搜索內容的時候,需要有如下猜想:

第一、是否包含多個dex文件,可以利用Jadx去打開其他dex文件進行搜索。

第二、是否存在動態加載插件功能,全局搜索DexClassLoader找到插件加載位置,獲取插件功能包,在用Jadx打開插件包進行搜索。

第三、是否存在so文件中,可以利用IDA打開so文件,Shift+F12展示so中所有的字符串信息視圖,然後進行搜索。

第四、是否信息來源於網絡請求返回,比如一些字符串信息展示,有可能是服務器返回的信息。

繼續分析,點進去查看這個類的定義:

技術分享

查看他的父類信息:

技術分享

看到有一個url加密的方法,比較好奇。我們查看這個方法:

技術分享

繼續查看這個方法:

技術分享

這裏發現有一個網絡請求,會發現一些信息,然後設置到一個地方。我們繼續看方法:

技術分享

看到d變量的定義類型,一般我們看到不可點擊的可能這個類不在這個dex文件中了,所以我們需要去另外一個dex文件進行查找,而本文案例就是來回這麽折騰查找信息操作的,去另外一個dex文件中進行搜索:

技術分享

查找到了,點進去查看:

技術分享

這裏又看到是一個a變量,看看他的定義:

技術分享

看到,這裏這個類又不可以點擊,說明這個類不在這個dex文件中,去另外一個dex文件中進行搜索:

技術分享

發現這個類的定義了,點進去進行查看:

技術分享

原來是一個native的工具類,內部有很多native方法,包括了設置信息的方法,加密解密url方法等。看看他加載的so是什麽:

技術分享

原來是這三個so文件,看到crypto和ssl,弄過加密的知道,這個是openssl加密的庫文件,這裏猜想他在native層用了這個加密算法了。先不管,我們用IDA打開這個so文件,因為我們知道libcrypto和libssl這兩個是庫文件,所以直接打開它自己的libsecret文件吧,然後Shift+F12查看他的字符串信息頁面,在之前不是想看看那個加密字段,這裏搜索看看結果:

技術分享

的確找到了,那個加密的字段了,我們點擊進入查看:

技術分享

然後點擊X鍵,查看調用地方,不過可惜的是,跳轉過去之後發現,那個匯編代碼不是一般的多。這裏先不去看了,回過頭來,看看那個加密url的函數:

技術分享

點擊進去,然後按F5查看對應的C代碼:

技術分享

這時候就要開始懷疑人生了,IDA卡死了。然後簡單看一下這個函數的匯編代碼,簡直蒙圈。太長了。如果靠靜態分析,我是沒這個耐心和能力了。動態調試?我覺得也夠嗆,搞不好還有反調試,各種跳轉。不知道調試到猴年馬月。

四、獲取加密內容

那麽到這裏,我大致分析這個直播app的請求協議有一個加密簽名的字段s_sg,這個值是在native層中進行加密操作的,采用openssl進行加密,但是加密函數非常長,分析難度加大。但是不能就這樣放棄了。我們想要這個加密結果,用於我們自己構造參數之後獲取正確的簽名信息值。那麽就需要轉化思維了。我們或許只要結果,加密過程對我們來說並不那麽重要。所以這裏的一個思路:自己寫一個程序調用它的so文件中的這個加密函數。

我們做過NDK開發的都知道,默認情況native方法在so中的JNI_OnLoad函數自動註冊,但是native中的函數必須按照這種格式:Java_類名_方法名,類似這樣:

技術分享

那麽我們就可以在自己的程序中,把app的那個Secret類拷貝過去,不過一定要註意包名一定不能變:

技術分享

然後在代碼中直接調用native方法:

技術分享

不過可惜的是,調用的結果,沒有加密字段信息。所以這裏我們會發現應該還缺少什麽設置。我們回過頭看看java層的代碼:

技術分享

這裏有一個set方法,在之前分析已經發現了,他的調用地方:

技術分享

這裏有一個SecretDataModel類,應該是從網上請求獲取到的數據,然後解析構造出這個類,看看這個類定義:

技術分享

看到這裏,發現已經用了第三方的json解析包,註解直接解析字段值。但是我們全局搜索這個類的話,跟蹤太麻煩了,這裏就采用另外一種方式跟蹤代碼,那就是利用Xposed攔截這個類的構造方法,然後在內部打印堆棧信息來查看方法的調用路徑,這種方法我在之前已經用過了。本文能夠更好的體現:

技術分享

因為應用是多dex文件,所以hook必須先hook他的Application類的attach方法拿到正確的類加載器,正確加載需要hook的類信息,不然就報錯了。這個已經講了很多遍了。然後就是利用自動拋異常來打印方法的調用堆棧信息,安裝運行,重啟生效看日誌:

技術分享

這裏看到了,他用google的gson庫解析json數據的,看到了json數據是從下面這兩個方法中傳遞過來的,查看這個類的方法:

技術分享

點進去進行查看:

技術分享

為了看到返回的json數據,我們在攔截這個方法,把返回的json數據打印出來看看是啥:

技術分享

運行模塊,重啟生效,看日誌信息:

技術分享

看到這段json數據了,這時候,在返回去看看SecretDataModel那個調用set方法:

技術分享

看到這四個參數值,第一個是Context不解釋了,第二個是serverTime字段值,第三個是startCode字段值,第四個是runCode字段值。這三個字段都是可以在上面打印的json中找到的,我們把json格式化看看:

技術分享

有了這三個值和Context變量,直接調用Secret的native方法set進行設置,看看能否正確獲取到加密之後的字段值:

技術分享

運行demo程序看看日誌信息:

技術分享

看到了,設置成功了,而且獲取加密字段也成功了。到這裏我們就成功的獲取到加密字段s_sg值了。

五、獲取加密配置信息

不過到這裏還沒有結束,因為我們發現那三個set值字段從網絡獲取,我們還需要知道是哪個url獲取到的,這裏從代碼跟蹤依然很困難,所以我們還需要利用hook來打印方法的堆棧信息來追蹤代碼,通過上面打印的獲取json數據的堆棧信息:

技術分享

看到是這個類訪問獲取json數據的,進去看看:

技術分享

而傳入的參數,在進行查看:

技術分享

看到有一個getUrl方法,就是獲取訪問的url值,我們就可以這麽來進行hook操作,打印這個url訪問地址了:

技術分享

運行模塊,重啟生效,看日誌信息:

技術分享

下面打印了那個我們想要的json數據,上面有幾個url,我們在去Fiddler觀察這幾個url返回的數據,最後定位到這個是這個url返回的數據信息:

技術分享

六、梳理加密流程

到這裏我們就分析完了直播app的協議加密流程,下面來總結一下:

第一步:通過/user/account/token_v2接口獲取加密前的配置信息

第二步:通過native方法把第一步獲取到的信息進行設置(set方法)。

第三步:通過native方法將java層拼接參數的url值進行加密處理返回(encryUrl方法)

那麽我們可以這麽做,自己協議demo程序,在Java層拼接好參數,然後調用so的native方法,返回還有加密字段的url,然後可以解析出這個字段就是加密信息了。我們就可以批量處理這種網絡請求了。比如刷粉,觀看直播,點贊等操作。當然有的同學會認為這次操作其實不是真正意義上的破解加密算法。的確不算,但是我們弄到我們想要的就好,過程其實沒那麽重要,而在這個操作過程中,我們又學習到了很多逆向技巧。

七、逆向技巧總結

第一、在用Jadx打開apk卡死的時候,記得先解壓出dex文件,在用Jadx打開dex文件即可。

第二、對於多dex的應用,使用Xposed進行hook的時候,需要先攔截Application類的attach方法獲取正確的類加載器。不然會報攔截失敗。

第三、當我們在使用Jadx進行全局搜索內容,發現沒有搜索結果的時候,可能需要從以下幾個方面考慮:

  • 1、是否包含多個dex文件,可以利用Jadx去打開其他dex文件進行搜索。
  • 2、是否存在動態加載插件功能,全局搜索DexClassLoader找到插件加載位置,獲取插件功能包,在用Jadx打開插件包進行搜索。
  • 3、是否存在so文件中,可以利用IDA打開so文件,Shift+F12展示so中所有的字符串信息視圖,然後進行搜索。
  • 4、是否信息來源於網絡請求返回,比如一些字符串信息展示,有可能是服務器返回的信息。

第四、在我們用Jadx進行代碼跟蹤非常困難的時候,記得還可以利用Xposed攔截指定方法,打印堆棧信息來跟蹤代碼,也是一種高效方法。

第五、當你在使用Jadx右鍵一個方法看看調用路徑,發現沒有結果的時候,那麽看看這個方法是否是該類實現的一個接口中的方法或者是抽象方法。去父類或者接口中的那個方法在右鍵看看調用路徑。

第六、在不關心過程,只關心結果的場景下,可以構造一個app來調用程序的so,獲取我們想要的結果,這種方式一定要記住,後面很多場景都會用到。可以用它來嗅探so中一些函數的功能。比如通過調用so中的一個方法,輸入規律數據,看輸出結果是否符合一定規律,通過規律來破解加密算法。

八、總結

本文介紹的內容有點多,感謝該直播app開發者提供這麽好的研究樣本,當然最後需要說一句就是:安全防護策略不夠,我們在本文可以看到我們利用調用他的so來獲取加密信息,這個方法是可以用於很多app的,對於那些我們無需關心過程,只關心結果的內容,這種方法屢試不爽。那麽作為開發者如何規避這種安全問題呢?很多人第一就想到了:在so的JNI_OnLoad方法中判斷簽名信息是否正確,不正確就直接退出。這個的確可以防範。但是如果用我之前介紹的kstools工具原理,直接hook系統的PMS服務攔截獲取簽名信息方法,返回正確的應用簽名信息,這種防護策略就失效了。所以說:安全不息,逆向不止。兩者都在進步。

android黑科技系列——分析某直播App的協議加密原理以及調用加密方法進行協議參數構造