某信用中心之加速乐实战分析

news2024/9/24 1:24:57

某信用中心之加速乐实战分析

  • 某信用中心之加速乐实战分析
    • 声明
    • 逆向目标
    • 逆向分析
      • 第一层cookie获取
      • 第二层cookie获取
      • 调试分析JS文件
    • 模拟执行
      • 致谢

某信用中心之加速乐实战分析

声明

本文章中所有内容仅供学习交流,抓包内容、敏感网址、数据接口均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关,若有侵权,请联系我立即删除!

逆向目标

在这里插入图片描述

逆向分析

通过打开F12抓包查看是否存在加密参数

发现我们需要的数据在xhr请求中

在这里插入图片描述

再查看标头和负载,初步看好像没有加密参数,所以我们直接发送request请求尝试能不能获取到数据。

在这里插入图片描述
在这里插入图片描述

发送请求后发现返回一个js文件

在这里插入图片描述

如果有了解过的同学就知道,这是加速乐cookie反爬虫,是知道创宇推出的一款网站CDN加速、网站安全防护平台。

加速乐的特点是访问网站一般有三次请求:

  1. 第一次请求网站,网站返回的响应状态码为 521,响应返回的为经过 AAEncode 混淆的 JS 代码;
  2. 第二次请求网站,网站同样返回的响应状态码为 521,响应返回的为经过 OB 混淆的 JS 代码;
  3. 第三次请求网站,网站返回的响应状态码 200,即可正常访问到网页内容。

我们可以在网页中清除cookie后再尝试抓包查看是否和我们上述所说

在这里插入图片描述

接下来就是重点分析这三个cookie文件

第一层cookie获取

直接查看 response 是显示无响应内容的,所以我们通过之前发送请求包中返回的响应包代码进行分析

在这里插入图片描述

分析响应包,可以看到第一个xyxx-list.do返回的响应内容经过 AAEncode 加密,大致内容如下,可以看到一堆颜表情符号,还挺有意思的:

<script>document.cookie=('_')+('_')+('j')+('s')+('l')+('_')+('c')+('l')+('e')+('a')+('r')+('a')+('n')+('c')+('e')+('_')+('s')+('=')+(-~{}+'')+(6+'')+(3+6+'')+(~~[]+'')+(2+4+'')+(2+6+'')+(([2]+0>>2)+'')+((1+[4]>>1)+'')+((1<<2)+'')+(9+'')+('.')+(1+[0]-(1)+'')+((2<<1)+'')+(1+[0]-(1)+'')+('|')+('-')+(-~0+'')+('|')+('I')+('G')+('j')+('P')+(4+4+'')+('l')+('r')+('j')+('q')+('T')+('P')+('y')+('q')+('v')+('O')+('i')+(4+4+'')+('N')+('i')+('n')+('G')+('B')+('O')+('f')+('r')+('k')+('s')+('%')+(1+2+'')+('D')+(';')+('m')+('a')+('x')+('-')+('a')+('g')+('e')+('=')+(1+2+'')+(3+3+'')+(~~[]+'')+(~~{}+'')+(';')+('p')+('a')+('t')+('h')+('=')+('/');location.href=location.pathname+location.search</script>

document.cookie 里的颜表情串实际上是第一次 __jsl_clearance_s 的值,可以直接通过正则提取到加密内容后,使用execjs.eval()方法即可得到解密后的值:

import re
import execjs

js_clearance = re.findall('cookie=(.*?);location',response.text)[0]
jsl_clearance_s  = execjs.eval(js_clearance).split(';')[0]
print(jsl_clearance_s)

// __jsl_clearance_s=1690686292.777|-1|uzTU5s0inLnvhCVdFmuyRXtr69k%3D

在这里插入图片描述

第二层cookie获取

第二层cookie获取可以直接查看第一个xyxx-list.do的响应包,或者通过第一层cookie获取后的__jsl_clearance_s __jsluid_s两个cookie参数发包请求,也能获得对应响应代码,如图所示

在这里插入图片描述

在这里插入图片描述

将文件复制出来分析后发现是一个经过 OB 混淆的 JS 文件,我们需要对其进行调试分析,所以我们首先需要寻找找这个js代码的加密位置,先清除本地浏览器的cookie。

在这里插入图片描述

然后在源代码中勾选住脚本,这样网页执行的每一个js文件都会被我们断住了,当然也可以使用hook注入等方式寻找加密位置

在这里插入图片描述

刷新网页,然后不断进行F8往下,我们首先会看到我们之前分析过的第一个cookie文件,继续F8往下走

