说明:仅供学习使用,请勿用于非法用途,若有侵权,请联系博主删除
作者:zhu6201976
一、 反爬分析
url:aHR0cHM6Ly9uZXdob3VzZS4wNTU3ZmRjLmNvbQ==
该站点项目url通过点击JS生成,project_id与生成后的结果完全不同,且通过生成后的结果进行访问、有时效性。例如:project_id=3362,生成结果:0984-18052-9217-2406976066313,最终通过 https://{hostname}/item/0984-18052-9217-2406976066313 进行访问。
如果请求过期url,则返回空结果。为何url需要动态生成呢?
有一种可能,就是防止爬虫程序轻易解析提取数据,对网站造成压力,同时保护网站珍贵的数据不被轻易窃取。当然,动态生成的url,因有时效性,也能防止数据库长期存储和分享。
我们知道,无论再复杂的程序和代码,底层都有严谨的实现逻辑。网站采用BS架构,客户端代码运行在浏览器中,这就意味着,代码是可见的,甚至还能被调试!这对网站开发人员而言,隐藏了巨大的风险。无论客户端代码多复杂、混淆多严重,最终都有被逆向分析的可能,只是时间问题。
既然没有绝对的安全,无法彻底防御风险,那么,只能将客户端程序尽可能复杂化,让爬虫程序难以模拟,或者模拟成本非常高,从而望而生畏,主动放弃。加密算法是复杂化的一个重要途径,按时间分有古代密码学、现代密码学;按实现方式分有自定义算法、通用算法等。
那么,它是如何实现的呢?采用了什么样的加密算法?
1. 首先,访问项目首页,返回document文档,项目通过a标签进行项目列表展示。
a标签属性id即project_id,它通过绑定对应的点击事件函数reurl(this),点击后a标签作为参数进行传递,最后JS生成加密结果,再给a标签设置href属性实现url的动态生成。
a标签点击前:
a标签点击后:
2. 其次,在项目的首页,添加了大量待执行JS外链。
如图所示:
点击事件函数reurl大概率在上述外链JS中。依次访问上述JS外链,并在返回的JS中全局搜索关键词reurl,成功定位到文件lanrenzhijia.js。
项目详情url动态生成逻辑就在此处。
3. 加密逻辑都是在虚拟机中执行的。
function reurl(a) {a.href = "/item/" + recode(a.id)
}
;
recode函数具体实现:
function recode(a) {var n = nscaler(a);var c = SetObjNum(a.length);var d = SetObjNum(a.length);n = parseInt(n) + parseInt(d);var b = $("#iptstamp").val();b = nscaler(b.toString());return c + "-" + n + "-" + d + "-" + b
}
nscaler函数具体实现:
function nscaler(a) {var b = "";$.each(a, function(i, e) {switch (e) {case "0":b += "0";break;case "1":b += "2";break;case "2":b += "5";break;case "3":b += "8";break;case "4":b += "6";break;case "5":b += "1";break;case "6":b += "3";break;case "7":b += "4";break;case "8":b += "9";break;case "9":b += "7";break}});return b
}
这个函数通过古代密码学凯撒加密,对输入的数字依次进行偏移,从何达到简单加密的结果。
setObjNum函数具体实现:
function SetObjNum(n) {var a = "";for (var i = 0; i < n; i++)a += Math.floor(Math.random() * 10);return a
}
这个函数通过简单的随机数,对结果进行进一步的混淆。
iptstamp变量来源:
在document文档中定义,是一个时间戳。
通过上述凯撒加密、随机数、时间戳拼接后,得到最终结果:/item/0984-18052-9217-2406976066313
那么,服务端是如何识别加密结果并做到过期处理的呢?
nscaler函数是加密算法的核心也是服务端能够还原的关键,对于每个数字,偏移量是固定的。所以服务端可以根据偏移量,依次减法,即可还原原始project_id。而iptstamp时间戳是判断url失效的关键。
当然,最后我们扣取整理的JS代码,不一定能够正常运行,需要根据代码逻辑,适当修改调整,以下是整理后的最终可执行JS代码:
function SetObjNum(n) {var a = "";for (var i = 0; i < n; i++)a += Math.floor(Math.random() * 10);return a
}function nscaler(a) {var b = "";// $.each(a, function(i, e) {for (let i = 0; i < a.length; i++) {switch (a[i]) {case "0":b += "0";break;case "1":b += "2";break;case "2":b += "5";break;case "3":b += "8";break;case "4":b += "6";break;case "5":b += "1";break;case "6":b += "3";break;case "7":b += "4";break;case "8":b += "9";break;case "9":b += "7";break}}return b
}function recode(a, b) {var n = nscaler(a);var c = SetObjNum(a.length);var d = SetObjNum(a.length);n = parseInt(n) + parseInt(d);// var b = $("#iptstamp").val();b = nscaler(b.toString());return c + "-" + n + "-" + d + "-" + b
}function reurl(a, b) {let a_href = "/item/" + recode(a.id, b);return a_href;
}var ret = reurl({"id": '3362'}, 1704894044656);
console.log(ret);
二、 完整代码
项目已开源,请访问github获取,期待你的一键三连、star、交流。
github项目地址:GitHub - zhu6201976/newhouse20240111: JS逆向实战案例1——某房地产url动态生成
项目运行完整截图: