网易云参数解析(多图)
網(wǎng)易云api接口js逆向
工具:python3.6.6、火狐 、chrome、node.js
此教程為定向爬蟲,非通用向,就是會改動😑,此教程忽略部分基礎(chǔ)知識,如有不適請留下評論,我會補充。
文章目錄
- 網(wǎng)易云api接口js逆向
- api定位
- js定位
- js解讀
- js追蹤
- AES加密
- 重發(fā)
- 結(jié)尾:
api定位
基礎(chǔ)知識(難度:☆)
首先在web應(yīng)用中定位需要抓取的api接口,確定請求攜帶的參數(shù)及大概猜測加密方式(猜不到或者猜錯也沒有關(guān)系,只是為了方便快速定位),下圖是查詢評論api(其他原理一樣)。
js定位
難點在于這里(敲黑板,難度:☆☆)
如何確定加密的參數(shù)出處?這里羅列幾個步驟,大致可以按照這樣來
js解讀
找到j(luò)s的基本入口之后怎么利用?(持續(xù)難度:☆☆)
通用寫個大致流程步驟(并不能通用哈)
js追蹤
到了這一步一般就是比較繁瑣了,一般考究個人悟性及閱讀水平,實在沒有什么好的方法可以解決(也可以不追蹤,直接編譯整個js然后調(diào)用對應(yīng)的function,但是也需要一定的閱讀能力)。
說道此處,基本有了大概的處理思路了,就是不斷斷點調(diào)試,然后追蹤參數(shù)的出處及方式,最后重現(xiàn),下圖是網(wǎng)易云的一個追蹤過程圖。
根據(jù)函數(shù)定位向上尋找函數(shù)d,并添加斷點進行調(diào)試,可以發(fā)現(xiàn)d、e、f、g四個參數(shù)只有d是變化的,"{“s”:“s”,“l(fā)imit”:“8”,“csrf_token”:""}"(這是照抄我的程序上面的,我發(fā)送的數(shù)據(jù)是s,要求返回的是8,這也可以換成下載音樂的查詢格式,或者是評論歌詞都可以)還有下面的encSecKey的幾個參數(shù)除了(e、f)也是固定值。
function d(d, e, f, g) {var h = {},i = a(16);return h.encText = b(d, g),h.encText = b(h.encText, i),h.encSecKey = c(i, e, f),h}繼續(xù)跟蹤a函數(shù)可以定位到一個生成16位的隨機數(shù), 用到參數(shù) i 的就是params跟encSecKey的驗證,只要固定死了了 i 那么,encSecKey也就是固定值了。
AES加密
parm追蹤到 b 函數(shù)進行兩次運算,重新看一下參數(shù),d是發(fā)送的數(shù)據(jù),g是一常量,看看b函數(shù)
function b(a, b) { var c = CryptoJS.enc.Utf8.parse(b), d = CryptoJS.enc.Utf8.parse('0102030405060708'), e = CryptoJS.enc.Utf8.parse(a), f = CryptoJS.AES.encrypt(e, c, { iv: d, mode: CryptoJS.mode.CBC }); return f.toString() }看到這里先不管前面幾個運算是做什么,但是看到.mode.CBC 會不會有種熟悉的感覺?沒錯就是大名鼎鼎的AES的CBC,驚不驚喜意不意外,那么前面應(yīng)該就是補位函數(shù)了,看函數(shù)的名字也越來越像了(所以說為什么要猜測算法加密類型)。
ps:關(guān)于crypto庫的安裝,略,也可以在瀏覽器的console窗口進行調(diào)試代碼
from Crypto.Cipher import AES import base64#補全16的整數(shù)倍,要求bytes def contentEndo(content):content=content.encode('utf-8')while len(content) % 16 != 0:content += '\0'.encode('utf-8')#以0補全return (content) #進行AES加密 def AESencrypt(key, content):key = contentEndo(key)iv = b'0102030405060708'encryptor = AES.new(key, AES.MODE_CBC, iv)encrypt = encryptor.encrypt(content)encrypt = base64.b64encode(encrypt)return bytes.decode(encrypt)content ="{\"s\":\"s\",\"limit\":\"8\",\"csrf_token\":\"\"}" key = "0CoJUm6Qyw8W8jud" content = contentEndo(content) en =AESencrypt(key,content) print(en)得到的是,好像跟我們調(diào)試的有一點點不一樣
f5Lcudct4ZaW6sHL3WNKrqGGzqLedMMO1DN2CDPnLFC55pGM7XlcfLr5RfVCzCai不過至少成功了一半吧,將標(biāo)準的加密串進行解密
def decrypt(text):key = "0CoJUm6Qyw8W8jud".encode('utf-8')cryptor = AES.new(key, AES.MODE_CBC, b'0102030405060708')text = base64.decodestring(text.encode('utf-8'))plain_text = cryptor.decrypt(text)print (plain_text) b'{"s":"s","limit":"8","csrf_token":""}\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b'
可以得知其補位字符,把\0換成\x0b,就得到正確的運算結(jié)果,只要在結(jié)合隨機數(shù)i進行第二次加密就可以得到真正的param ,但是同樣的還是會出現(xiàn)加密串最后的有些不一樣,同樣通過解密得到補位的字符,加密后都是64位,用字符串拼接再進行加密
還有一點,就是最后的需要進行URL轉(zhuǎn)換
from Crypto.Cipher import AES import urllib.parse import base64#補全16的整數(shù)倍,要求bytes def contentEndo(content):content=content.encode('utf-8')while len(content) % 16 != 0:content += '\x0b'.encode('utf-8')#配合解密函數(shù)尋找補位字符return (content)#進行AES加密 def AESencrypt(key, content):key = contentEndo(key)iv = b'0102030405060708'encryptor = AES.new(key, AES.MODE_CBC, iv)encrypt = encryptor.encrypt(content)encrypt = base64.b64encode(encrypt)return bytes.decode(encrypt)def makeData():content ="{\"s\":\"s\",\"limit\":\"8\",\"csrf_token\":\"\"}"key = "0CoJUm6Qyw8W8jud"i="tCBHRuGjK2gndtne" #固定死,對應(yīng)的encSecKey就是常量encSecKey = "2e3d379b236dffdf32409f066f6cc2f076ab0d713546ed0da7372c357755b0c364009ce41c093864788cb487f2b854d56b1ce06c2b62d79a718206b9e4b42122a82322f8b28c857f3cc99cb39de06fe5882cea5f49fed9684afcc1d5e22ea500ea18781f586b533e0bde357ac2ea87d4bc8c99f65d7fc0756d099f4bb2ce8d84"content = contentEndo(content)en =AESencrypt(key,content)+'\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10'param = AESencrypt(i,en.encode('utf-8'))param = urllib.parse.quote(param)param=param.replace("/","%2F")data = "params={}&encSecKey={}".format(param,encSecKey)return dataprint (makeData()) content = "{\"s\":\"s\",\"limit\":\"8\",\"csrf_token\":\"\"}"運行程序
重發(fā)
把結(jié)果拷貝下來打開火狐瀏覽器的開發(fā)者模式,選擇編輯重發(fā),將參數(shù)填進去,看是否可以正常響應(yīng)。
把postdata粘貼進去,把請求頭里面的一些參數(shù)刪除Content-Length: XXX,看是不是正確的響應(yīng)
結(jié)尾:
一個定向的api爬蟲就寫完了,其實大部分都是可以按照這樣一個流程走一遍,如果這個不能通過的就需要一部分的js源碼編譯運行,通過調(diào)試斷點看一下傳輸?shù)母袷绞鞘裁葱薷囊幌?#xff0c;再進行加密也可以得到答案。
免責(zé)聲明:以上代碼及示例,僅用于個人學(xué)習(xí)使用,不允許用于商業(yè)或者危害其他個人或者團體利益相關(guān)的活動中。
總結(jié)
以上是生活随笔為你收集整理的网易云参数解析(多图)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: MyBatis缓存通俗易懂
- 下一篇: docker导入镜像 liunx_doc