一.項目背景
學(xué)習(xí)爬蟲最難之一無非就是如何破解JS加密,但是關(guān)于JS加密的網(wǎng)上資料非常零散雜亂,本人對這方面也略有研究,本篇文章在之前兩篇文章[Python玩轉(zhuǎn)JS腳本](http://mp.weixin.qq.com/s?__biz=MzIzODI4ODM2MA==&mid=2247486598&idx=1&sn=1fb3996f99d0080c0c146395bb1a5139&chksm=e93ae001de4d6917a52ce50472e95d8153f23dad2409046d78ec0627b4af8c3f894349b41db9&scene=21#wechat_redirect) 和 [送你一個翻譯軟件(文末福利)](http://mp.weixin.qq.com/s?__biz=MzIzODI4ODM2MA==&mid=2247485945&idx=1&sn=4d085a0fbf2825fb8ce9c1466fad34b4&chksm=e93ae57ede4d6c68476a422b0d0102d06acb269853150894579475269c2298ba39710fd835fe&scene=21#wechat_redirect) 基礎(chǔ)上教大家如何破解JS加密,希望大家能夠?qū)W有所獲
二.實現(xiàn)過程
1.準(zhǔn)備工具
》》Chrome瀏覽器
》》鬼鬼JS調(diào)試工具
》》Pycharm
如果沒有鬼鬼JS調(diào)試器(可以寫JS代碼的編譯器,運行時需要關(guān)閉殺毒軟件)工具的小伙伴,后臺發(fā)送" **JS"** 關(guān)鍵字即可獲取。
2.分析網(wǎng)頁
》》網(wǎng)頁抓包
》》分析參數(shù)
》》明確來源
我們的目標(biāo)網(wǎng)址是微博登錄網(wǎng)址https://weibo.com/login.php,通過點擊瀏覽器Network抓包找到真正的請求網(wǎng)絡(luò)網(wǎng)址,通過查看請求信息發(fā)現(xiàn)是一個POST請求(一般來說POST請求要比GET請求安全的多)如下圖所示。
我們主要任務(wù)是如何破解請求參數(shù) su (如下圖所示),該參數(shù)明顯是一個被加密的參數(shù)(關(guān)于其他參數(shù)比如s****p等參數(shù)破解方法都是一樣的,感興趣的讀者可以下去試試,有問題的話可以后臺私聊我)
接下來我們需要搜索我們要破解的參數(shù),如下圖所示(如果還有不清楚的請參考之前文章[)](http://mp.weixin.qq.com/s?__biz=MzIzODI4ODM2MA==&mid=2247485945&idx=1&sn=4d085a0fbf2825fb8ce9c1466fad34b4&chksm=e93ae57ede4d6c68476a422b0d0102d06acb269853150894579475269c2298ba39710fd835fe&scene=21#wechat_redirect)
我們打斷點分析,如下圖所示,發(fā)現(xiàn)此處的**su**參數(shù)是輸入的用戶名經(jīng)過base64算法加密,現(xiàn)在需要以相同方式模擬生成。知道這些內(nèi)容后,通過復(fù)制網(wǎng)頁中相關(guān)JS加密代碼,在我們鬼鬼JS調(diào)試工具中運行生成加密內(nèi)容。
3.加載JS代碼
》》復(fù)制網(wǎng)頁中JS代碼
》》運行JS代碼
#鬼鬼JS調(diào)試工具代碼
function get_su(){
var sinaSSOEncoder = sinaSSOEncoder || {};
(function() {
var a = 0
, b = 8;
this.hex_sha1 = function(a) {
return i(c(h(a), a.length * b))
}
;
var c = function(a, b) {
a[b >> 5] |= 128 << 24 - b % 32;
a[(b + 64 >> 9 << 4) + 15] = b;
var c = Array(80)
, h = 1732584193
, i = -271733879
, j = -1732584194
, k = 271733878
, l = -1009589776;
for (var m = 0; m < a.length; m += 16) {
var n = h
, o = i
, p = j
, q = k
, r = l;
for (var s = 0; s < 80; s++) {
s < 16 ? c[s] = a[m + s] : c[s] = g(c[s - 3] ^ c[s - 8] ^ c[s - 14] ^ c[s - 16], 1);
var t = f(f(g(h, 5), d(s, i, j, k)), f(f(l, c[s]), e(s)));
l = k;
k = j;
j = g(i, 30);
i = h;
h = t
}
h = f(h, n);
i = f(i, o);
j = f(j, p);
k = f(k, q);
l = f(l, r)
}
return [h, i, j, k, l]
}
, d = function(a, b, c, d) {
return a < 20 ? b & c | ~b & d : a < 40 ? b ^ c ^ d : a < 60 ? b & c | b & d | c & d : b ^ c ^ d
}
, e = function(a) {
return a < 20 ? 1518500249 : a < 40 ? 1859775393 : a < 60 ? -1894007588 : -899497514
}
, f = function(a, b) {
var c = (a & 65535) + (b & 65535)
, d = (a >> 16) + (b >> 16) + (c >> 16);
return d << 16 | c & 65535
}
, g = function(a, b) {
return a << b | a >>> 32 - b
}
, h = function(a) {
var c = []
, d = (1 << b) - 1;
for (var e = 0; e < a.length * b; e += b)
c[e >> 5] |= (a.charCodeAt(e / b) & d) << 24 - e % 32;
return c
}
, i = function(b) {
var c = a ? "0123456789ABCDEF" : "0123456789abcdef"
, d = "";
for (var e = 0; e < b.length * 4; e++)
d += c.charAt(b[e >> 2] >> (3 - e % 4) * 8 + 4 & 15) + c.charAt(b[e >> 2] >> (3 - e % 4) * 8 & 15);
return d
}
, j = function(a) {
var b = ""
, c = 0;
for (; c < a.length; c++)
b += "%" + k(a[c]);
return decodeURIComponent(b)
}
, k = function(a) {
var b = "0" + a.toString(16);
return b.length <= 2 ? b : b.substr(1)
};
this.base64 = {
encode: function(a) {
a = "" + a;
if (a == "")
return "";
var b = "", c, d, e = "", f, g, h, i = "", j = 0;
do {
c = a.charCodeAt(j++);
d = a.charCodeAt(j++);
e = a.charCodeAt(j++);
f = c >> 2;
g = (c & 3) << 4 | d >> 4;
h = (d & 15) << 2 | e >> 6;
i = e & 63;
isNaN(d) ? h = i = 64 : isNaN(e) && (i = 64);
b = b + this._keys.charAt(f) + this._keys.charAt(g) + this._keys.charAt(h) + this._keys.charAt(i);
c = d = e = "";
f = g = h = i = ""
} while (j < a.length);
return b
},
decode: function(a, b, c) {
var d = function(a, b) {
for (var c = 0; c < a.length; c++)
if (a[c] === b)
return c;
return -1
};
typeof a == "string" && (a = a.split(""));
var e = [], f, g, h = "", i, j, k, l = "";
a.length % 4 == 0;
var m = /[^A-Za-z0-9+\\/=]/
, n = this._keys.split("");
if (b == "urlsafe") {
m = /[^A-Za-z0-9-_=]/;
n = this._keys_urlsafe.split("")
}
if (b == "subp_v2") {
m = /[^A-Za-z0-9_=-]/;
n = this._subp_v2_keys.split("")
}
if (b == "subp_v3_3") {
m = /[^A-Za-z0-9-_.-]/;
n = this._subp_v3_keys_3.split("")
}
var o = 0;
if (b == "binnary") {
n = [];
for (o = 0; o <= 64; o++)
n[o] = o + 128
}
if (b != "binnary" && m.test(a.join("")))
return c == "array" ? [] : "";
o = 0;
do {
i = d(n, a[o++]);
j = d(n, a[o++]);
k = d(n, a[o++]);
l = d(n, a[o++]);
f = i << 2 | j >> 4;
g = (j & 15) << 4 | k >> 2;
h = (k & 3) << 6 | l;
e.push(f);
k != 64 && k != -1 && e.push(g);
l != 64 && l != -1 && e.push(h);
f = g = h = "";
i = j = k = l = ""
} while (o < a.length);
if (c == "array")
return e;
var p = ""
, q = 0;
for (; q < e.lenth; q++)
p += String.fromCharCode(e[q]);
return p
},
_keys: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
_keys_urlsafe: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_=",
_subp_v2_keys: "uAL715W8e3jJCcNU0lT_FSXVgxpbEDdQ4vKaIOH2GBPtfzqsmYZo-wRM9i6hynrk=",
_subp_v3_keys_3: "5WFh28sGziZTeS1lBxCK-HgPq9IdMUwknybo.LJrQD3uj_Va7pE0XfcNR4AOYvm6t"
};
this.Cookie = {
decode: function(a) {
var b = []
, c = a.substr(0, 3)
, d = a.substr(3);
switch (c) {
case "v01":
for (var e = 0; e < d.length; e += 2)
b.push(parseInt(d.substr(e, 2), 16));
return decodeURIComponent(j(sinaSSOEncoder.base64.decode(b, "binnary", "array")));
case "v02":
d = d.replace(/\\./g, "=");
b = sinaSSOEncoder.base64.decode(d, "urlsafe", "array");
return j(sinaSSOEncoder.base64.decode(b, "binnary", "array"));
default:
return decodeURIComponent(a)
}
}
};
this.getSUBPCookie = {
__parse: function(a) {
var b, c, d, e, f, g = 0, h, i = {}, k = "", l = "";
if (!a)
return i;
do {
c = a[g];
b = ++g;
for (h = g; h < c + b; h++,
g++)
k += String.fromCharCode(a[h]);
e = a[g];
b = ++g;
if (k == "status" || k == "flag")
for (h = g; h < e + b; h++,
g++)
l += a[h];
else {
l = a.slice(b, e + b);
try {
l = j(l)
} catch (m) {
l = ""
}
g += e
}
i[k] = l;
k = "";
l = ""
} while (g < a.length);
return i
},
decode: function(a) {
var b = [], c, d = a.substr(0, 3), e = decodeURIComponent(a.substr(3));
switch (d) {
case "002":
b = sinaSSOEncoder.base64.decode(e, "subp_v2", "array");
return sinaSSOEncoder.getSUBPCookie.__parse(b);
case "003":
c = e.substr(0, 1);
e = e.substr(1);
b = sinaSSOEncoder.base64.decode(e, "subp_v3_" + c, "array");
return sinaSSOEncoder.getSUBPCookie.__parse(b);
default:
return decodeURIComponent(a)
}
}
}
}
).call(sinaSSOEncoder);
urlencode = function(a) {
return encodeURIComponent(a)
}
su = sinaSSOEncoder.base64.encode(urlencode("13525486941"))
return su
}
與我們發(fā)的POST請求參數(shù)相同,說明我們成功地破解該參數(shù)。
4.Python運行JS文件
》》導(dǎo)入包名
》》加載文件
》》編譯文件
》》調(diào)用函數(shù)
import execjs
#生成su
def get_su():
#讀入JS腳本文件
with open('weibo_su.js', 'r', encoding='utf-8') as f:
content = f.read()
#編譯JS代碼
jsdata = execjs.compile(content)
#調(diào)用函數(shù)
wb_su = jsdata.call('get_su')
#輸出結(jié)果
print('wb_su:', wb_su)
#運行函數(shù),輸出也是相同的
get_su()
聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。
舉報投訴
-
JS
+關(guān)注
關(guān)注
0文章
78瀏覽量
18053 -
python
+關(guān)注
關(guān)注
55文章
4767瀏覽量
84375 -
爬蟲
+關(guān)注
關(guān)注
0文章
82瀏覽量
6813
發(fā)布評論請先 登錄
相關(guān)推薦
2704R加密芯片已破解,有替代方案
本帖最后由 Major911 于 2015-5-20 15:05 編輯
2704R加密芯片已破解,有替代方案。高難度加密芯片破解業(yè)務(wù)請聯(lián)系我,幾十款芯片的成功
發(fā)表于 05-16 16:05
exew文件加密:利用破解版exe文件加密器對exe文件進(jìn)行加密保護(hù)
exew文件加密:利用破解版exe文件加密器對exe文件進(jìn)行加密保護(hù)
發(fā)表于 12-19 17:04
labview的VI加密暴力破解工具
VI加密破解工具,有需要可以聯(lián)系我發(fā)送wx:***,破解內(nèi)容僅用于學(xué)習(xí),勿用于商用。
發(fā)表于 09-03 08:53
【開源三方庫】crypto-js加密算法庫的使用方法
應(yīng)用。如果是發(fā)布到開源社區(qū),稱為開源三方庫,開發(fā)者可以通過訪問開源社區(qū)獲取。接下來我們來了解crypto-js開源三方庫。crypto-js是一個加密算法類庫,可以非常方便地在前端進(jìn)行其所支持的加解密操作。目前
發(fā)表于 09-08 15:10
彩虹加密狗破解技巧數(shù)據(jù)代碼分析
彩虹加密狗破解技巧數(shù)據(jù)代碼分析以上是彩虹加密狗破解技巧數(shù)據(jù)代碼分析的簡單介紹,文章由(逆向開發(fā)技術(shù)網(wǎng))編輯整理。
發(fā)表于 01-24 08:00
?9次下載
Python怎么玩轉(zhuǎn)JS腳本
本項目旨在讓大家了解如何用Python來執(zhí)行JS腳本,其主要目的是在進(jìn)行數(shù)據(jù)
分析時,需要利用爬蟲獲取數(shù)據(jù),有時會遇到JS混淆加密反爬取難點,此時我們需
要獲取網(wǎng)頁JS
python爬蟲之某站JS加密逆向分析
實現(xiàn)的目標(biāo):可以通過JS加密逆向后,得到加密參數(shù),請求獲取數(shù)據(jù)。此方法同樣適用于被前端JS加密的用戶名、密碼爆破。
評論