在这里插入图片描述

成功找到我们所需要的js文件

在这里插入图片描述

调试分析JS文件

由于网站是cookie加密,所以每次刷新JS文件的一些参数都是在动态变换的,所以我们可以使用本地替换的方式固定一套下来再进行调试。然后在该 JS 文件中通过 CTRL + F 搜索 document,只有一个,在第 596 行打断点调试,选中_0x1739('0x93', '3R@K') + 'ie'后进入控制台输入会发现这里就是 cookie 经过混淆后的样式:
在这里插入图片描述

在这里插入图片描述

将等号后面的内容全部选中,进入控制台输入可以发现,这里生成了 Cookie 中 __jsl_clearance_s 参数的值:

在这里插入图片描述

至此,我们知道了 Cookie 生成的位置,接下来就需要了解其加密逻辑和加密方法,然后通过 python 对其进行复现了,document 部分完整的代码如下:

document[_0x1739('0x93', '3R@K') + 'ie'] = _0x3fa957[_0x1739('0x9b', '9PBK') + 'W'](_0x3fa957[_0x1739('0x43', '7C)&') + 'W'](_0x3fa957[_0x1739('0xbc', 'ML*i') + 'X'](_0x3fa957[_0x1739('0x37', 'tfb]') + 'X'](_0x5a3a5f['tn'] + '=', _0x4bca4c[0x0]), _0x1739('0x114', '@XV)') + _0x1739('0x10f', ')!ai') + '='), _0x5a3a5f['vt']), _0x1739('0x20', '711Q') + _0x1739('0xda', 'R2lr') + '\x20/');

这里等号后面的内容比较冗杂,其实我们想要获取的是 jsl_clearance_s 参数的值,通过逐步分析调试可以看到其值由(_0x5a3a5f['tn'] + '=', _0x4bca4c[0x0])生成:

在这里插入图片描述

继续分析可知_0x5a3a5f['tn']对应的部分是__jsl_clearance_s,而其值是_0x4bca4c[0x0],因此我们需要进一步跟踪 _0x4bca4c 生成的位置。

在这里插入图片描述

通过搜索,在第 587行可以找到其定义生成的位置,打断点调试可以看到,_0x4bca4c[0x0]其实就是取了 _0x4bca4c 数组中的第一个位置的值:

在这里插入图片描述

我们来进一步分析 _0x4bca4c 后面代码各自的含义,完整代码如下

_0x3fa957[_0x1739('0x11', '3)Nv') + 'V'](_0x29f4ef, _0x5a3a5f['ct'], _0x5a3a5f[_0x1739('0x68', '&GmG')]);

通过控制台可知_0x3fa957[_0x1739('0x11', '3)Nv') + 'V']取的是后面参数中第一个参数当做函数体,第二和第三个值当做参数传入。
在这里插入图片描述

_0x5a3a5f['ct'])取的是 go 函数传入的字典中 ct 参数的值:

在这里插入图片描述
在这里插入图片描述

分析可知将_0x5a3a5f[_0x1739('0x68', '&GmG')]数组中的值按照某种规则进行拼接就是 __jsl_clearance_s 参数的值,并且_0x1739('0x68', '&GmG')对应字典中 bts 的值:
在这里插入图片描述

所以需要进一步跟踪 _0x29f4ef,可以发现其是个函数体,第 582 行 return 后的返回值就是 __jsl_clearance_s参数的值:

在这里插入图片描述

在第 581 行打断点调试,能知道 hash 后 _0x2cc335 为 __jsl_clearance_s 参数的值:

在这里插入图片描述

hash( _0x2cc335) 的值为 _0x2cc335 经过加密后的结果,在本例中,加密结果特征分析很明显能看出是SHA256的加密长度,其实通过查看之前获取的go字典也能看到他写出了用的什么加密方式。

但加密的方法即 hash 方法不全是 SHA256,多刷新几次发现会变化,实际上这个 hash 方法与原来调用 go 函数传入的字典中 ha 的值相对应,ha 即加密算法的类型,一共有 md5、sha1、sha256 三种,所以我们在本地处理的时候,要同时有这三种加密算法,通过 ha 的值来匹配不同算法。

在这里插入图片描述

进一步观察这里还有个 for 循环,分析发现每次循环 hash(_0x2cc335) 的值是动态变化的,原因是 _0x2cc335 的值是在动态变化的,_0x2cc335 中只有中间两个字母在变化,不仔细看都看不出来:

在这里插入图片描述

