⛳️ 前置知识
历经 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
。
在该页面点击更多之后,会加载节目列表数据,得到的接口与参数如下所示。
- 请求网址: www.tvmao.com/api/pg?p=加密…
- 请求形式:GET
通过查看更多,我们可以抓取到数据请求位置。
⛳️ 电视猫 实战场景
伴随断点,我们进入到 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 是加密过的字符串。
⛳️ 掌房买好房实战场景
本篇博客要盘的目标站点是【掌房买好房】登录页加密逻辑,提前访问 http://eip.chanfine.com/login.jsp
做一下接口分析。
随机写入一个账号和密码,测试加密接口。
- 账号:15012341234
- 密码:123456
通过开发者工具查看到接口参数如下所示。
- 请求网址: eip.chanfine.com/j_acegi_sec…
- 请求方法: POST
其中加密位置呈现如下内容。
- j_username: 15012341234
- j_password: 䐵匠䴵 N3IRFNdustKHXjJ5PDrZIQ==
- j_redirectto:
其中比较重要的就是 j_password
,我们要解析的位置也在这里。
⛳️ 加密参数寻找过程
直接全局搜索关键字 j_password
即可查询对应值。
直接定位到检索结果中的 desEncrypt
函数位置,得到下述内容。
鼠标移动到加密函数位置,发现出现 VM 相关内容,这里就可以初步猜测其使用的是 eval
函数加密。
直接跳转到对应代码部分,其实已经得到了相关逻辑,参考着下述代码编写 Python 代码就可以完成任务,但这与我们一开始学习 eval 逆向相违背。
function desEncrypt(value, xForm, type) {
if (_0(xForm)) {
return value;
} else {
var keyObj = {};
if (type == null || "aes" == type.toLowerCase()) {
keyObj = SECURITYKEY.get();
value = CryptoJS.AES.encrypt(value, CryptoJS.enc.Utf8.parse(keyObj.key), {
iv: CryptoJS.enc.Utf8.parse(keyObj.iv),
}).toString();
} else {
keyObj = SECURITYKEY.get("des");
value = CryptoJS.DES.encrypt(value, CryptoJS.enc.Hex.parse(keyObj.key), {
iv: CryptoJS.enc.Hex.parse(keyObj.iv),
});
}
return keyObj.security + value;
}
}
从上述代码提炼关键字 SECURITYKEY
,在全局代码再次检索。
结果中发现了加密函数真实位置,并且明显的 eval
痕迹。
既然已经找到代码源头,接下来就可以找一款在线解密工具,实施解析即可。
📢📢📢📢📢📢 💗 你正在阅读 【梦想橡皮擦】 的博客 👍 阅读完毕,可以点点小手赞一下 🌻 发现错误,直接评论区中指正吧 📆 橡皮擦的第 685 篇原创博客
- 我正在参与掘金技术社区创作者签约计划招募活动,点击链接报名投稿。