背景:需要編寫一個爬蟲爬取網站的資料,框架寫好了,發現該網站所有api都進行了加密.
用fiddler抓包
網頁端api如下圖所示:
這裏可以觀察到,這確實就是網站的api.而且返回的都是一大串莫名其妙的東西,隨後多抓了幾個包,可以發現共同點.
不同的api返回的前面部分都是一樣的,這樣其實已經可以假想這是一個json,加密肯定不會是md5,base64這些單向加密了.
下載app抓包
一輪操作之後發現,安卓端是一樣的返回內容.這樣就可以選擇逆向的方向了.一般我會先選擇js,因爲app有可能加殼了之類的,當然如果app沒有加殼的話,直接放到jadx的話肯定可以更直觀地定位到加密的位置了.
目前有三種選擇:
- js逆向
- app逆向
- 從後端找突破口
先從別的地方看一下哪個方向入手比較好
前端分析
直接在前端右鍵選擇檢查元素,再右鍵選擇查看源代碼,對比如圖
可以明顯的看出,源代碼是沒有前端的代碼的,只是簡單的加載了js和css文件.
由此可見,
- 本網站全是js或者接口生成的界面.
- 但是又因爲app端不需要接口返回前端界面,
- 但是app端的接口返回內容和網頁端是一樣的
綜上所述,加密來源是js.app的加密是通過java代碼.
js分析
在fiddler進行文件過濾之後可以發現,js只有這兩個文件,其中一個是5w行代碼,一個是1w行代碼.
我打開哪個都會卡幾秒.先從1w行的下手.
打開js在線格式化格式化一下.大致拖一下看看是不是全是亂碼,實際這個操作沒啥用.我們可以直接用搜索大法.目前我們得到能用的常量就是它的api路徑.
直接搜索 “searchVideoByClass”
如圖可見一發入魂.複製"SEARCH_VIDEOBYCLASS"繼續搜索後,最後追蹤到這段代碼
getVideoList: function() {
var t = this;
this.hasMore && !this.isLoading && (this.setLoadingShow(!0), this.isLoading = !0, this.$axios.postCheckCache(_.SEARCH_VIDEOBYCLASS, {
flag: this.videoFlag,
vt_id: this.typeId,
typeList: this.conditions.join(","),
currentPage: this.currPage + 1,
pageSize: 10
}).then((function(e) {
var n, a = e.data,
i = a.status,
o = a.msg,
s = a.data;
1 == i ? (t.currPage++, t.hasMore = s.pageSize == s.list.length, (n = t.videoList).push.apply(n, Object(P.a)(s.list))) : (t.hasMore = !1, window.console.error("errorCode", i, o, s), t.$u5_global.toastFail("錯誤:".concat(o)))
})).
catch((function(e) {
t.hasMore = !1,
window.console.error(e),
t.$u5_global.toastFail("數據請求失敗")
})).then((function() {
t.setLoadingShow(!1),
t.isLoading = !1
})))
},
一目瞭然的代碼,也沒說在哪裏加密.只能再從"this.$axios.postCheckCache(_.SEARCH_VIDEOBYCLASS,"這段中找到postCheckCache這個函數.直接跳到函數體中繼續分析
mi = {
initAxios: pi,
postCheckCache: function(t, e) {
if (t.needCache) {
var n;
if (n = "".concat(t.toString(), "?data=").concat(it(JSON.stringify(e))), st.hasItem(n)) {
var a = JSON.parse(st.getItem(n));
if (a.expiration > (new Date).getTime()) return new Promise((function(t) {
a.status = 200,
a.statusText = "OK",
t(a)
}))
}
}
return ui.a.post(t.toString(), e)
}
},
在搜索過程中發現,所有接口都是通過postCheckCache這個函數發送的.想必這就是核心代碼了.
這裏的代碼做過壓縮,也沒看到什麼加密.我們直接斷點吧.
chrome斷點調試
斷點如上.然而點擊刷新後發現頁面卡死了…
可想而知網頁做了防止debug的檢測,但是直接f12是正常的,那就找一下網站上的突破口.
訪問了一下之後發現.網站的框架是瀑布流懶加載的.就是當你滾到最下面的時候會繼續加載更多的內容.
通過這個方式我們可以不用刷新就進入接口的斷點.
如圖所示,證明地方沒找錯.這裏就是每個接口加密的位置,現在是還沒加密的狀態所以數據還是看得懂的.我們繼續下一步.
期間看到了isvue這種東西.大膽猜測這裏是判斷生成界面的地方.這時候數據應該已經返回了.我們打開fiddler也證明了我的想法.接口已經被訪問了.
步入這裏的時候,數據已經被加密了.這時候我們就可以開始看堆棧信息.
箭頭位置是我們斷點的位置,圓圈位置的時候,數據已經被加密了.
綜上所述,加密語句就是!!
concat(it(JSON.stringify(e)))
這一句了
直接控制檯跑一下
這時候已經找到核心加密語句,只要對它進行再追蹤,離成功不遠了.
控制檯輸入函數名(it) 進行追蹤之後跳到函數的位置了.學過加密的同學一看就知道是個什麼東西
加密在線解密
而且他這個代碼沒有做過多的混淆.直接告訴你是 AES加密了 密鑰和偏移也在
我們直接到在線aes加密試試看
cbc偏移量16 數據位也是128 輸出hex 字節集utf8 我賭他一手
如圖所示一發入魂
實在不懂AES的話可以逐個試試.也就十幾二十次就出來了…886