跟进 _0x2cc335 生成的位置,分析可知 _0x2cc335 参数的值是由 _0xf7137b 数组的第一个值加上两个字母再加上该数组第二个值组成的结果:

在这里插入图片描述

_0x2cc335的源代码混淆参数很多不好直接分析,建议解混淆后再进行分析

var _0x2cc335 = _0xf7137b[0x0] + _0x5a3a5f[_0x1739('0x89', 'BSbR') + 's'][_0x1739('0xb8', 'jBDG') + 'tr'](_0x107bb7, 0x1) + _0x5a3a5f[_0x1739('0x105', 'kvMu') + 's'][_0x1739('0x6e', 'm%$p') + 'tr'](_0x4ec95b, 0x1) + _0xf7137b[0x1];

解混淆后代码如下

var _0x2cc335 = _0xf7137b[0x0] + _0x5a3a5f['chars']["substr"](_0x107bb7, 0x1) + _0x5a3a5f['chars']["substr"](_0x4ec95b, 0x1) + _0xf7137b[0x1];

中间两个字母是将底下这段写了两次生成的,即 _0x5a3a5f['chars']['substr'][1], 取字典中 chars 参数的一个字母,取了两次,这里通过 for 循环在不断取这两个值,直到其值加密后与 _0x1c0bb7(即 ct)的值相等,则作为返回值传递给 __jsl_clearance_s 参数:

_0x1c0bb7为ct的值:

在这里插入图片描述

最前面_0x3fa957[_0x1739('0xf0', 'oMaE') + 'E']是个方法,我们进一步跟进过去,看这个方式里面实现了什么样的逻辑:

其内容如下,可以看到这个方法返回的值是两个相等的参数:
在这里插入图片描述

模拟执行

综上所述,_0x29f4ef 函数中的逻辑就是判断 _0x2cc335 的值经过 hash 方法加密后的值,是否与 ct 的值相等,若相等则将返回值传递给 __jsl_clearance_s 参数,循环完后还未有成功匹配的值则会执行提示失败,传入参数中 ha 的值是在变化的,即加密算法也是在变化的,有三种加密方式 SHA1SHA256MD5,我们可以扣下三种 hash 方法,也可以直接使用 crypto-js 库来实现:

var 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();
    }
}

function cookies(_0x5a3a5f){
    var _0x26fd06 = new Date();
    function _0x29f4ef(_0x1c0bb7, _0xf7137b) {
        var _0x5dfb01 = _0x5a3a5f['chars']['length'];
        for (var _0x107bb7 = 0x0; _0x107bb7 < _0x5dfb01; _0x107bb7++) {
            for (var _0x4ec95b = 0x0; _0x4ec95b < _0x5dfb01; _0x4ec95b++) {
                var _0x2cc335 = _0xf7137b[0x0] + _0x5a3a5f['chars']["substr"](_0x107bb7, 0x1) + _0x5a3a5f['chars']["substr"](_0x4ec95b, 0x1) + _0xf7137b[0x1];
                if ((hash(_0x5a3a5f['ha'],_0x2cc335) == _0x1c0bb7)) {
                    return [_0x2cc335, new Date() - _0x26fd06];
                }
            }
        }
    }
    var _0x4bca4c = _0x29f4ef (_0x5a3a5f['ct'], _0x5a3a5f['bts']);

  return {'__jsl_clearance_s' : _0x4bca4c[0]};
}

console.log(cookies({
    "bts": ["1690639070.278|0|ihl", "l%2FaY6Y3B%2FKq8I4GT55NZvc%3D"],
    "chars": "iMyDvZzWmPBnCGdujVpCAJ",
    "ct": "fb9fe0ec006b42f92ffbd372dc71b4612c989e2bf4d095afb8abbfce8ed3d35f",
    "ha": "sha256",
    "is": false,
    "tn": "__jsl_clearance_s",
    "vt": "3600",
    "wt": "1500"
}))

获取结果如下

在这里插入图片描述

python代码只演示部分关键代码,完整代码可私信联系我

def get_first_cookie():
    global cookies
    resp_first = requests.post(url, headers=headers,  data=data)
    # 获取 cookie 值 __jsluid_s
    cookies.update(resp_first.cookies)
    # 获取第一层响应内容, AAEncode 加密
    content_first = re.findall('cookie=(.*?);location', resp_first.text)[0]
    jsl_clearance_s = execjs.eval(content_first).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 获取第二层响应内容
    resp_second = requests.get(url=url, headers=headers, cookies=cookies)
    # 获取 go 字典参数
    go_params = re.findall(';go\((.*?)\)</script>', resp_second.text)[0]
    params = json.loads(go_params)
    return params


