当前位置: 首页 > news >正文

JS逆向 - (国外)SHEIN站 - 请求头(armorToken、Anti-in)

文章目录

    • 概要
    • 整体架构流程
    • 技术名词解释
    • 小结

概要

提示:仅供学习,不得用做商业交易,如有侵权请及时联系

逆向:JS逆向 - (国外)SHEIN站 - 请求头(armorToken、Anti-in)

URL:aHR0cHM6Ly9pZC5zaGVpbi5jb20vUmVjb21tZW5kU2VsZWN0aW9uL0hvbWUtS2l0Y2hlbi1zYy0wMTcxODU1NDYuaHRtbD9pY2k9aWRlbl90YWIwNW5hdmJhcjA1JnNyY19tb2R1bGU9dG9wY2F0JnNyY19pZGVudGlmaWVyPWZjJTNESG9tZSUyMCUyNiUyMEtpdGNoZW4lNjBzYyUzREhvbWUlMjAlMjYlMjBLaXRjaGVuJTYwdGMlM0QwJTYwb2MlM0QwJTYwcHMlM0R0YWIwNW5hdmJhcjA1JTYwamMlM0RpdGVtUGlja2luZ18wMTcxODU1NDYmc3JjX3RhYl9wYWdlX2lkPXBhZ2VfaG9tZTE3NTAzMTk2NDQ2NzQmY2F0ZWdvcnlKdW1wPTY2MTE3MV8hXzAmcGFnZT0y

提示:需要翻墙

整体架构流程

提示:分析参数生成

1、参数位置和验证接口:

在这里插入图片描述

响应内容:会返回一个token

在这里插入图片描述

2、堆栈分析位置或者搜索关键字:armorToken,这里就不带着一起跟了,直接搜索

在这里插入图片描述
提示:需要将浏览器加载的缓存全部清理

3、下断,直接刷新网页,NcWc(“0x3c”)跳进去吗,发现是从zc函数进行加密的

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

注意:手动去执行它加密的时候,浏览器会将生成好的值存储到localStorage/sessionStorage

4、进入到zc函数,我们可以看到,如果$c这个对象里面的value有值的话,我们可以给它赋值字符串,重新生成一个

在这里插入图片描述

w(this, Rc, $c, [["S", at[t("0x11")]()][t("0x51")](""), pt(), te[t("0x22")](mc[t("0x4e")](Dn[t("0x4f")](b(this, Rc, Kc)[t("0xf")](this)), Dn[t("0x4f")](At()), {iv: J[t("0x4f")](""),mode: L[t("0x5c")][t("0x5d")],padding: Pc})[t("0x50")]), (new Date)[t("0x5e")]()][t("0x51")]("_"))

分析这块代码

  • att(“0x11”):固定、pt():版本号
    在这里插入图片描述

  • b(this, Rc, Kc)t(“0xf”):这里观察是下面的Kc函数获取,Qr就是一个标准的MD5加密
    在这里插入图片描述

const CryptoJs = require('crypto-js');
var getReportUrl_metricCount = 0var version = "3.7.0"var armorUuid = '浏览器返回'var userAgent = "换成自己的"var now_time = new Date().getTime()get8LRandomStr = function () {return 'xxxxxxxx'['replace'](/[xy]/g, (function (t) {var n = 16 * Math["random"]() | 0;return ("x" == t ? n : 3 & n | 8)['toString'](16)}))}();armorToken_list = [getReportUrl_metricCount, version, armorUuid, userAgent, now_time, get8LRandomStr, '-'].join("^@^")armorToken_list_data = [armorToken_list, CryptoJs.MD5(armorToken_list).toString()["slice"](-6)].join("^@^")
  • 继续看一下key是什么:发现是固定的"Yp22&mqMv#3t28Zh"
    在这里插入图片描述

  • 继续观察它是一个AES加密,并且是标准的,但是转字符串的函数是魔改的,你会看到AES加密其实取的是ciphertext
    在这里插入图片描述

CryptoJs.enc.toString_ = function toString(t) {var r = !0;var e = t["words"], x = t["sigBytes"], a = r ? "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_" : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";t["clamp"]();for (var i = [], o = 0; o < x; o += 3)for (var c = (e[o >>> 2] >>> 24 - o % 4 * 8 & 255) << 16 | (e[o + 1 >>> 2] >>> 24 - (o + 1) % 4 * 8 & 255) << 8 | e[o + 2 >>> 2] >>> 24 - (o + 2) % 4 * 8 & 255, u = 0; u < 4 && o + .75 * u < x; u++)i["push"](a['charAt'](c >>> 6 * (3 - u) & 63));var s = a['charAt'](64);if (s)for (; i['length'] % 4; )i["push"](s);return i['join']("")
}
aes_encrypt = function (data, key, iv) {key = CryptoJs.enc.Utf8.parse(key);iv = CryptoJs.enc.Utf8.parse(iv);var encrypted = CryptoJs.AES.encrypt(data, key, {iv: iv,mode: CryptoJs.mode.CBC,padding: CryptoJs.pad.Pkcs7});return CryptoJs.enc.toString_(encrypted.ciphertext);
}

最后将上面的值进行拼接就得到了armorToken

