前言
今天的分析對象是這個:aHR0cHM6Ly9tLmN{防查找,去掉我,包括大括號}0eXVuLmNuL3dhc{防查找,去掉我,包括大括號}C9tYWluL2F1dGgv{防查找,去掉我,包括大括號}bG9naW4=
就是去搞這個登錄接口的加密參數
就這三個參數
第一個不用說,就是個時間戳
第二個comParam_seqCode和第三個comParam_signature就是我們要破解的參數了
分析
開始搞吧,直接搜索comParam_seqCode
很快就找到了這里,同時第三個參數sign也找到了
打斷點測試下吧
輸入賬號密碼,點擊登錄,然后跟着斷點走:
走到了這里:
先看下這個t.d是屬於哪個函數對象的,往上找第一個外層定義的,不太理解的,訣竅就是,往上跟着找同排列的同級的,然后第一個同級的外層定義體,這個就是函數對象了,如下:
繼續點,又走到了這里,說明這里才是實際的加密邏輯
看這種加密邏輯,有點像webpack啊,直接搜webpack看看:
還真的有,那就可以走一個取巧的方案了,因為本篇文章,標題也說了取巧方式,所以不會直接去逆向,而是用webpack的屬性,導出我們需要的加密方法,然后調用即可
怎么導出,先不急,看看加密邏輯,上面是第二個參數,再看第三個加密參數的邏輯,接着走斷點:
發現走到一個chunk里,這個chunk名字不重要
先看這個S是在哪個函數對象里,網上找,發現這個8d81,好,做個記錄
繼續走斷點,走完斷點,第二個,第三個參數,值都有了
整個流程就完了,總結下,comParam_seqCode進入到了一個7f6d的函數對象里,comParam_signature進入到了一個8d81里,這里我們只需要把這兩個函數導出來,然后調用即可
調試
這里就不多說了,webpack其實是一種代碼打包壓縮,實際上並不是加密,搞過vue的應該有了解,我的博客里也有vue相關的文章:https://www.cnblogs.com/Eeyhan/category/1422542.html
具體就不多介紹了,反正就是,webpack打包之后,最后會暴露出一個入口,這個入口會被調用,然后才進入核心的webpack代碼,所以我們找到這個打包到入口函數的過程,然后賦值給一個全局對象,我們直接調用這個全局對象就可以直接用里面的方法了,具體邏輯就不太好用文字說明了,直接實操吧:
找到導出器exports,包含exports的字眼,因為所有的webpack打包,都長這樣,一搜發現還挺多的,那哪個才是我們要用的呢?
先把這個main.xxx.js的代碼全部復制下來,放在本地,在上面我看着眼花,而且沒法縮進,本地搜發現就12個
找一個定義export之后又立即有操作的,就是它了,一般在整個js的最開始部分,這里一找就找到了
可以看看,其他的都是些賦值操作:
中間略過。。。。。。
后面全是賦值操作,這種我們也不方便處理,肯定要在一個地方設置之后一勞永逸的,那一定是最開始那里了
那好,開始操作吧,我們先在js文件的最開始部分,定義兩個變量,不給修飾符就默認是全局變量,當然你也可以給個var
然后再剛才定位到導出器那里,如下設置:
if (typeof (_map[n]) == 'undefined'){
_map[n] = 1;
_code = _code+ '"'+n+'":'+e[n]+",";
}
注意,一定要在return前面,exports定義的后面
再在這個函數的后面賦值給一個全局對象,值為這個函數名:
最后一步,把導出器輸出的入口函數去掉,因為我們根本就不需要它了,刪掉t()即可,然后保證代碼不標紅
已經完了?
沒有呢,我們還要做導出捕獲,打開fiddler,把線上的那個js替換成我們改過的這個js文件,打開fiddler:
保存之后,瀏覽器直接開個無痕模式吧,懶得去清那個站的cookie了,搞起麻煩,開無痕,兩個對比,正好,回車:
打開看到fiddler那個文件報錯了
把路徑的反斜杠改為斜杠,保存,重新刷新,網站打開是空白,不要緊,打開控制台
順便看看,這邊也成功請求,只要不是紅色就是沒問題,如果是紅色,請檢測你的路徑
現在在控制台里,看看剛才的方法能用不:
ojbk
現在把7f6d的放進去執行,
執行完了后,_code里就會有東西,這個_code一開始是空的,執行了window.get_code后,就會把相關的東西放進_code里,這里你可以理解為手動調用了一次導出器,把要導出的東西放到了_code里
把這一長段js復制出來,調整下,直到不標紅,這個是個繁瑣且沒有技術含量的操作,但是卻是一項不可缺失的操作,就像曾經在大廠呆過的我一樣,做的事感覺low,但是就是不可缺失
調整完之后,把這整段代碼,替換掉剛才本地的js里的這段:
就是上面的最后縮進好的整段,但不包括大括號哈,原始的部分內容如下:
現在把剛才調整好的導出的js覆蓋掉上面的,調整完如下,第一個就是7f6d
現在就開始調用了,如下:
報錯了,先放一放,有朋友應該會問了,你怎么知道要調用k啊,看最開始的代碼,這個u['k'].(),這個寫法不糾結了,反正我告訴你此時跟k()是一個意思
繼續看那個報錯,把window補齊下,這個就再熟悉不過了,補齊,此時這里的window一定要寫成global才行,寫成空對象{}不能出值,調用k
繼續執行,又報了個userAgent的錯
這個就很簡單了
繼續執行:
補:
繼續,ok,comParam_seqCode是有了,
接下來第三個加密參數,這個就有點意思,因為我們剛才拿到的是8d81,但我們如下調用,報錯了,
這,有點意思了,那還是像剛才那樣,去導出看看,先把補環境這里注釋掉,
繼續用fd替換然后控制台執行:
然后把這段代碼,跟之前的7f6d放一起就行了:
現在再執行下這個函數,不報錯了,
調用看看,這里又有個問題,怎么調用啊,直接調用看看:
這個值也不知道對不對,打斷點走到這里看看,注意這里的代碼不是替換過的代碼,原始代碼:
這時候,在控制台執行看看,發現,不傳任何值的時候,完美,對上了,此時感覺有點像md5啊,不過不用細摳邏輯,相信就算是md5也肯定是做了加鹽的,肯定不會原始的md5
那傳對應值呢?先看調用邏輯
那o我們已經有了,a,t,n是啥?原始代碼的控制台看看:
發現a就是剛才的k()方法的值,t是固定的,n就是個時間戳,不過精確到了微妙級別,ok,就用這三個值單獨調用下,看能不能對上就行了:
再看原始的控制台輸出呢,對上了,此時此刻,其實已經可以說算搞定了
再看comParam_signature 其實是o()(n + a + o()(a + t + n))
那么我們的代碼就寫成如下即可:
執行結果就不對比了,就掉了兩次而已,三個參數也沒變,沒有太大區別,成了
就是這樣的了
后續就可以把這段js封裝成一個函數,然后被python的pyexecjs庫執行即可,然后帶上加密參數去請去,完美,另外注意那個t變量,因為是寫死的,保不齊可能會像某詞典一樣,不定期改變這個值,所以你要長期用,應該要單獨寫一個程序去請求這個js獲取源碼,把t摳出來作為變量傳入,活動輸出,具體的python代碼細節就不展開了,也不是什么難事了,略過
補充
其實,這種不算是實際的破解,而是調用,玩逆向的,不要糾結於用的什么方法解決,能搞定就行了,但是平時實際的研究的時候,對於一個問題掌握多個解決方法,肯定是可以的
另外,如果對這個webpack邏輯熟悉,不用搞得那么復雜,我只是寫的比較細,真的操作秒解決不是誇張說法
有經驗的人怎么做,拿到7f6d和8d81之后
第一步
把名字為main的js文件內容copy下來,然后把最后那一大坨本來要覆蓋的,直接刪除
第二步
把7f6d和8d81在源碼里搜到的,復制下來放進去:
第三步:
啥都不用管,直接把這個導出器的結果賦值了
第四步:
執行,然后,缺啥補啥,補環境略過,一樣可以拿到值
都不需要用fiddler替換,然后用那什么map,code,在控制條輸出值再調整,這個繁瑣的過程直接沒有了
別看上面四步說起來有個幾十個字,操作起來真的就分分鍾,執行肯定是秒秒種出結果的
另外要注意的是,有時候,去找那個導出器exports時,可能對webpack不熟悉,找到個其他的文件,然后這個文件里面就有很多個exports,搞得你都不知道怎么操作了,那說明你一定找錯了,就比如這個站,如果你找到的是名為chunk的js的話,里面就有很多個exports。
webpack作為一個打包工具,一定有個入口,基本都在一個叫main的文件里,或者其他的index之類的,找到那個只有一個exports定義加return的就行了
結語
你覺得難嗎?