Android中某視訊的資料請求加密協議(第二篇)
阿新 • • 發佈:2019-01-06
本文轉載自Android中某視訊的資料請求加密協議(IDA動態除錯SO)第二篇
年前必須搞定短視訊四小龍,之前已經搞定某音和某山,那麼今天繼續來搞某拍,不多說,找到突破口還是抓包。
我們通過下拉一次資料看到這個請求url,發現請求中的引數資訊沒有攜帶簽名信息,但是返回的資料是加密的位元組陣列。所以得先搞定這個位元組陣列了。直接用Jadx開啟應用,然後全域性搜尋url字串資訊。
很容易就找到了,直接點選進入即可。
這裡看到呼叫一個方法之後拿到字串就開始直接解析json了,看看這個返回字串方法。
Jadx中解析失敗,不過沒關係,還是smali程式碼,大致能看懂,繼續往下看。
這裡需要你用過okhttp框架了,一看就知道這裡用到這個框架,而且最終通過bytes來獲取位元組陣列,我們看到這裡又呼叫了一個方法,然後直接返回字串了,去檢視這個方法實現。
繼續往下看,應該是個解密方法。
這裡依然把加密工作放到了native層了,我們操作依然很簡單,直接把這個libte.so拷貝到我們的demo工程中,然後構造這個native類,直接呼叫native方法進行解密即可。
我們通過之前抓包看到,請求引數都是一些常規的資訊,沒有簽名信息,為了簡單,這裡直接把這些引數拷貝出來寫死利用okhttp框架進行資料請求。
當然這些引數後續肯定需要優化,實現動態獲取最靠譜。
拿到請求之後的位元組資料之後呼叫native方法進行解密,我們直接執行看看日誌資訊。
可惜的是解密失敗。那麼就要懷疑so中是否有判斷邏輯了,直接使用IDA開啟so檢視。
直接F5檢視對應的C程式碼,看到一個tinydecode函式的返回值,然後有一個判斷,進入這個函式看看。
這裡呼叫了strstr系統函式,這個函式主要用來判斷第二個引數是不是第一個引數的字串,如果是就返回字串的指標,如果不是就返回空指標NULL。看到這裡有個包名欄位,感覺應該和包名有關係,雙擊這個g_packagename欄位,然後點選X鍵,檢視呼叫的地方。
在JNI_OnLoad中進行賦值的,依然檢視JNI_OnLoad函式程式碼。
這裡開始進行賦值了,看看上面這裡的sub_43B0函式怎麼獲取字串資訊的。
好吧,竟然是通過讀取系統的這個檔案來獲取包名值,而不是通過全域性的Context變量了。這個檔案是很奇特的,只要在本應用中讀這個檔案就是當前應用包名,而用命令列去檢視這個檔案是沒任何內容的。這個知識點大家就記住一下就好了。那麼這個到底用當前應用包名和哪個包名進行比較呢?看上面的strstr函式的第二個引數。
依然雙擊這個變數,然後點選X鍵檢視賦值地方。
還是在JNI_OnLoad函式中,點選進入賦值程式碼。
看到一個特別的字串資訊和一個迴圈指令,可以猜想應該是通過這個字串資訊來獲取最後的資訊賦值給g_me變數,這個值應該是應用的包名com.yixia.xxxx,只有當前應用的包名正確才能正確呼叫邏輯。所以這裡我們需要修改一下so指令,讓這個判斷無效。網上有一個工具線上修改地址:http://armconverter.com/,先輸入CMP R0,#0指令,看看對應的十六進位制值和so中的值是否對應。
去IDA中檢視這條指令對應的值。
這裡為了後面修改指令方便,藉助010Editor工具進行操作。
010Editor工具有兩個常用的快捷鍵,一個是Ctrl+F全域性查詢十六進位制值,一個是Ctrl+G跳轉到指定的地址。這裡我們跳轉到5BB0地址處。
看到這裡的值是000050E3,和上面的轉化的arm架構值對應的。那麼下面就來修改指令,比較簡單,直接修改為CMP R0,#0==>CMP R0,#1。
對應的十六進位制值就是010050E3了,直接去010Editor工具中進行修改儲存,再次用IDA開啟修改之後的so檔案,F5檢視程式碼。
這時候strstr返回NULL了,和1進行比較顯然不相等就開始走下面的正確解密邏輯了。修改成功了,到這裡有的同學好奇,是否可以直接修改後面的BEQ指令為BNE呢?當然是可以的,這個方式後面繼續介紹,因為我寫文章的目的就在於能介紹技術都給介紹,多條路始終是好事。然後我們把修改之後的so檔案拷貝到工程中,再次執行,其實這個結果還是不可以的,當然找問題還得去那塊請求資料的smali程式碼處。
開始的分析okhttp請求程式碼處忽略了這個地方,去檢視這個類。
到了這個內部類中發現了很多關鍵資訊,最重要的莫過於這個UA,請求頭資訊。而這裡有很多資訊,還包括了簽名信息,繼續往下看。
好吧,這下已經肯定就是把簽名信息放到了請求頭中了,這招也是夠狠的,一般人還很難發現,再回到Fiddler抓包看看請求頭中的具體資訊。
果然在頭部中有這幾個資訊,通過分析可以發現,除了sign欄位其他的值可以暫時寫死,都是表示唯一的,後續需要搞定那個sessionid值。這裡先不管寫死。然後就來關鍵看看sign簽名欄位值怎麼來的。
依然呼叫上面的native方法的,這裡為了搞清楚引數值,直接啟動hook大法列印引數值即可,沒必要分析程式碼了。
需要注意的是應用進行拆包了,所以為了確保hook成功,先hook系統的Application類的attach方法拿到正確的類載入器,這個方法已經在很多文章中都介紹了,這裡不多說了,直接執行看日誌。
看到引數再結合上面的程式碼可以看到,大致是應用版本號、UUID、時間戳、請求url的path值。這裡我們可以把前兩個值寫死,後面兩個值獲取即可。
這裡的URL就是請求視訊列表資料的。
然後我們把上面的頭部資訊設定到okhttp中即可。
然後執行看看效果,抓包看到頭部資訊已經設定成功了,看看返回的資料。
看到的確有結果了,但是貌似是錯誤資訊,直接去轉碼這個Unicode值。
看到,提示是簽名校驗失敗,也就是上面的頭部資訊中的簽名值是錯誤的。說明那個native函式簽名有問題,繼續用IDA開啟so檔案進行檢視即可。
這裡依然有一個sign函式,獲取v18值,到下面進行比較邏輯,進入sign函式看看。
果然這裡還是進行判斷當前應用是否為正確的包名,所以我們需要修改指令了,這一次不修改該CMP比較的值了,而是修改跳轉指令,直接把BEQ改成BNE即可,方法和之前一樣。把修改之後的so檔案拷貝到我們的demo工程中,再次執行。
這樣終於有結果了,我們把這json格式化看看。
好了到這裡,我們就成功的拿到了視訊的資料了。