本文中所有内容仅供学习交流使用,不用于其他任何目的,不提供完整代码,敏感网址、数据接口等均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关!
本文未经许可禁止转载,禁止任何形式的修改后进行二次传播,若有侵权,请联系作者删除!
网站:aHR0cHM6Ly93d3cubXBzLmdvdi5jbi9pbmRleC5odG1s
加速乐的特点是一般有三次请求:
根据加速乐的特点,思路分为以下三点:
先对目标网站抓个包分析一下,可以看到请求同一个页面发生了三次请求,前两次都是返回521状态码,最后一次是200,符合加速乐特征
点击第一次请求,我们看到服务器给我们返回了cookie参数__jsluid_s,但响应内容无法看到,这时可以使用fiddler抓包工具查看,是一段混淆后的内容
我们把响应内容拿出来,粘贴到notepad++,内容大致是一个经过AAEncode混淆的cookie
直接拿出document.cookie等号后的值控制台输出一下,果然是一段cookie,在Python中可以使用execjs.eval()解混淆(可以使用正则将混淆的cookie提取出来)
点击查看第二次请求,返回的也是一段混淆的
这里我也不知道怎么解混淆,参考了下K哥的教程,提到了两种方法,一种是本地替换,一种是hook,我这里直接就选择了hook方法,使用了编程猫插件
//当前版本hook工具只支持Content-Type为html的自动hook
//下面是一个示例:这个示例演示了hook全局的cookie设置点
(function() {
//严谨模式 检查所有错误
'use strict';
//document 为要hook的对象 这里是hook的cookie
var cookieTemp = "";
Object.defineProperty(document, 'cookie', {
//hook set方法也就是赋值的方法
set: function(val) {
if(val.indexOf("__jsl_clearance_s") != -1){
debugger;
}
//这样就可以快速给下面这个代码行下断点
//从而快速定位设置cookie的代码
console.log('Hook捕获到cookie设置->', val);
cookieTemp = val;
return val;
},
//hook get方法也就是取值的方法
get: function()
{
return cookieTemp;
}
});
})();
可以看到成功hook到cookie参数__jsl_clearance_s
下面开始跟栈调试,在这里设置了cookie
找到了cookie生成的位置是下面这段代码
var _0x2cb0e1 = _0x293413[_0x5c39('0x4b', 'fbqw') + 'c'](_0x1ab968['tn'] + '=' + _0x1f2023[0x0] + (_0x5c39('0xab', 'FMv#') + _0x5c39('0x75', '%^JY') + '=') + _0x1ab968['vt'], _0x293413[_0x5c39('0x94', 'aZ9(') + 'o']);
将这段代码优化下,发现cookie由_0x1f2023[0x0]生成,继续跟栈调试,找到_0x1f2023[0x0]的生成位置是如下代码
var _0x1f2023 = _0x293413[_0x5c39('0x35', '34sA') + 'R'](_0x47a5cd, _0x1ab968['ct'], _0x1ab968[_0x5c39('0xfe', '7oIp')]);
先将代码本地保存一份到notepad++,因为该js代码是动态变化的,方便我们调试。我们直接在开发者工具新建代码片段进行调试,记得清除cookie再断点调试
经过调试发现,cookie参数由如下代码生成,其关键处是hash函数,当hash函数加密后的数据等于_0x393bf1时,返回cookie参数的值
function _0x47a5cd(_0x393bf1, _0xf58bf1) {
var _0x15efa8 = {};
_0x15efa8[_0x5c39('0xae', 'm$PE') + 'S'] = function(_0x555149, _0x3f2144, _0x255dc1) {
return _0x555149(_0x3f2144, _0x255dc1);
}
;
_0x15efa8[_0x5c39('0x5a', '#2#0') + 'Z'] = function(_0x9f6fcd, _0x54edcc, _0x37d23d) {
return _0x293413[_0x5c39('0x5c', '(aB&') + 'h'](_0x9f6fcd, _0x54edcc, _0x37d23d);
}
;
var _0x283d83 = _0x15efa8;
if (_0x293413[_0x5c39('0x104', 'swkp') + 'k'] !== _0x293413[_0x5c39('0xd7', '*)&)') + 'k']) {
a = _0x283d83[_0x5c39('0xf4', '%^JY') + 'S'](AddUnsigned, a, _0x283d83[_0x5c39('0x6b', '2Qrn') + 'Z'](AddUnsigned, AddUnsigned(F(b, c, d), x), ac));
return _0x283d83[_0x5c39('0x1e', 'fbiV') + 'Z'](AddUnsigned, RotateLeft(a, s), b);
} else {
var _0x3c0e1f = _0x1ab968[_0x5c39('0x7e', 'Q#%8') + 's'][_0x5c39('0xfd', 'w[O^') + 'th'];
for (var _0x14a05f = 0x0; _0x293413[_0x5c39('0x121', '62a0') + 's'](_0x14a05f, _0x3c0e1f); _0x14a05f++) {
for (var _0x56321d = 0x0; _0x56321d < _0x3c0e1f; _0x56321d++) {
var _0x1919fd = _0xf58bf1[0x0] + _0x1ab968[_0x5c39('0x129', '72K6') + 's'][_0x5c39('0xbc', '#2#0') + 'tr'](_0x14a05f, 0x1) + _0x1ab968[_0x5c39('0xf2', 'Zw9a') + 's'][_0x5c39('0xf8', '!Y%v') + 'tr'](_0x56321d, 0x1) + _0xf58bf1[0x1];
if (_0x293413[_0x5c39('0x4e', '%^JY') + 'A'](hash(_0x1919fd), _0x393bf1)) {
return [_0x1919fd, _0x293413[_0x5c39('0x72', '7XT8') + 'i'](new Date(), _0x534ce4)];
}
}
}
}
}
调试这段代码可以发现里面所用参数来自go函数传入,并且hash函数所使用的加密方法是动态变化的,由go["ha"]决定,有三种加密方式md5、sha1、sha256,找个在线网站或者编程猫插件可以验证hash函数是标准的加密方式,直接调用crypto-js库实现算法
go = {
"bts": ["1699759180.198|0|gI4", "2F4ybqrb3R3XniRZUgcbpvJI%3D"],
"chars": "IVwNuGnmmWkymG%lYdqCqQ",
"ct": "6f455c7207ae7bdee69232d4b9df739f",
"ha": "md5",
"is": true,
"tn": "__jsl_clearance_s",
"vt": "3600",
"wt": "1500"
}
const CryptoJs = require("crypto-js");
function hash(type, value){
if(type == "md5"){
return CryptoJs.MD5(value).toString();
}
if(type == "sha1"){
return CryptoJs.SHA1(value).toString();
}
if(type == "sha256"){
return CryptoJs.SHA256(value).toString();
}
}
cookie逆向已经完成,直接编写Python代码进行请求,验证是否可用
# @Time : 2023/11/11 16:18
# @Author : 车厘子
# @Software: PyCharm
import re
import json
import execjs
import requests
from loguru import logger
url = ''
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36',
}
cookies = {}
def get_first_cookie():
global cookies
response = requests.get(url, headers=headers)
# 获取 cookie 值 __jsluid_s
cookies.update(response.cookies)
# 获取第一层响应内容, AAEncode 加密
AAEncode_text = re.search('document.cookie=(.*?);location', response.text).group(1)
__jsl_clearance_s = execjs.eval(AAEncode_text).split(";")[0]
# 获取 cookie 值 __jsl_clearance_s
cookies["__jsl_clearance_s"] = __jsl_clearance_s.split("=")[1]
def get_second_cookie():
global cookies
# 通过携带 __jsluid_s 和 __jsl_clearance_s 值的 cookie 获取第二层响应内容
response = requests.get(url, headers=headers, cookies=cookies)
go_params = re.findall(';go\((.*?)\)', response.text)[0]
go_params = json.loads(go_params)
return go_params
def get_response_data(go_params):
global cookies
__jsl_clearance_s = execjs.compile(open("__jsl_clearance_s.js","r", encoding="utf-8").read()).call("get__jsl_clearance_s",go_params)
cookies["__jsl_clearance_s"] = __jsl_clearance_s
response = requests.get(url, headers=headers, cookies=cookies)
response.encoding = "utf-8"
logger.success(response.text)
def main():
get_first_cookie()
go_params = get_second_cookie()
get_response_data(go_params)
if __name__ == '__main__':
main()
完美通过!