歷經 10 篇左右的 Python 字體反爬系列文章,我們又進入了一個新的主題,常見混淆加密原理與實踐。
本篇博客從 eval
混淆開始,逐層為大家拆解 JS 逆向中混淆相關知識。
eval 函數可以將 JS 字符串解析成源碼執行
在搜索引擎隨機選擇可進行加密 JS 代碼的頁面,然後加密下述內容。
加密前
var name = "橡皮擦";
加密後
eval(
(function (p, a, c, k, e, d) {
e = function (c) {
return (
(c < a ? "" : e(parseInt(c / a))) +
((c = c % a) > 35 ? String.fromCharCode(c + 29) : c.toString(36))
);
};
if (!"".replace(/^/, String)) {
while (c--) d[e(c)] = k[c] || e(c);
k = [
function (e) {
return d[e];
},
];
e = function () {
return "\\w+";
};
c = 1;
}
while (c--)
if (k[c]) p = p.replace(new RegExp("\\b" + e(c) + "\\b", "g"), k[c]);
return p;
})('1 0 = "橡皮擦"', 62, 2, "name|var".split("|"), 0, {
})
);
可以看到加密之後的代碼變得更加復雜,並且可讀性變弱。
在 JS 中,eval
函數本身就是一個 JS 代碼執行器,它可以將傳入的字符串按照 JS 語法進行解析並執行。
解密 eval 函數的方式比較簡單,直接找工具。
該形式代碼最常見的場景就是百度的統計代碼,具體案例你可以尋找一下。
本次我們要采集的站點是電視貓,目標地址為:https://www.tvmao.com/program/BTV1
。
在該頁面點擊更多之後,會加載節目列表數據,得到的接口與參數如下所示。
通過查看更多,我們可以抓取到數據請求位置。
伴隨斷點,我們進入到 JS 逆向環節,得到的第一段代碼如下所示。
$(".more-epg").click(function () {
var b = "src";
var a = A.d("a", b);
ajaxVerify(
"/api/pg",
"GET",
{
p: a,
},
function (c, d) {
$("#noon").after(d[1]);
$(".more-epg").remove();
}
);
});
代碼中比較核心的是 A.d("a", b)
,其中函數 d()
可能是加密環節。
接下來就是重點內容了,我們並沒有找到加密函數所在的 JS 文件,該 JS 代碼段是臨時的,或者稱為匿名的。
但是關鍵字 _keyStr
是可以直接被檢索到的,全局搜索一下,得到如下內容。
順著 base.js
爬過去,找到如下內容,發現 eval 函數,混淆點出現了。
所有的 eval
函數包裹的代碼,都可以使用 console.log
進行打印。
可以看到混淆前後的代碼差異,解析之後恰巧是我們的目標函數。
也可以搜索反混淆工具,直接查詢即可,反混淆的時候,注意攜帶 eval()
函數,其中內容可以自己多次測試。
當我們得到原函數時,基本表示加密邏輯已經解決了。
最後在補充一點
當你發現【匿名】函數時,大概率這段 JS 是加密過的字符串。
你正在閱讀 【夢想橡皮擦】 的博客
閱讀完畢,可以點點小手贊一下
發現錯誤,直接評論區中指正吧
橡皮擦的第 683 篇原創博客