网址: aHR0cDovL3d3dy5jaGluYXN0b2NrLmNvbS5jbi9uZXdzaXRlL2Nncy1zZXJ2aWNlcy9zdG9ja0ZpbmFuY2UvYnVzaW5lc3NBbm5jLmh0bWw=
本期教学需要你有一点瑞数的基础,js过瑞数无非是扣代码(注意保护好头发)和补环境,不懂的可以看我往期的教程,js逆向之补环境过瑞数4.0 某房地产,尽量一遍带你理清瑞数的流程.同时推荐多去看看k哥的博客k哥爬虫.下期更新加速乐.
补环境与扣代码区别:
对于js逆向
来说,这是两种常规且实用的手段,也各有优劣势;不管使用哪种方式,我们都是先从网站中将加密JS代码扣出,然后再选择是继续扣代码,将使用到的浏览器环境api
进行逻辑替换;还是使用补环境,让加密JS代码仿佛在浏览器环境中运行。
总而言之,扣代码
侧重js语法和代码逻辑,其熟练度依赖于逆向经验,对不同网站要扣的不一样,难以通用,人工效率低,但是程序执行效率高。补环境
侧重原型链及浏览器环境模拟,熟练度几乎只依赖对JS的原理掌握程度,对于不同网站补的越多可通杀的网站越多,人工效率巨高,但是程序执行效率不高。
本期教学将带大家补环境过5.0,事实上4.0也差不多
引用某博主的一段话
瑞数动态安全 Botgate(机器人防火墙)以“动态安全”技术为核心,通过动态封装、动态验证、动态混淆、动态令牌等技术对服务器网页底层代码持续动态变换,增加服务器行为的“不可预测性”,实现了从用户端到服务器端的全方位“主动防护”,为各类 Web、HTML5 提供强大的安全保护。瑞数 Botgate 多用于政企、金融、运营商行业,一度被视为反爬天花板.目前版本4.0,5.0,6.0,本章针对5.0 ,与4.0有点区别,但本质是一样的,目标网站的结构:
1. 一个meta标签,其content内容很长且是动态
的(每次请求会变化),会在eval执行第二层JS代码时使用到;
2. 一个script标签(与4代不同的是这里不是一个自执行函数,外链js文件里才有.call方法,4代的是.call在自执行函数里),里面的属性需要提供给外链js文件来生成加密参数(每次请求首页都会动态
变化)
3. 一个外链js文件(自执行函数,与4代完全不同,像是两个调换了一下顺序,4代的自执行函数在html中,属性在外链js中,5代巧好相反,补环境需要注意,扣代码的话不用管,直接扣VM里面的再替换),一般同一页面中其内容是固定
的,.call方法在里面,会也生成第二层VM代码
4.生成WT这个cookie再带上第一次请求返回的3个cookie,注意:4.0有一个生成假cookie的过程,扣代码的话要注意真假cookie,如果是补环境的话可以不用管,直接调用最后生成的document.cookie即可.5代没有
1.找到cookie的生成位置,可以hook cookie的生成位置,油猴,fiddler,浏览器插件都行. 注意: hook前把浏览器的cookie缓存清空,否则可能会hook不到(之前忘讲了)
(function() {
'use strict';
var cookieTemp = '';
Object.defineProperty(document, 'cookie', {
set: function (val) {
debugger;
console.log('Hook捕获到cookie设置->', val);
cookieTemp = val;
return val;
},
get: function () {
return cookieTemp;
},
})
})();
2.往上跟栈,定位到生成VM的位置,通常是VM下面的那几个栈,找到.call方法,5.0,6.0可能会混淆,仔细观察一下就能找到,此时你注意到没有它整体是一个js文件,没有我们要的content和自执行函数
3.这里hook就失效了,不过也别担心,办法总比困难多,客户端拥有浏览器最高解释权,我们可以在源面板页面打开事件监听器,把脚本勾上,如图,然后一步步点击下一步定位到html中
5.继续开启事件监听器,因为你在静态代码里下断点你会发现断不住的,你使用事件监听器的时候应该发现了会提前开启一个VM的html,之后就会调用外链js里的.call,然后才会出现含content的html文件,所以这里需要你在调用外链js的时候直接进去函数里面找到.call方法,可能会混淆,这里并没有,混淆的话你只能解混淆或者凭经验找了.完成上述一系列操作之后,你就可以试着在本地调试js补环境了,遇到了函数未定义直接进VM里去找就行了
1. 先把基本的东西写好 proxy(吐环境脚本)这里就不详细介绍了,感兴趣的可以自行网上搜索怎么自吐的,脚本有需要的可以联系我.
2.接下来先把一些基础的环境加上,比如,window=global;document= {};location直接去浏览器copy(location)一个,navigator就是你的浏览器信息,也是直接去浏览器copy一个,一般是固定的
location = {
"ancestorOrigins": {},
"href": "http://www.脱敏处理/newsite/cgs-services/stockFinance/businessAnnc.html",
"origin": "http://www.脱敏处理",
"protocol": "http:",
"host": "www.脱敏处理",
"hostname": "www.脱敏处理",
"port": "",
"pathname": "",
"search": "",
"hash": ""
}
navigator = {
userAgent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36",
languages: ["zh-CN", "zh"],
appVersion: "5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36",
webdriver: false,
appName: "Netscape",
vendor: "Google Inc.",
}
3. 补上后先尝试运行一下,不出意外会报错,因为window,和document两个还缺了比较多的环境
4.果然报了一个top未定义,这也是比较经典的一个环境,直接补上window.top = window,然后再运行一下
5. 发现node一直跑,整个程序没有停下来的意思,此时就要注意了,可能是触发了定时器,此时最好是马上把node关闭,不然你的电脑一直跑着你电脑的小风扇就会不停的吹啊吹,可以提前置空,置空后再补上上面的两个undefined
window.setInterval = function (){console.log(arguments)}
window.setInterval = function (){console.log(arguments)}
document.appendChild = function (){console.log(arguments)}
document.removeChild = function (){console.log(arguments)}
6. 此时接着运行代码,报了一个方法未定义,往上滑发现断在document.createElemnet
7. 接着去浏览器里调试,有多个,全部打上断点后仔细调试就行了
div = {getElementsByTagName(val){
if(val==='i'){ return {length :0}}
}}
document.createElement = function (val){if(val==='div'){return div} if (val === 'form'){
return {}
} if (val === 'a'){
return {}
}}
8. 接着跑,又报了一个document.getElementsByTagName未定义,往下滑看看,发现有个函数未定义,
9.去浏览器里找,发现正是上面的document.getElementsByTagName,给它补上
document.getElementsByTagName = function (val){
return [
{
content:content,
parentNode:{
removeChild:function (){}
},
parentElement : {
removeChild:function (){}
}
},
{
content:content,
parentNode:{
removeChild:function (){}
},
parentElement : {
removeChild:function (){}
}
}
]
}
10.再次运行,发现报了相同的错,说明我们补的不全,接着去浏览器里调试会发现还要补以下代码,可以去看看js逆向之补环境过瑞数4.0 某房地产里面有提到过
Object.prototype.getAttribute = function (val){
console.log('getAttribute', arguments)
if(val === 'r') {
return 'm';
}
}
11.补完后再次运行发现有少了两个未定义,无奈补上,要有耐心哈,逆向本来就是很难的
window.addEventListener = function (){console.log(arguments)}
window.attachEvent = function (){console.log(arguments)}
12.应该差不多了,再次运行,结果也是成功出来了,最后再在pycharm里跑一下,也是成功拿到数据了. 提一点,实现的语言不重要,Java,go都行,关键是逆向的思路.
1整个逆向过程耗时半天,很多环境直接拿4.0的就能直接用,再结合浏览器来调试稍微修改一下就行了. 整体看上去好像过程很多,其实不然,因为很多环境都是一样的,也正好映衬了开头讲的,补环境是通用的,补的越多,可通杀的网站就越多.逆向说难可以很难,难到无法下手,说简单,好吧说不出口,哈哈.多加练习把.
2出于安全考虑,本章未提供完整流程,调试环节省略较多,只提供大致思路,具体细节要你自己还原,相信你也能调试出来.
3本人写作水平有限,如有讲解不到位或者讲解错误的地方,还请各位大佬在评论区多多指教,共同进步.技术探讨加本人v lyaoyao__i(两个_,本人)