def get_third_cookie():
    with open('jsl.js', 'r', encoding='utf-8') as f:
        jsl_js = f.read()
    params = get_second_cookie()
    # 传入字典
    third_cookie = execjs.compile(jsl_js).call('cookies', params)
    cookies.update(third_cookie)


def main():
    get_first_cookie()
    get_third_cookie()
    resp_third = requests.post(url, headers=headers,cookies=cookies , data=data)
    resp_third.encoding = 'utf-8'
    print(resp_third.text)


if __name__ == '__main__':
    main()

获取结果如下

在这里插入图片描述

致谢

部分思路代码通过以下文章学习:【JS 逆向百例】某网站加速乐 Cookie 混淆逆向详解

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/810863.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【二叉树进阶】搜索二叉树(递归+非递归两种版本详解)

文章目录 前言1. 二叉搜索树的概念2. 二叉搜索树的结构2.1 结点结构2.2 树结构 3. 插入操作&#xff08;非递归&#xff09;3.1 思路分析3.2 代码实现3.3 中序遍历&#xff08;测试用&#xff09; 4. 查找操作&#xff08;非递归&#xff09;4.1 思路分析4.2 代码实现 5. 删除操…

七大经典比较排序算法

1. 插入排序 (⭐️⭐️) &#x1f31f; 思想&#xff1a; 直接插入排序是一种简单的插入排序法&#xff0c;思想是是把待排序的数据按照下标从小到大&#xff0c;依次插入到一个已经排好的序列中&#xff0c;直至全部插入&#xff0c;得到一个新的有序序列。例如&#xff1a;…

Doc as Code (3):业内人士的观点

作者 | Anne-Sophie Lardet 在技术传播国际会议十周年之际&#xff0c;Fluid Topics 的认证技术传播者和功能顾问 Gaspard上台探讨了“docOps 作为实现Doc as Code的中间结构”的概念。在他的演讲中&#xff0c;观众提出了几个问题&#xff0c;我们想分享Gaspard的见解&#x…

深入学习 Redis - 渐进式遍历 scan 命令、数据库管理命令

目录 前言 一、scan 命令 二、数据库管理命令 select dbsize flushdb / flushall 前言 之前我们所了解到的 keys * 是一次性把整个 redis 中所有的 key 都获取到&#xff0c;但是整个操作比较危险&#xff0c;可能会一下子的都太多的 key&#xff0c;阻塞 redis 服务器. …

NLP(六十三)使用Baichuan-7b模型微调人物关系分类任务

任务介绍 人物关系分类指的是对文本中的两个人物&#xff0c;在特定的关系列表中&#xff0c;判断他们之间的人物关系。以样本亲戚 1837年6月20日&#xff0c;威廉四世辞世&#xff0c;他的侄女维多利亚即位。为例&#xff0c;其中亲戚为人物关系&#xff0c;威廉四世为实体1&a…

vins调试的注意事项

1、摄像头的内参和畸变矫正系数 这个系数不对&#xff0c;没法做&#xff0c;因为下一步没法做对。这个会导致系统无法初始化。 2、对畸变的像素点&#xff0c;求得归一化坐标的方法 理解不同矫正模型的原理&#xff0c;确保矫正对了&#xff0c;得到z1平面的去畸变点。 3、摄…

python皮卡丘编程代码教程,用python打印皮卡丘

大家好&#xff0c;小编来为大家解答以下问题&#xff0c;如何用print函数打印一只皮卡丘&#xff0c;用python如何打印丘比特之心&#xff0c;现在让我们一起来看看吧&#xff01;

CCL 2023 电信网络诈骗案件分类评测-第一名方案

1 任务内容 1.1 任务背景 2022年12月1日起&#xff0c;新出台的《反电信网络诈骗犯罪法》正式施行&#xff0c;表明了我国治理当前电信网络诈骗乱象的决心。诈骗案件分类问题是打击电信网路诈骗犯罪过程中的关键一环&#xff0c;根据不同的诈骗方式、手法等将其分类&#xff…

13个ChatGPT类实用AI工具汇总

在ChatGPT爆火后&#xff0c;各种工具如同雨后春笋一般层出不穷。以下汇总了13种ChatGPT类实用工具&#xff0c;可以帮助学习、教学和科研。 01 / ChatGPT for google/ 一个浏览器插件&#xff0c;可搭配现有的搜索引擎来使用 最大化搜索效率&#xff0c;对搜索体验的提升相…

