本次實戰目標站點為 https://www.ichunqiu.com/courses/qmxc
,隨機尋找一門課程點擊播放,然後通過開發者工具獲取視頻文件地址。
這次我們測試的的課程 ID 與地址為:https://www.ichunqiu.com/course/298
,你可以選擇其它的,重點是用工具捕捉到 m3u8
文件。
請求網址: https://www.ichunqiu.com/video/info/338.m3u8?type=2
請求方法: POST
請求表單數據如下所示:
其中出現了第一個加密參數 rs
,首先從其入手。
編寫簡單的測試代碼,竟然出現了招聘啟事。
import requestsheaders = { "Host": "www.ichunqiu.com", "Origin": "https://www.ichunqiu.com", "Referer": "https://www.ichunqiu.com/course/298"}form_data = { "rs": "6d896ff4dec07103fad79c1b010286b8", "type": "2", "section_id": "338", "time": "1653371562000"}res = requests.post('https://www.ichunqiu.com/video/info/338.m3u8?type=2', data=form_data, headers=headers)print(res.text)
問題應該出在 ts
參數,下面就通過斷點分析該值,目測上猜測應該是 md5
。
斷點調試,得到加密關鍵點代碼如下:
u = new Rusha,c = sectionID + "icq",d = u.digest(c).substr(0, 32),
其中涉及的核心函數是 Rusha
和 u.digest(c)
,接下來就是漫長的扣取過程了。
為了扣取 Rusha
文件,我們找到了其定義位置,代碼如下。
window.Rusha = y;
然後扣取第 1 行~399 行附近相關代碼(截止 5 月 24 日可用)。
在接下來對扣取的結果進行改造和刪減,例如下圖。
接下來在刪除 y
相關導出部分代碼,如果你扣取失敗,可以點擊文末卡片,聯系橡皮擦。
測試加密之後的結果,使用下述代碼。
a.digest("338icq");// '6d896ff4dec07103fad79c1b010286b8431b8fbe'
很明顯官方截取的前 32 位,此時第一個步驟成功解決了。
但是也發現了一個問題,其實這個參數並沒有動態值的加入,也就是說,它是固定的。
繼續尋找被反爬原因,在請求頭中又發現了 Sign
參數,但是還沒等測試,再次被封了。
更換浏覽器,再次嘗試,發現就在 rs
參數之後,就是 Sign
參數。
這裡的參數都可以直接獲取到,不在進行或多說明,下面查看請求 m3u8
之後的響應內容。
其中 data
也被加密了。
再次跟進請求之後,發現 Ci
函數中存在解析代碼,其邏輯在圖片下。
果然最終解析出來的是 m3u8 文件內容,有目標就變得簡單多了。
r = xxtea.toString(xxtea.decrypt(n.data.data, xxtea.toBytes(i + sectionID)));
後續扣取 JS 部分的代碼,參考上文一點點來就行。
你正在閱讀 【夢想橡皮擦】 的博客
閱讀完畢,可以點點小手贊一下
發現錯誤,直接評論區中指正吧
橡皮擦的第 689 篇原創博客