兄弟,你爬蟲基礎這麼好,需要研究js逆向了,一起吧(有完整JS程式碼)
這幾天的確有空了,看更新多快,專門研究了一下幾個網站登錄中密碼加密方法,比起滑塊驗證碼來說都相對簡單,適合新手js逆向入門,大家可以自己試一下,試不出來了再參考我的js程式碼。篇幅有限,完整的js程式碼在這裡:從今天開始種樹
前戲
今天要碰的是汽車之家
,關於這個網站網上大多都再研究其字體反爬,如果想研究字體反爬的話直接搜一下就有很多。
今天主要是研究汽車之家在登錄時的password
加密方法,並通過python
調用js
的方式運行出加密結果。
開始
老規矩,打開登錄頁面,長下面這樣,與大多網站一樣的布局,切換到帳號密碼登錄。
接下來應該知道怎麼做了吧(花5秒鐘假裝思考一下),跟長頸鹿裝進冰箱里一樣,一共4步:
- 把冰箱門打開:F12,切到
Network
頁簽(一般默認就是這個頁簽,建議大家都用chrome
); - 把大象拿出來:輸入帳號密碼,可別輸入正確的哦;
- 把長頸鹿放進去:在請求列表裡查詢關於登錄發起的請求;
- 把冰箱門關上:找到請求,查看
POST
(一般都是post請求,暫時還沒見過其它方式的) url,還有FormData
里的參數。
把冰箱門打開
按F12打開工具
把大象拿出來
輸入錯誤的帳號密碼。
把長頸鹿放進去
找到請求,一般這種就需要就經驗了,有時候這種請求名稱會帶login
等字眼,通常都是ajax
請求(切到XHR
可以只看ajax請求,如果實在找不到可以切換到XHR),這樣就不會有亂七八糟的圖片、css、js請求干擾你。
把冰箱門關上
這裡只截取了部分數據,後面沒截的大都是滑塊驗證碼相關參數,這個後續再進行研究,今天只看這個pwd
參數。
分析
有了前面查看的結果,我們可以直接拿這個pwd
去sourecs
里查找相關的js文件,從下圖看有兩個文件包含pwd
關鍵字,第一個看著都不像,不信你可以點進去看看,第二個包含了login
關鍵字,八九不離十就是它,點進去。
進行來後繼續搜索pwd
關鍵字,幸運的是只有一個結果:
那可以確定加密函數就是hex_md5
了,一般我們會碰到的就是帶有rsa
、MD5
、encrypt
之類的函數,可以作為經驗留意一下。
調試
整一個斷點,我整在了413行,大家看自己的在第幾行。
輸入帳號密碼,點擊登錄然後應該就會跳轉到413行,點擊右側下一步箭頭,就是下面這個:
hex_md5函數
一步一步運行進入hex_md5
函數,函數長這樣:
function hex_md5(s) {
return binl2hex(core_md5(str2binl(s), s.length * chrsz));
}
s
是我們的密碼,可以看出調用了binl2hex
和core_md5
,還有一個chrsz
變數,往上看一點就發現了chrsz
。
hex_md5
函數返回的就是最終加密的結果。
binl2hex函數
function binl2hex(binarray) {
var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
var str = "";
for (var i = 0; i < binarray.length * 4; i++) {
str += hex_tab.charAt((binarray[i >> 2] >> ((i % 4) * 8 + 4)) & 0xF) + hex_tab.charAt((binarray[i >> 2] >> ((i % 4) * 8)) & 0xF);
}
return str;
}
hexcase
在前面那個圖裡有,binarray
先不用管,這是core_md5
返回的值,函數相對簡單,內部也沒有繼續調用小函數,我們也不用知道幹了啥,到時候摳出來直接調用即可。
str2binl函數
function str2binl(str) {
var bin = Array();
var mask = (1 << chrsz) - 1;
for (var i = 0; i < str.length * chrsz; i += chrsz)
bin[i >> 5] |= (str.charCodeAt(i / chrsz) & mask) << (i % 32);
return bin;
}
這個函數也沒有內部小函數了。
core_md5函數
這個函數就長了,內部也調用了很多,這裡只截部分了,建議分別去看看調用的這些小函數,比如md5_ff
等,這樣後面好扣程式碼:
function core_md5(x, len) {
/* append padding */
x[len >> 5] |= 0x80 << ((len) % 32);
x[(((len + 64) >>> 9) << 4) + 14] = len;
var a = 1732584193;
var b = -271733879;
var c = -1732584194;
var d = 271733878;
for (var i = 0; i < x.length; i += 16) {
var olda = a;
var oldb = b;
var oldc = c;
var oldd = d;
a = md5_ff(a, b, c, d, x[i + 0], 7, -680876936);
d = md5_ff(d, a, b, c, x[i + 1], 12, -389564586);
c = md5_ff(c, d, a, b, x[i + 2], 17, 606105819);
b = md5_ff(b, c, d, a, x[i + 3], 22, -1044525330);
a = md5_ff(a, b, c, d, x[i + 4], 7, -176418897);
.....
省略
.....
摳出來python運行
前面已經把js程式碼加密思路理了一下,大家可以自己試著摳一下,實在摳不出來的點擊這裡從今天開始種樹參考完整js程式碼,接下來使用python運行,使用的依然是execjs
庫。
import execjs
with open('..//js//qichezhijia.js', encoding='utf-8') as f:
qichezhijia= f.read()
js = execjs.compile(qichezhijia)
logid = js.call('get_pwd', "123456")
print(logid)
結果對比
FormData里的加密結果:
python運行的結果:
看看的確是一模一樣,一方面說明沒問題,另外一方面說明加密方法跟時間戳沒什麼關係,有些網站加密結果還會跟時間戳、useragent等有關。
結束
整個過程並不難,又是一個適合js逆向入門練手級網站,可以通過這個例子練習一下調試技巧,完整程式碼點擊這裡從今天開始種樹,關注下面的公眾號,獲取更多內容,當然不關注也無所謂。