【机器学习】Linear Regression

Model Representation 1、问题描述2、表示说明3、数据绘图4、模型函数5、预测总结附录 1、问题描述 一套 1000 平方英尺 (sqft) 的房屋售价为300,000美元&#xff0c;一套 2000 平方英尺的房屋售价为500,000美元。这两点将构成我们的数据或训练集。面积单位为 1000 平方英尺&a…

C++ 类和对象篇(零) 面向过程 和 面向对象

目录 一、面向过程 二、面向对象 三、两种编程思想的比较 四、C和C 一、面向过程 1.是什么&#xff1f; 是一种以解决问题的过程为中心的编程思想。即先分析出解决问题所需要的步骤&#xff0c;然后用函数把这些步骤一步一步实现。 2.为什么&#xff1f; 面向过程就纯粹是分析…

基于x-scan扫描线的3D模型渲染算法

基于x-scan算法实现的z-buffer染色。c#语言&#xff0c;.net core framework 3.1运行。 模型是读取3D Max的obj模型。 x-scan算法实现&#xff1a; public List<Vertex3> xscan() {List<Vertex3> results new List<Vertex3>();SurfaceFormula formula g…

SAP 自定义BADI增强点

应用场景 标准化代码中预留客制化部分&#xff0c;保证代码主体完整性&#xff0c;可以在预留增强位置预留两种类型的增强处理&#xff0c;其一为标准增强类型的&#xff0c;增强部分代码属于增加的逻辑&#xff0c;其二对于部分多样化的逻辑&#xff0c;使用优先执行默认逻辑&…

Java常用API:Object、Objects、包装类

Object类API toString 返回字符串类型 equals 默认比较的是地址 此时返回的是 false 可以在类中重写equals 方法 比较内容 如果内容一样就返回true clone 不能在测试类中用&#xff0c;必须在创建的类中重写克隆方法 还必须要有接口&#xff0c;说明这个对象有这个能力克隆 …

增量预训练baichuan-13b-chat遇到的那些坑

文章目录 前言资源deepspeed一、训练的坑二、推理的坑三、继续训练的坑总结前言 资源 单机两4090,如图 单卡24G,baichuan-13b-chat单卡推理需要至少26G,因此仅用一张卡,我们是无法加载百川13B的模型,所以,无论是推理还是训练,我们都必须并行! deepspeed 核心思想…

主干网络篇 | YOLOv8 更换主干网络之 VanillaNet |《华为方舟实验室最新成果》

论文地址:https://arxiv.org/pdf/2305.12972.pdf 代码地址:https://github.com/huawei-noah/VanillaNet 在基础模型的核心是“多样性即不同”,这一哲学在计算机视觉和自然语言处理方面取得了惊人的成功。然而,优化和Transformer模型固有的复杂性带来了挑战,需要转向简洁性…

Python-Python基础综合案例--数据可视化 - 地图可视化

版本说明 当前版本号[20230729]。 版本修改说明20230729初版 目录 文章目录 版本说明目录知识总览图Python基础综合案例--数据可视化 - 地图可视化基础地图使用案例效果视觉映射器 疫情地图-国内疫情地图案例效果实操设置全局配置选项 疫情地图-省级疫情地图案例效果实操 知…

spring拦截器 与统一格式

目录 前言模拟拦截器拦截器的实现原理什么是动态代理? 什么是静态代理静态代理与动态代理的区别两种常用的动态代理方式基于接口的动态代理基于类的动态代理 JDK Proxy 与 CGlib的区别 其他 统⼀访问前缀添加统⼀异常处理统⼀数据返回格式 前言 之前博客讲述了 , 关于SpringA…

Kotlin~Memento备忘录模式

概念 备忘录模式是一种行为型设计模式&#xff0c;用于捕获和存储对象的内部状态&#xff0c;并在需要时将对象恢复到之前的状态。 备忘录模式允许在不暴露对象内部实现细节的情况下&#xff0c;对对象进行状态的保存和恢复。 角色介绍 Originator&#xff1a;原发器&#x…

7.事件类型

7.1鼠标事件 案例-轮播图点击切换 需求&#xff1a;当点击左右的按钮&#xff0c;可以切换轮播图 分析: ①右侧按钮点击&#xff0c;变量&#xff0c;如果大于等于8&#xff0c;则复原0 ②左侧按钮点击&#xff0c;变量–&#xff0c;如果小于0&#xff0c;则复原最后一张 ③鼠…