7、继续分析我们的第二个参数Anti-in,这里划一下水,自己跟一下栈,比较容易跟

在这里插入图片描述

你会发现它是通过浏览器指纹进行加密最好得到一大串字符串的,这里Zc就是加密函数

var x = {data: b(e, r, Zc)[n("0xf")](e, t),appName: at[n("0x19")]()};

8、进入到加密函数,我们观察可以看到,mc也是一个AES,key的值是:“Q5eV2XXICMBi0CBL”,但是它是ECB模式的,需要注意一下,肯定也是对toString进行了魔改的

在这里插入图片描述

aes_encrypt_Ecb = function (data, key) {key = CryptoJs.enc.Utf8.parse(key);var encrypted = CryptoJs.AES.encrypt(data, key, {mode: CryptoJs.mode.ECB,padding: CryptoJs.pad.Pkcs7});return encrypted.ciphertext;
}
  • 这里我们会发现i的值就是对指纹数组进行转字符串,然后先经过oc处理这个字符串得到一个Uint8Array数组,这里其实就是一个字符串压缩算法
const pako = require('pako');
const encoder = new TextEncoder();
const utf8Bytes = encoder.encode(指纹字符串);
const compressedBytes = pako.deflate(utf8Bytes);  // 默认生成 zlib 头 
const zhiw_stringify_uint8Array = new Uint8Array(compressedBytes);
  • 继续我们看到,对这个压缩后的数组进行转WrodArry,其实这个J[r(“0x49”)]函数就是标准的CryptoJs.enc.Hex.parse
    在这里插入图片描述

  • Qr(i)n(“0xc”)n(“0x4d”):说一下这里其实也是对指纹进行MD5然后取后面6位

  • 最后再说一下这个Mc(u, Tc):它也是一个魔改的stringify
    在这里插入图片描述

function Tc(t, r) {return 64 === t ? 64 : 63 === t ? r : t >= r ? t + 1 : t}
function Mc(t, n) {var e = t["words"], x = t["sigBytes"], i = "xYACKb9gwIn12kHtuiG7RVSJjTU-Z8cq_NOvmXzeaFoyWQpDh3LB4rs0EM6fd5lP=";t["clamp"]();for (var a = [], o = Math["floor"](64 * Math["random"]()), u = 0; u < x; u += 3)for (var c = (e[u >>> 2] >>> 24 - u % 4 * 8 & 255) << 16 | (e[u + 1 >>> 2] >>> 24 - (u + 1) % 4 * 8 & 255) << 8 | e[u + 2 >>> 2] >>> 24 - (u + 2) % 4 * 8 & 255, s = 0; s < 4 && u + .75 * s < x; s++) {var f = c >>> 6 * (3 - s) & 63;a['push'](i['charAt'](n(f, o)))}var v = i['charAt'](64);if (v)for (; a['length'] % 4; )a['push'](v);return a['join']("")['replace'](/=/g, "") + i[o]
}

技术名词解释

提示:py调用
在这里插入图片描述
在这里插入图片描述

小结

提示:学习交流主页,星球持续更新中:链接https://t.zsxq.com/AJTw2(+星球主页+v)

http://www.dtcms.com/a/298314.html

相关文章:

  • 【05】C#入门到精通——C# 面向对象、类、静态变量static、类与类之间的调用
  • [SV]在 Verilog 中,对某个信号施加一个弱下拉,但又不能影响后续的正常驱动
  • CSS 盒子模型学习版的理解
  • 【论文阅读51】-CNN-LSTM-安全系数和失效概率预测
  • Multiscale Structure Guided Diffusion for Image Deblurring 论文阅读
  • 【论文阅读】-《GenAttack: Practical Black-box Attacks with Gradient-Free Optimization》
  • 零售收银系统开源代码全解析:连锁门店一体化解决方案(含POS+进销存+商城)
  • 深入理解 Linux 进程信号
  • Linux 桌面市场份额突破 5%:开源生态的里程碑与未来启示
  • [MMU]四级页表查找(table walk)的流程
  • 流式接口,断点续传解决方案及实现
  • 前端核心进阶:从原理到手写Promise、防抖节流与深拷贝
  • iOS 抓包工具有哪些?模块化功能解析与选型思路
  • 容器化环境下的服务器性能瓶颈与优化策略
  • ubuntu22.04.4锁定内核应对海光服务器升级内核无法启动问题
  • Qt Mysql linux驱动编译
  • Google AI Mode 解析:生成式搜索功能的核心机制与应用场景
  • PowerDesigner安装教程(附加安装包)PowerDesigner详细安装教程PowerDesigner 16.6 最新版安装教程
  • Nacos-服务注册,服务发现(一)
  • 【模型剪枝1】结构化剪枝论文学习笔记
  • 如何理解SpringBoot starters的自动装配
  • 地下隧道管廊结构健康监测系统 测点的布设及设备选型
  • 1 51单片机-C51语法
  • 4麦 360度定位
  • docker搭建ray集群
  • SAP-PP-MRPLIST
  • MybatisPlus-17.扩展功能-JSON处理器
  • 【57】MFC入门到精通——MFC 多线程编程总结
  • 【lucene】自定义tokenfilter 自带payload
  • String类常用方法练习