js逆向爬蟲實戰(2)--快手第三方平臺之加密引數

資料流浪者發表於2020-10-24

爬蟲js逆向系列
我會把做爬蟲過程中,遇到的所有js逆向的問題分類展示出來,以現象,解決思路,以及程式碼實現。我覺得做技術分享,不僅僅是要記錄問題,解決辦法,更重要的是要提供解決問題的思路。怎麼突破的,遇到這個問題怎麼思考,嘗試的方法有哪些。這樣就可以有的放矢。希望對大家有用

爬蟲認知
在程式猿所有的方向中,爬蟲是離money最近的一個方向,你的明白?而且爬蟲可發展的方向很多,前可走大資料,人工智慧,後可轉後端,還有就是安全領域。而且爬蟲做得好,要求的技術棧還是比較全面的。如果你對爬蟲有興趣,歡迎加V:13809090874,一起溝通交流

免責申明
此內容僅供學習交流使用,不用於商業用途,如果涉及侵權,聯絡作者刪除

此專欄系列主要寫一些js逆向爬蟲的實戰:

  1. 抖音第三方資料分析平臺爬蟲心路歷程(done)
    1.1 爬蟲js逆向之無限debugger–抖音第三方資料分析平臺的坑
    1.2 爬蟲js逆向之加密引數破解–抖音第三方資料分析平臺的坑
  2. 快手第三資料分析平臺爬蟲爬蟲心路歷程(ing)
    2.1 js逆向爬蟲實戰(2)–快手第三方資料分析平臺的請求解析
    2.2 js逆向爬蟲實戰(2)–快手第三方平臺之加密引數
  3. 淘寶
  4. 拼多多
  5. 知乎
  6. B站
  7. 微博
  8. 小紅書
  9. 美團
  10. 攜程

js逆向爬蟲實戰(2)–快手第三方平臺之加密引數與登入破解

上次寫了新快的請求分析(http2.0)的解決辦法,一直在想把js引數破解與登入破解的問題寫了,不過呢,最近應公司需求做了一個window一個桌面版軟體的破解,一個exe程式,搞的我有點頭大。破解沒解決,最後用自動化工具解決了。好了,我們們言歸正傳,說說快手第三方資料分析平臺–新快的加密引數破解和自動登入問題

新快的加密引數:xyz與nonce

為什麼是這兩個引數,可以參考上一篇文章js逆向爬蟲實戰(2)–快手第三方資料分析平臺的請求解析
下面我們的主要目的,是要獲取xyz與nonce的加密過程。OK,我們們走起。

1. 找一個有效的請求

在這裡插入圖片描述
大家可以看到我所圈住的請求,每條請求都會帶有“xyz”與“nonce”這兩個引數,而且也都是變數。右邊的則是該請求的響應結果。

2. 搜尋大法

在我們不知道這個網站是否對js程式碼混淆的時候,我們第一步一定是去搜“xyz”與“nonce”這兩個引數,看看能不能搜到。
在這裡告訴大家一個小技巧,不要在chrome裡搜,因為chrome只能搜單檔案,無法進行全域性搜尋。在charles裡搜或者在fiddler裡搜。
在這裡插入圖片描述
我是用charles的,我們在搜尋框中輸入“xyz”,然後下面出來一堆的結果。我們細細去看。第2部分,其實是我們的請求頭中的url中所帶的“xyz”引數,對我們是沒用的。我們主要找的是js檔案,也就是第3部分。
在第3部分中有兩個檔案:main.8bxxxx.chunk.js與async~…js這兩個檔案。我們看檔名,async是非同步的意思,而main,大家對這個應該非常熟悉吧,主要的檔案。非同步的那個我們暫時不看,先看看main這個檔案。
此時我們要移步chrome,找到該js檔案,(main.js檔案的路徑也在上圖)
在這裡插入圖片描述
根據上圖所描述的順序,找到main.js的檔案,格式化一下,然後搜尋“xyz”,我們就找到“xyz”所在的位置了。目前還遇到js混淆,還算幸運。是說他們弱呢,還是我們強,哈哈哈。

3. 分析js

我們仔細去看一下上圖所顯示的js程式碼,我們可以基本確定兩個加密引數“xyz”與“nonce”就是在這裡封裝的。當然,我們不確定的話,可以在這裡打個斷點,重新整理一下頁面,就可以看出的確是這這裡(這一步我自己做過了,就略過了)。
到這裡,我們找到了加密引數最頂層的封裝結果的地方了,下面我們要做的就是往下逆向,看這兩個“xyz”,“nonce”是怎麼生成的吧。不然我們沒辦法模擬它,對吧。

return "post" === e.method.toLowerCase() ? (e.params = function(e, t={}) {
                let a = "".concat(e, "?AppKey=joker")
                  , r = {
                    xyz: "",
                    nonce: ""
                };
                const n = i()(p, 9).join("");
                return a += "&nonce=".concat(n),#nonce生成的地方
                r.nonce = n,
                r.xyz = u()(a),#xyz生成地方
                r
            }("".concat(e.baseURL).concat(e.url), t),
            e) : e

