首先來個聲明: 本文為論文性質(zhì),請勿轉(zhuǎn)載;本文僅學習討論加密解密技術(shù),勿用于其他任何用途,否則與本人無關(guān)!為了避免不必要的麻煩,屏蔽相關(guān)軟件的名字。
有朋友請我研究一個WX插件的驗證機制,一直沒找到整塊時間,回頭想起來這個事花了點時間看了看,很簡單,不過插件已經(jīng)過氣了。記錄一下逆向過程,開始吧!插件為DEB格式,解壓后出現(xiàn)了一個application和三個dylib,安裝后會彈出一個UIAlertView,要求輸入用戶名和驗證碼,隨便輸入一個會彈出注冊失敗。好,就從這個UIAlertView入手,因為它的initWithTitle跟這個DEB包的名字是一樣的,根據(jù)這個去定位相關(guān)函數(shù),把三個dylib和一個application都扔進IDA,查看輸入表,找到OBJC_CLASS___UIAlertView的交叉引用,最后確定一個z開頭的dylib里負責彈出這個UIAlertView,代碼如下:
我用的是IDA6.8,里面的Unicode支持不好,使用相關(guān)插件后,會自動在注釋中標上對應(yīng)的中文,但是跟心中期望的直顯中文還是有所距離,沒有6.9也沒辦法,我湊合用大家湊合看吧。
再去找消息響應(yīng)函數(shù),代碼如下:
我們來看一下dispatch_after的官方解釋 Enqueue a block for execution at the specified time.
可以理解成在指定的時間執(zhí)行代碼塊,至于代碼塊,IDA已經(jīng)幫我們分析好了,就是這個block_invoke。IDA為了表述方便吧,他重新定義了一個函數(shù)表示這個代碼塊。那就去看這個block吧!
翻譯一下:鑜孮1"就是注冊失敗,看一下text也挺清楚的,左邊成功,右邊失敗。
接下來就是去分析那個V8啥時候為1(注冊成功),代碼很清楚:checkUID textFieldAtIndex.text encrypt(getuuid())。驗證你輸入的驗證碼和一個加密了的uuid。getuuid顧名思義,
接著去看看encrypt
看起來很清晰,uuid先經(jīng)過utf8編碼,然后做MD5,把HASH值打成string再統(tǒng)一大寫。這樣看下來其實不是加密,編碼而已,checkUID的倆參數(shù)都搞清楚了,再去看看這個方法
打開一看有些篇幅,分析分析啊,看字符串的樣子,明顯是base64編碼過的,注意代碼中的這行 v10 = objc_msgSend(v9, "initWithData:encoding:", v8, 4); 這個4其實是
確定是標準的BASE64解碼,解碼后其實是一個URL地址,就是驗證服務(wù)器的。接著往下看,向這個地址發(fā)起了一個HTTP請求,把那個“加了密”的UUID和我輸入的驗證碼統(tǒng)統(tǒng)發(fā)給服務(wù)端驗證,然后在response里面找code,這個值就是服務(wù)器的驗證結(jié)果。到這里這個驗證機制就分析清楚了,這個插件的驗證太簡單了,方法名沒混淆,連個像樣的加密算法也沒加,嚴陣以待的LLDB都沒用上,就當給剛剛?cè)腴T的朋友們增加信心吧。On the last,我順便看了看其他dylib的代碼,發(fā)現(xiàn)這套驗證也是HOOK了其他人的驗證,貴圈真亂啊。。。。
|