記錄一次爬蟲(chóng)的js解密過(guò)程

概述

這里嘗試的是破解某道翻譯的js加密,網(wǎng)址如下:http://fanyi.youdao.com/

過(guò)程講解

第一步

首先需要尋找翻譯結(jié)果的請(qǐng)求地址,這里建議使用chrome瀏覽器,在后續(xù)的一些調(diào)試功能和快捷鍵上更加方便使用,先按f12打開(kāi)開(kāi)發(fā)人員工具,選擇network,然后輸入一個(gè)要翻譯的內(nèi)容,尋找結(jié)果,結(jié)果可以發(fā)現(xiàn)請(qǐng)求結(jié)果在如下圖所示的鏈接里:

第二步

觀察請(qǐng)求鏈接和請(qǐng)求頭以及header,觀察其中的規(guī)律,然后先用爬蟲(chóng)測(cè)試一下


請(qǐng)求鏈接

可能會(huì)用得上的請(qǐng)求頭

請(qǐng)求數(shù)據(jù)

第三張圖尤其注意,因?yàn)閖s加密往往就是對(duì)這個(gè)地方的數(shù)據(jù)進(jìn)行加密傳輸,而加紅框的地方經(jīng)過(guò)嘗試,可以發(fā)現(xiàn)是請(qǐng)求時(shí)會(huì)發(fā)生變動(dòng)的地方,先把請(qǐng)求頭和data完整復(fù)制,然后用爬蟲(chóng)嘗試,代碼如下:

import requests

headers = {
    'Content-Length': '200',
    'Cookie': 'OUTFOX_SEARCH_USER_ID=-1066101715@10.169.0.84; '
           'OUTFOX_SEARCH_USER_ID_NCOO=805928033.6230187; '
           'JSESSIONID=aaaB8dqXbJ9XM4ahhsuAw; '
           '___rl__test__cookies=1540086196483',
    'Host': 'fanyi.youdao.com',
    'Origin': 'http//fanyi.youdao.com',
    'Referer': 'http//fanyi.youdao.com/',
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 '
               '(KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36'
}


data = {
    'action': 'FY_BY_REALTIME',
    'client': 'fanyideskweb',
    'doctype': 'json',
    'from': 'AUTO',
    'i': 'look',
    'keyfrom': 'fanyi.web',
    'salt': '1540087006029',
    'sign': '675f5b51df2c8db9a12fe102f3355277',
    'smartresult': 'dict',
    'to': 'AUTO',
    'typoResult': 'false',
    'version': '2.1'
}

url = 'http://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule'

res = requests.post(url, headers=headers, data=data)
print(res.text)

結(jié)果為:
{"translateResult":[[{"tgt":"看","src":"look"}]],"errorCode":0,"type":"en2zh-CHS","smartResult":{"entries":["","n. 看;樣子;面容\r\n","vi. 看;看起來(lái);注意;面向\r\n","vt. 看;期待;注意;面向;看上去像\r\n"],"type":1}}

可以看到請(qǐng)求返回成功,然后刪除一些數(shù)據(jù),觀察能否訪問(wèn)成功,最終發(fā)現(xiàn)必須的請(qǐng)求頭和data如下:

headers = {
    'Cookie': 'OUTFOX_SEARCH_USER_ID=-1066101715@10.169.0.84;',
    'Referer': 'http//fanyi.youdao.com/',
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 '
               '(KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36'
}

data = {
    'client': 'fanyideskweb',
    'i': 'look',
    'keyfrom': 'fanyi.web',
    'salt': '1540087006029',
    'sign': '675f5b51df2c8db9a12fe102f3355277',
}

而除了data里的i、salt、sign和headers的cookie以外,其他都是固定的,并且cookie就用這個(gè)也行

第三步

通過(guò)上面得出的規(guī)律,那么接下來(lái)的目標(biāo)就是對(duì)于data里三個(gè)數(shù)據(jù)的模擬解析了,i很明顯是要查詢的單詞,而saltsign則需要我們?nèi)フ壹用艿囊?guī)則,所以現(xiàn)在在chrome瀏覽器下按ctrl+shift+f打開(kāi)全局查找,先查找我們要知道的salt,如圖:


可以看到代碼如下:

雖然能看到這些參數(shù),卻沒(méi)看到計(jì)算公式,所以我們?cè)谠摯a里繼續(xù)通過(guò)ctrl+f查找salt的位置,最終看到下面這個(gè)公式:

可以看出saltsign的計(jì)算加密這里實(shí)現(xiàn)了

第四步

找到了加密代碼以后,我們就可以將其轉(zhuǎn)換成python代碼來(lái)模擬,或者用一些模塊帶執(zhí)行js語(yǔ)句獲得結(jié)果,這里用python模擬方法,其中t可以用python解析為:

import time
import random
t = str(time.time()*1000 + random.randint(1, 10))
#*1000是在后面調(diào)試時(shí)發(fā)現(xiàn)時(shí)間戳剛好少了個(gè)1000倍

知道了t以后,就差一個(gè)e不知道了,于是我們可以開(kāi)始用瀏覽器進(jìn)行js調(diào)試,觀察e的值。調(diào)試步驟如下:
1.在需要得知數(shù)據(jù)的地方點(diǎn)擊行數(shù)設(shè)置斷點(diǎn),改行變成藍(lán)色即說(shuō)明設(shè)置成功,如圖:

設(shè)置斷點(diǎn)

2.重新輸入一個(gè)單詞,即會(huì)自動(dòng)幫你調(diào)試,如圖:

這下可以發(fā)現(xiàn)原來(lái)e就是單詞本身,所以接下來(lái)sign用python解析成的代碼就是:

import hashlib
e = '要查詢的單詞'
tmp = 'fanyideskweb' + e + t + '6x(ZHw]mwzX#u0V7@yfwK'
sign = hashlib.md5(tmp.encode('utf-8')).hexdigest()

測(cè)試后結(jié)果發(fā)現(xiàn)成功!源碼如下:

import requests
import time
import random
import hashlib

url = 'http://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule'

headers = {
    'Cookie': 'OUTFOX_SEARCH_USER_ID=-1066101715@10.169.0.84;',
    'Referer': 'http//fanyi.youdao.com/',
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 '
               '(KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36'
}

data = {
    'client': 'fanyideskweb',
    'keyfrom': 'fanyi.web'
}

e = input('請(qǐng)輸入單詞>>')
t = str(time.time()*1000 + random.randint(1, 10))
tmp = 'fanyideskweb' + e + t + '6x(ZHw]mwzX#u0V7@yfwK'
sign = hashlib.md5(tmp.encode('utf-8')).hexdigest()

data['i'] = e
data['salt'] = t
data['sign'] = sign

res = requests.post(url, headers=headers, data=data)
print(res.text)

總結(jié)

到這里js加密的破解就結(jié)束了,可以看到在流程當(dāng)中比較重要的地方就是:
1.找數(shù)據(jù),知道該網(wǎng)站會(huì)對(duì)哪些數(shù)據(jù)和請(qǐng)求頭進(jìn)行驗(yàn)證
2.找規(guī)律,尋找這些數(shù)據(jù)的加密規(guī)則
3.調(diào)試js,學(xué)會(huì)瀏覽器中對(duì)js代碼進(jìn)行調(diào)試
4.模擬數(shù)據(jù),將這些數(shù)據(jù)通過(guò)代碼模擬生成,然后加入到數(shù)據(jù)當(dāng)中

聲明

該文章主要提供交流學(xué)習(xí)使用,請(qǐng)勿利用其進(jìn)行不當(dāng)行為,并且由于本人也是通過(guò)尋找網(wǎng)上各種資料偶然習(xí)得js加密的入門(mén)方法,其中有許多處理不當(dāng)?shù)牡胤揭矚g迎指正


看到一個(gè)百度翻譯的JS逆向解密教程感覺(jué)挺不錯(cuò)的,這里推上:
https://blog.zhangkunzhi.com/2019/05/19/%E7%99%BE%E5%BA%A6%E7%BF%BB%E8%AF%91/index.html
還有一些其他不錯(cuò)的教程也一并推上:
https://www.cnblogs.com/junrong624/p/5533655.html

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容