4. 逆向js

我們可以看出xyz的生成是依賴與nonce的,那我們就先找nonce這個引數,從上面的js程式碼中,我們可以看出nonce就是等於“n”:

n = i()(p, 9).join("");

跟緊了,開始開車了啊!!!!
我們就是找i()這個方法了。這裡就得打斷點一點點往裡面找了。這也是它開始混淆的地方。
在這裡插入圖片描述
我們第一步斷點除錯,進入i()方法裡,然後通過控制檯輸出的形式,我們可以吧上面的混淆的js程式碼:

e.exports = function(e, t, n) {
        return t = (n ? a(e, t, n) : void 0 === t) ? 1 : u(t),
        (o(e) ? r : i)(e, t)
    }

簡化為:

e.exports = function(e, t, n) {
        return u(t),r(e, t)
    }

這裡有兩個方法u(t),r(e,t)

1.1 第二步深入–u(t)

在這裡插入圖片描述
不廢話,再深入r(e)

1.2 第二步深入–u(t) -->r(e)

在這裡插入圖片描述

1.3 第二步深入–u(t) -->r(e)–>r(e)

在這裡插入圖片描述

1.4 第二步深入–u(t) -->r(e)–>r(e)–>r(e),到底

在這裡插入圖片描述
到了這裡,就已經到了這個nonce()請求引數的底部了。e = 9,是一個“number”型別,所以就可以直接“return”了。這個js經過四層的呼叫,我們找到了最底部。
接下來我們要做的,不是說把完全去讀它的js,完全消化理解,然後復現它,這樣做我們會很蛋疼的。這裡只是4層呼叫,要是10幾層,幾十層,那豈不是要瘋了。
我們要做的就是,完全拷貝它的js,到我們自己的js檔案中,hook住這個方法就是。一個原則“缺啥補啥”

至此,我們就找到nonce引數的實現過程,同理‘xyz’引數尋找過程也是如此,就不囉嗦了,主要是貼圖說,打字說這個過程實戰太煩。以後找個機會錄個視訊,三五句話就能說明白的事情

上程式碼,python

我們找到引數的模擬過程了,然後就是把相關的js程式碼模擬出來。這就是引數破解的全過程了。(程式碼我只能截圖,不開源,因為我們畢竟是做爬蟲的,逆向的程式碼開源,我怕人家打我
nonce.js
在這裡插入圖片描述
xyz.js
在這裡插入圖片描述
xyz的破解比較長,有200多行js,沒貼全,(如果你需要破解程式碼研究學習,可以VX我

python的程式碼可以公開,如下

import requests
import os
import execjs
import redis

redis_cli = redis.StrictRedis(host='127.0.0.1',port=6379,db=5,decode_responses=True)
def xyz(url):
    js = execjs.compile(open(r"./xyz.js").read())
    res = js.call('xyz',url)
    return res

def nonce():
    js = execjs.compile(open(r"./nonce.js").read())
    return js.call('nonce')
def all_rank_list():
    cookies = redis_cli.lrange('ksxk_cookies',0,-1)[0]
    print(cookies)
    header = {'Content-Type': 'application/json;charset=UTF-8', 'pragma': 'no-cache', 'cache-control': 'no-cache', 'accept': 'application/json, text/plain, */*',
              'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36', 'origin': 'https://xk.newrank.cn',
              'sec-fetch-site': 'same-origin', 'sec-fetch-mode': 'cors', 'sec-fetch-dest': 'empty', 'referer': 'https://xk.newrank.cn/data/account/rank/overall',
              'accept-encoding': 'gzip, deflate, br', 'accept-language': 'zh-CN,zh;q=0.9', 'Connection': 'close', 'Content-Length': '101',
            'Cookie':cookies}
    url = 'https://xk.newrank.cn/xdnphb/nr/cloud/ks/rank/accountAllRankList'
    nonce_ = nonce()
    url_ = url + '?AppKey=joker&nonce={}'.format(nonce_)
    xyz_ = xyz(url_)
    url_params = {
        'xyz':xyz_,
        'nonce':nonce_
    }
    url = '{}?{}={}&{}={}'.format(url,'xyz',url_params['xyz'],'nonce',url_params['nonce'])
    post_params ={"type":"搞笑","rankDate":"2020-10-07","start":1,"size":20,"rankType":"realTime","sort":"newrankIndex"}
    r = requests.post(url, json=post_params, headers=header,verify=False)
    print(r.text)

在這裡插入圖片描述
請求引數的破解就已經完成了,哈哈哈哈哈哈,還有誰!!(不能跳,得低調點)
當然這對於爬蟲的前期工作來說只是完成了一半,還有個什麼問題啊,朋友們。還有登入的問題,也就是cookies的問題。沒有cookies,一切都是白搭

登入問題,待會寫。主要是通過selenium自動登入,因為還有滑塊的問題。

相關文章