前言:
本文章仅供交流学习使用,请勿用于非法用途,若侵权,请联系作者删除
一.简介
1. 瑞数
瑞数动态安全 Botgate(机器人防火墙)以“动态安全”技术为核心,通过动态封装、动态验证、动态混淆、动态令牌等技术对服务器网页底层代码持续动态变换,增加服务器行为的“不可预测性”,实现了从用户端到服务器端的全方位“主动防护”,为各类 Web
2. 瑞数执行流程分析
我们在做逆向的时候,首先得分析出哪些加密参数
是需要逆向的,然后再是去逆向这些参数。当然瑞数也是一样。 所以我们第一步就是明确逆向的目标
:
-
现象:上了rs的网站会请求两次page_url,第二次请求page_url时才能得到正确的页面内容;
-
分析:分析其请求体,发现第二次请求page_url时带上了cookie_s和cookie_t, 而cookies_s是来自第一次请求page_url时其响应头set的;
3.执行流程
这里我们需要关注eval调用
的位置(也就是VM的入口
),cookie生成的位置。
注:浏览器
v8
调用eval
执行代码时会开启一个虚拟机(VM
+数字)去执行JavaScript代码。
二.瑞数4
1. 逆向目标
-
目标地址 : aHR0cDovL3d3dy5mYW5nZGkuY29tLmNuL2luZGV4Lmh0bWw=
-
逆向参数:
FSSBBIl1UgzbN7N80T
2. 瑞数4特点
-
debugger: 两次
-
key名字:
FSSBBIl1UgzbN7N80T
是js代码生成,FSSBBIl1UgzbN7N80S
是服务器返回
3. 逆向分析
-
过无限debugger
var _constructor = constructor;
Function.prototype.constructor = function(s) {
if (s == "debugger") {
console.log(s);
return null;
}
return _constructor(s);
}
var _constructor = constructor;
Function.prototype.constructor = function(s) {
if ( s== "debugger") {
console.log(s);
return null;
}
return _constructor(s);
}
//去除无限debugger
Function.prototype.__constructor_back = Function.prototype.constructor ;
Function.prototype.constructor = function() {
if(arguments && typeof arguments[0]==='string'){
//alert("new function: "+ arguments[0]);
if( "debugger" === arguments[0]){
// arguments[0]="consoLe.Log(\"anti debugger\");";
//arguments[0]=";";
return
}
}
return Function.prototype.__constructor_back.apply(this,arguments);
};
var _Function = Function;
Function = function(s) {
if (s == "debugger") {
console.log(s);
return null;
}
return _Function(s);
}
-
hook对应cookie生成的位置
(function () {
// 严谨模式 检查所有错误
'use strict';
// document 为要hook的对象 这里是hook的cookie
var cookieTemp = "";
Object.defineProperty(document, 'cookie', {
// hook set方法也就是赋值的方法
set: function (val) {
// 这样就可以快速给下面这个代码行下断点
// 从而快速定位设置cookie的代码
if (val.indexOf('FSSBBIl1UgzbN7N80T') != -1) {
debugger;
}
console.log('Hook捕获到cookie设置->', val);
cookieTemp = val;
return val;
}, // hook get 方法也就是取值的方法
get: function () {
return cookieTemp;
}
});
})();
-
可以看到cookie的生成位置,
-
是有
$FG
函数调用生成的,执行的代码是在vm
文件当中 -
vm
文件在瑞数当中都是通过eval
生成的,可以网上找到他执行eval
的位置
-
往下面的栈进行查找可以找到入口文件
-
这个文件就是瑞数第一次请求返回412状态码的页面
-
那我们就需要把这个页面的代码拿下来我们自己执行,获取的方法是一个自执行方法
-
需要把这个文件的外链js代码也拿过来,一般是一个ts数据的js文件
-
要进外链js文件的话,需要通过抓包工具的脚本功能
-
那下来之后我们就可以补环境了
4.逆向结果
import requests
import re
import execjs
from lxml import etree
requests = requests.session()
headers = {
'Host': '脱敏处理',
'Referer': '脱敏处理',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36',
}
url = '脱敏处理'
def first_request():
response = requests.get(url, headers=headers)
obj_html = etree.HTML(response.text)
content_data = obj_html.xpath('//meta[2]/@content')[0]
func_code = obj_html.xpath('//script[2]/text()')[0]
return content_data, func_code
def second_request():
content_data, func_code = first_request()
# print(content_data, func_code)
with open('1111.js', encoding='utf-8') as f:
js_code = f.read().replace('content_data', content_data).replace("'func_code'", func_code)
# print(js_code)
js = execjs.compile(js_code)
cookies = {'FSSBBIl1UgzbN7N80T': js.call('get_cookie').split(';')[0].split('=')[-1]}
# print(cookies)
res = requests.get(url, headers=headers, cookies=cookies)
print(res.request.headers)
print(res)
# second_request()
second_request()
若需要源码请联系作者获取。
aHVhcXUwNzI3
(懂得都懂。嗯)