【JS逆向百例】某點資料逆向分析,多方法詳解

K哥爬虫發表於2024-06-24

0

前言

最近收到粉絲的私信,其在逆向某個站點時遇到了些問題,在查閱資料未果後,來詢問K哥,K哥一向會盡力滿足粉絲的需求。網上大多數分析該站點的教程已經不再適用,本文K哥將提供 3 種解決方案,對於 webpack 不太熟練的小夥伴來說,這是一個很好的練手案例:

7g4HjG.png

逆向目標

  • 目標:某點資料,排行榜
  • 地址:aHR0cHM6Ly9hcHAuZGlhbmRpYW4uY29tL3JhbmsvaW9zLw==

逆向過程

抓包分析

開啟開發者人員工具,隨便開啟一個區域排行榜,在 Network 中即會抓包到相應的排行榜資料介面,即

/pc/app/v1/rank ,響應內容如下:

7gCT1P.jpg

請求引數如下,其中主要引數為 K 引數,需要透過演算法生成,其他引數 time,country_id 等,是時間戳以及一些固定的 id 值,k 值每次都會發生變化,需要進行分析研究:

7gCLQ6.jpg

本文將會用多種方法實現資料的採集,適合不同的技術群體。

協議採集

逆向分析

該介面是透過 XHR 進行請求的,我們直接下一個 XHR 斷點 api.diandian.com/pc/app/v1/rank,重新整理排行榜,成功斷了下來:

7gCn3Q.jpg

並沒有發現任何 k 值,所以我們找網路攔截器,透過堆疊找到 m.request 的地方,在此處下一個斷點,斷下來以後,檢視 m 變數,裡面儲存了很多回撥方法:

7gCI5f.jpg

透過檢視 m 方法,我們在 onRequest 方法上下一個斷點,同時在方法末尾也下斷點,同時將上圖的斷點進行方向,再次檢視排行榜,發現在 onRequest 上成功斷了下來。同時我們發現,在呼叫 t 函式之前並沒有 k 引數的生成:

7gCMCc.jpg

我們繼續執行,在方法結束末尾斷點斷了下來,發現右側已經有 k 引數的生成。所以,由此判斷,k 引數是透過 t 函式生成的:

7gCiB3.jpg

我們進入 t 函式,在函式的開頭和結尾分別下一個斷點,發現透過 M 函式以後,生成了 k 值:

7gCZq4.jpg

繼續跟進 M 函式,我們檢視 k 值是如何生成的:

7gCdDh.jpg

透過分析得到 k 值的生成邏輯為:

var r = h()(t.params, !1)
    , o = Object(y.a)(r, path, {
    s: n.s,
    k: n.k,
    l: n.l,
    d: n.d,
    sort: n.sort,
    num: n.num
}, "get");
t.params.k = o

所以他是透過 y.a 傳入 r、path 以及大陣列生成的,我們可以透過將 y.a 函式扣出來實現 k 引數的生成。

第一種思路我們可以看看 y 函式是如何被定義,可以看到它是 webpack 打包,呼叫 2294 模組來實現的:

7gJ93Y.jpg

第二種思路,我們進入 y.a 函式,進行演算法的還原,其生成邏輯如下:

7gCef9.jpg

發現是透過 Object(l.b) 函式加密成位元組集,然後透過 t.from 方法編碼成 base64 進行展示,所以我們只需將這兩部分進行演算法還原即可復現 k 引數的生成,當然本文將會用不同的方法進行分析。

手動 webpack + 補環境

在 y=n(2294) 下斷點,重新整理排行榜,在該行成功斷下來:

7gJkAH.jpg

進入分發器 n 中,將 runtime.js 全部拿下,放到我們本地:

7gJBCZ.jpg

拿到本地以後,將分發器匯出,window.kk=r

7gMn34.jpg

控制檯透過 n.m[模組名] 將所需的模組進行查詢:

7gJpgq.jpg
拿到對應模組後,將 js 裡的模組複製放到我們剛剛扣的分發器中:

7gJLRs.jpg
透過模組,呼叫加密函式,檢視報錯資訊:

a = window.kk(2294)
r = {
    "start_time": 1717776000,
    "end_time": 1718345618
}
n = {
    "proxy": "/app",
    "target": "",
    "sort": "dd",
    "num": 10,
    "s": "d044bec62c1c9f9eee1ebd567e501719",
    "k": "93086c0e7c41cf46",
    "l": "091043cf5d1393af",
    "d": 0
}
path = "/v2/user/monitor/msg"
o = Object(a.a)(r, path, {
    s: n.s,
    k: n.k,
    l: n.l,
    d: n.d,
    sort: n.sort,
    num: n.num
}, "get");
console.log(o)

7gJ0Za.jpg

這種錯誤就是提示缺少對應模組,我們只需根據呼叫堆疊向上檢視,補上缺失的模組即可:

7gJlu7.jpg

然後在控制檯用 n.m[模組名] 進行模組查詢,然後重複上述操作將找到的模組放入分發器即可,它這個站模組分佈在幾百個 js 中,也算是一種程式碼混淆了:

7gJqAJ.jpg

最後板凳坐穿,全部模組找完大概 6w 多行程式碼吧,結果如下:

7gJ7DI.jpg

自動扣 webpack 模組

網上自動扣 webpack 的方法很多,但是對於幾百個 js 檔案的模組來說,可能就不太適用,上部分手動透過 n.m[模組名] 進行模組查詢的方法是最通用的,但是對於多個 js 檔案模組就略顯繁瑣。所以我們可以透過重寫分發器的方法,將載入的模組自動儲存然後匯出。

首先方法同上,先找到分發器的位置,在 r.e 及它之前下個斷點:

7gJuJG.jpg

重新整理頁面,發現在 r.e 的地方成功斷住,我們將以下 js 程式碼在控制檯進行注入:

window.code = '';
r = function (e) {
    if (r[e])
        return r[e].exports;
    var d = r[e] = {
        i: e,
        l: !1,
        exports: {}
    };
    console.log(e)

    window.code += e + ':' + o[e] + ',\r\n'
    return o[e].call(d.exports, d, d.exports, r),
        d.l = !0,
        d.exports
}

然後回車重新整理瀏覽器,進行一遍檢視排行榜的操作,發現控制檯就會自動列印載入的模組:

7gJyTB.jpg

控制檯輸入 copy(window.code) 將模組匯出,然後同上述方法一樣放到分發器中即可,再掛上代理,將常規的 document、navigator 補一下即可呼叫。最後結果如下:

7gJHgt.jpg

演算法還原

分析完 webpack 與補環境以後,我們最後來講講如何用演算法生成。上文提到,我們進入 y.a 函式後,發現他主要是透過 Object(l.b) 和 t.from 這兩個函式生成的,進入 Object(l.b) 發現是一個 AES 方法:

7gJKYb.jpg

其中又發現了這個 t.from 方法,這個方法其實就是一個 utf8 編碼,復現如下:

t=[]
t.from=function (hexString, encoding) {
    if (encoding !== "utf8") {
        throw new Error("Unsupported encoding");
    }

    // 將每個字元轉換為對應的 UTF-8 編碼的數值
    let byteArray = new Uint8Array(hexString.split('').map(char => char.charCodeAt(0)));

    return byteArray;
}

剩餘的加密方法,我們引庫復現即可:

const crypto = require('crypto');
var c = crypto.createDecipheriv("aes-128-cbc", n, o);
return d += c.update(e, "hex", "utf8"),
    d += c.final("utf8")

同時將 c 與 _ 這倆個函式也補一下(補函式的話,遵循和原函式一致即可,如果讀不懂原函式,可能就會卡在某一部分):

function c(a) {
    return function(t) {
        return t;
    };
}
var n = c()(t);  

function _(n) {
    return typeof n === 'object' && n !== null;
}

最後全部函式實現完畢以後,結果如下:

7gJbZe.jpg

只需 70 行即可完成 k 引數的生成,至此全部流程分析完畢。

八爪魚採集

對於新手來說,0 程式碼實現資料採集是不二選擇,同時他還可以設定代理 IP 進行免封操作。使用教程也非常簡單,進入官網選擇對應的系統版本進行下載安裝:

7gC0vO.jpg

安裝完成以後開啟軟體,首先看到的是他擁有一個模板採集,裡面內建了很多已經配置好的採集任務,點選即可一鍵應用:

7gC7Lf.jpg

我們點選“模板”或者“更多”,搜尋點點資料,發現搜尋未果:

7gCExc.jpg

那我們只能手動去新建一個任務,選擇左側新建,然後輸入你要採集的網址:

7gCQ43.jpg

進去以後,等待網頁載入完畢,然後選擇自動識別,它會根據頁面的佈局自動生成幾套採集模板:

7gCgIY.jpg

同時你也點選切換識別結果來自由切換識別模板:

7gCba9.jpg

很多時候識別的結果不盡如意,你可以選擇刪除某些多餘的欄位,同時也可以點選頁面元素進行文字提取或者滑鼠點選等操作:

7gCWPa.jpg

在所有需要採集的東西都配置完畢以後,我們可以點選設定,進行代理的設定:

7gCU0J.jpg

這裡代理選擇,我們採用快代理的私密代理或者獨享代理進行配置即可:

7gCOML.jpg

所有任務都準備完成以後,即可儲存進行任務的採集:

7gCaNI.jpg

關於八爪魚進階的玩法還有自動打碼與點選翻頁等,特殊場景需要進行更多的實際應用。

相關文章