WEB逆向—X-Bogus逆向分析(纯算+补环境)

声明

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

前言

此平台 本人 仅限研究。只针对某些算法参数进行研究。网站链接自己去找。

流程分析

这里就不多说了

直接看接口。发现有两个字需要我们逆向

msToken:

X-Bogus:

msToken

这里msToken 跟断点走。往上追栈后发现是直接读取的cookie里的。然后看了一下。然后测试了一下 这个有点像每次请求的token令牌。

这个应该可以模拟生成的。

 

不重要 暂时写死都行。这里也提供一份代码。

1

2

3

4

5

6

7

8

9

10

11

12

13

import random

def get_ms_token(randomlength=107):

    """

    根据传入长度产生随机字符串

    """

    random_str = ''

    base_str = 'ABCDEFGHIGKLMNOPQRSTUVWXYZabcdefghigklmnopqrstuvwxyz0123456789='

    length = len(base_str) - 1

    for in range(randomlength):

        random_str += base_str[random.randint(0, length)]

    return random_str

xb

这里话也不多说了。

直接讲流程。

首先 如下图所示

然后跳到断点之后往上找断点。

到达如图所示位置之后

 

这个apply啥意思就不多说了 直接插桩

1

_0x2458f0['apply'](_0xc26b5e, _0x1f1790)==28(xb的长度)

然后 单点调试下一步 ok 到达了一个JSVMP的方法。然后传的值都是字节码 然后把这些汇编代码转换为JS代码 

这里就考虑两种方法了。要不插桩纯算。要不补环境。

补环境

先说补环境。

直接全扣下来。

然后在下图位置赋值。

然后著名语录: 缺啥补啥。

这里已经补完了 就这么点。

1

2

3

4

5

6

window = global

document = {}

document.addEventListener = function () {}

navigator = {

    "userAgent"'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.366'

}

然后直接得到答案

至于这个警告。是一个弃用警告。代表这个Buffer这个方法已经不用了。可以通过修改代码

然后看看传参是什么

 

然后给他封装成参数去调用就可以了。

算法

这里我们看到这个文件里其实是经过混淆的 非常不利于我们分析加密参数。

所以我们需要使用到ast等工具对他进行解混淆。

然后通过解混淆完了的JS 进行文件重写覆盖。

这里简单讲讲流程。

 选择替换内容。浏览器会自动帮我们把js保存到替换的文件夹中。非常方便。

然后就能看到我们的文件了。然后复制文件。到v-tools中 

 然后继续往上找栈。发现下图就是JSVMP初始化的地方。并且通过执行了W方法 最终获得返回值。

我们这里就直接进入文中这个W方法。

这里进去看可以看到一堆的流程控制语句。

把这个方法复制下来。可以看到。这个方法的走向就是靠判断语句执行的。然后判断语句中又有一堆的流程控制语句。

而且这个判断条件也是由传参的最后一个参数控制的。那这个就很有意思了。

里在这两短流程语句中分别打上日志断点。然后来分析其中的参数。

第一处断点

1

"1""j>>>", j, "A>>>>", A, "O>>>>>", JSON.stringify(O, function(key, value) {if (value == window) {return undefined} return value})

 

第二处断点

1

"2","j>>>", j, "A>>>>", A, "O>>>>>", JSON.stringify(O, function(key, value) {if (value == window) {return undefined} return value})

 

这里一定要注意debugger不要乱删 不然很容易卡死 。打出来的数据非常之大。

如下图。把所有的日志断点保存 然后往上找第一个X-Bogus 生成的地方。

 可以看到 如下图所示。是赋值 值给 X-Bogus的地方。那我们去搜索这个值

 

这里就可以看到 。越往上 这个X-Bogus的值就越少。那我们大概就明白了。

这就意味着xb是一个字一个字的根据算法生成。

这里在浏览器看 不是很方便。我们把控制台另存为到文件中方便我们调试。

(这里浏览器卡死了。xb的值可能不固定,不要在意细节)

首先分析下这个3 是如何生成的。

 

1

2 j>>> 16 A>>>> 716 O>>>>> [null,[null,{},null,null,"\u0002ÿ-%.*¯Ë^9õ²\u000b&7\u0012","s2","=",{"s0":"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=","s1":"Dkdpgh4ZKsQB80/Mfvw36XI1R25+WUAlEi7NLboqYTOPuzmFjJnryx9HVGcaStCe=","s2":"Dkdpgh4ZKsQB80/Mfvw36XI1R25-WUAlEi7NLboqYTOPuzmFjJnryx9HVGcaStCe="},"Dkdpgh4ZKsQB80/Mfvw36XI1R25-WUAlEi7NLboqYTOPuzmFjJnryx9HVGcaStCe=","DFSzswVOPSzANro1t-KBsNAwgYo",1214867,21],"DFSzswVOPSzANro1t-KBsNAwgYo","3","Dkdpgh4ZKsQB80/Mfvw36XI1R25-WUAlEi7NLboqYTOPuzmFjJnryx9HVGcaStCe=",[19],63,21]

也就是代表 要通过 上面这些值 拿到 3

我们打个条件断点。去看看最后一个的生成逻辑

 

打断点继续往下走。

这里注意 要注意我们的O 里是否会有 如上值。如下图 才能正确单步调试。

 

我们的xb值为 DFSzswVOPSzANro1t-KBsNAwgYo3

由于我们目标是获得数值3。 用以下代码可以做到

1

2

"Dkdpgh4ZKsQB80/Mfvw36XI1R25-WUAlEi7NLboqYTOPuzmFjJnryx9HVGcaStCe=".charAt(19)

>> 3

同理 获得倒数第二位。继续看我们的日志

这里是 o,38位

根据断点可知 xb4个为一组。

charAt后面的值就是我们所需要的值。

这里 就不废话太多了

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

str1 = "Dkdpgh4ZKsQB80/Mfvw36XI1R25-WUAlEi7NLboqYTOPuzmFjJnryx9HVGcaStCe="

// 19 = (1214867 & 63) >> 0

str1.charAt((1214867 & 63) >> 0)

//结果:3

// 38 = (1214867 & 4032) >> 6

str1.charAt((1214867 & 4032) >> 6)

// 结果:o

// 40 = (1214867 & 258048) >> 12

str1.charAt((1214867 & 258048) >> 12)

// 结果:Y

// 4 = (1214867 & 16515072) >> 18

str1.charAt((1214867 & 16515072) >> 18)

// 结果:g

上述刚好对应了 xb的最后四位

DFSz swVO PSzA Nro1t-KB sNAw gYo3

其余算法也一样。

数字算法逻辑

现在唯一可能要注意的就是这个1214867的算法是什么?

这里篇幅原因不展开搞了。反正概念都是一样。根据索引找方法。


这里 1214867 是通过位运算符的 1214720 | 147 最终得到1214867

 

 

这里又牵扯到了 两个值

  • 1214720

    • 通过位运算 1179648 | 35072 移位得到1214720 那又有两个值出现了
      • 1179648 通过 18<< 16 左移得来 (这里16为定值)

 

 137 通过乱码charCodeAt得来 

image-20240330000412236

    • 而147 则是通过 乱码 charCodeAt 获取到的

有点乱 梳理一下

  1. 通过 乱码 charCodeAt(20)获得147
  2. 通过 乱码 charCodeAt(19)获得137
  3. 通过 乱码 charCodeAt(18)获得18
  4. 通过147 << 0 获得了 147(找规律得来)
  5. 通过 137 << 8 获得 35072
  6. 通过 18<< 16 获得 1179648
  7. 通过位运算 1179648 | 35072 获得1214720
  8. 位运算符的 1214720 | 147 最终得到1214867

那这个只是最后一组的。根据这四组 找规律 获取其他组的信息可得以下代码

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

const encodedString = "\u0002ÿ-%.*¯Ë^9õ²\u000b&7\u0012";

const decodingMap = "Dkdpgh4ZKsQB80/Mfvw36XI1R25-WUAlEi7NLboqYTOPuzmFjJnryx9HVGcaStCe=";

let xb = "";

for (let index = 0; index <= 20; index += 3) {

    const charCode1 = encodedString.charCodeAt(index);

    const charCode2 = encodedString.charCodeAt(index + 1);

    const charCode3 = encodedString.charCodeAt(index + 2);

    const combinedCode = charCode3 | (charCode2 << 8) | (charCode1 << 16);

    const codePart1 = (combinedCode & 16515072) >> 18;

    const codePart2 = (combinedCode & 258048) >> 12;

    const codePart3 = (combinedCode & 4032) >> 6;

    const codePart4 = combinedCode & 63;

    xb += decodingMap[codePart1] + decodingMap[codePart2] + decodingMap[codePart3] + decodingMap[codePart4];

}

console.log(xb);

乱码生成分析

然后就是获取这个乱码的生成处了。可以看到 如下图所示。

 

 

如上图所示。这个b的生成还是没有还原出来。我们继续来找b。

下图 是生成b的地方。所以我们把这个函数也扣下来。

 

事实证明和上文一样。没问题。

部分代码如下

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

function _0x86cb82(a) {

    return String.fromCharCode(a);

}

function _0x94582(a, b, c) {

    return _0x86cb82(a) + _0x86cb82(b) + c;

}

function _0x25788b(a, b) {

    for (var c, e = [], d = 0, t = "", f = 0; f < 256; f++) {

        e[f] = f;

    }

    for (var r = 0; r < 256; r++) {

        d = (d + e[r] + a.charCodeAt(r % a.length)) % 256, c = e[r], e[r] = e[d], e[d] = c;

    }

    var n = 0;

    d = 0;

    for (var o = 0; o < b.length; o++) {

        d = (d + e[n = (n + 1) % 256]) % 256, c = e[n], e[n] = e[d], e[d] = c, t += String.fromCharCode(b.charCodeAt(o) ^ e[(e[n] + e[d]) % 256]);

    }

    return t;

}

function _0x398111(a, b, c, e, d, t, f, r, n, o, i, _, x, u, s, l, v, h, p) {

    var y = new Uint8Array(19);

    return y[0] = a, y[1] = i, y[2] = b, y[3] = _, y[4] = c, y[5] = x, y[6] = e, y[7] = u,

        y[8] = d, y[9] = s, y[10] = t, y[11] = l, y[12] = f, y[13] = v, y[14] = r, y[15] = h,

        y[16] = n, y[17] = p, y[18] = o, String.fromCharCode.apply(null, y);

};

这个已经弄完了。还差最后一个就是这个数组。arr其实 不是一个完整的数组,而是一个个数字。

arr 共有19位。

这里说下大概。我也没有每个都去研究。

前4位是固定值

第5位到第10位通过md5 hex_md5 以及转码得到数组 然后切片取其中的值。

第11位到第18位是通过时间戳还有个canvas固定值拼接而来。

最后一位通过前面的签名最终得到最后一位数组

最后通过19位 数字 然后编码得到乱码。

最终结果

 

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

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

相关文章

分类预测 | Matlab实现CNN-BiLSTM-SAM-Attention卷积双向长短期记忆神经网络融合空间注意力机制的数据分类预测

分类预测 | Matlab实现CNN-BiLSTM-SAM-Attention卷积双向长短期记忆神经网络融合空间注意力机制的数据分类预测 目录 分类预测 | Matlab实现CNN-BiLSTM-SAM-Attention卷积双向长短期记忆神经网络融合空间注意力机制的数据分类预测分类效果基本描述程序设计参考资料 分类效果 基…

Spring Boot 如何进行多环境配置

在SpringBoot中管理不同环境的配置确实是一个常见且重要的实践。通过使用不同的配置文件&#xff0c;你可以轻松地在开发、测试和生产环境之间切换&#xff0c;而无需手动更改配置信息。这不仅提高了开发效率&#xff0c;还减少了因配置错误导致的潜在问题。 要实现这一点&…

深入探究音视频开源库WebRTC中NetEQ音频抗网络延时与抗丢包的实现机制

目录 1、引言 2、WebRTC简介 3、什么是NetEQ&#xff1f; 4、NetEQ技术详解 4.1、NetEQ概述 4.2、抖动消除技术 4.3、丢包补偿技术 4.4、NetEQ概要设计 4.5、NetEQ的命令机制 4.6、NetEQ的播放机制 4.7、MCU的控制机制 4.8、DSP的算法处理 4.9、DSP算法的模拟测试…

分布式与一致性协议之CAP(二)

CAP CAP不可能三角 CAP不可能三角是指对于一个分布式系统而言&#xff0c;一致性、可用性、分区容错性指标不可兼得&#xff0c;只能从中选择两个&#xff0c; 如图所示。CAP不可能三角最初是埃里克布鲁尔(Eric Brewer)基于自己的工程实践提出的一个猜想&#xff0c;后被塞斯吉…

论文辅助笔记:LLM-MOB代码解读

论文笔记 Where Would I Go Next? Large Language Models as Human Mobility Predictor-CSDN博客 1 主函数 1.1 导入库 import os import pickle import time import ast import logging from datetime import datetime import pandas as pd from openai import OpenAIclie…

【003_音频开发_基础篇_Linux进程通信(20种你了解几种?)】

003_音频开发_基础篇_Linux进程通信&#xff08;20种你了解几种&#xff1f;) 文章目录 003_音频开发_基础篇_Linux进程通信&#xff08;20种你了解几种&#xff1f;)创作背景Linux 进程通信类型fork() 函数fork() 输出 2 次fork() 输出 8 次fork() 返回值fork() 创建子进程 方…

Diffusion Model原理剖析

目录 前言1. DDPM演算法初览2. 图像生成模型共同目标3. VAE: Lower bound of l o g P ( x ) logP(x) logP(x)4. Diffusion Model背后的数学原理5. 为什么需要Sample?6. Diffusion Model的应用7. Diffusion Model成功的关键总结参考 前言 接着上篇文章 图像生成模型浅析&#…

1-k8s集群安装报错CGROUPS_CPU: missing

加入集群报错 [rootiZuf65r8i4e90z40vlh8mgZ ~]# kubeadm join 172.19.35.202:6443 --token 9edy1q.209zfq0387qtiv5x --discovery-token-ca-cert-hash sha256:24e0953896046aa8ce573ec7faf6609b87250883a7691fcad70a0faa81978c3b --control-plane --cri-socket "unix://…

Three.js入门学习笔记

学习资料&#xff1a; 【Three.js】Three.js快速上手教程_three.module.js-CSDN博客 2024年了&#xff0c;是该学学Three.js了_three.js 2024-CSDN博客 一、three.js简介 three.js是JavaScript编写的WebGL第三方库。 three.js&#xff0c;webGL&#xff0c;openGL三者的关…

【Linux高性能服务器编程】两种高性能并发模式剖析——领导者/追随者模式

hello &#xff01;大家好呀&#xff01; 欢迎大家来到我的Linux高性能服务器编程系列之两种高性能并发模式介绍&#xff0c;在这篇文章中&#xff0c;你将会学习到高效的创建自己的高性能服务器&#xff0c;并且我会给出源码进行剖析&#xff0c;以及手绘UML图来帮助大家来理解…

SpringBoot自动配置底层源码分析

文章目录 1. 什么是SpringBoot的自动装配&#xff1f;2. SpringBoot自动装配的底层原理 1. 什么是SpringBoot的自动装配&#xff1f; Spring Boot的自动配置是一种机制&#xff0c;它使得开发者能够快速地开始构建Spring应用&#xff0c;而不需要手动编写大量的样板代码。Spri…

代码随想录第34天: 贪心part03

力扣 1005.K次取反后最大化的数组和 class Solution {public int largestSumAfterKNegations(int[] nums, int k) {// 将基本类型的int数组转换成IntStream&#xff0c;以便进行流操作。nums Arrays.stream(nums)// 将IntStream中的int元素转换&#xff08;装箱&#xff09;为…

FRPC+PHP+MYSQL+APACHE2=个人网站

应用背景有公网需求,但是又不想去买又贵又低配置的服务器,然后方案就应运而生 frp/README_zh.md at dev fatedier/frp (github.com) 在这里, FRPC作为内网穿透服务, PHPMYSQLAPACHE2,作为网站搭建,具体细节不细讲, 但是在我的/var/www/html下面 linaroHinlink:/var/www/h…

17_c/c++开源库 easylogging日志库

1.简介与安装 简介: EasyLogging的主要特点包括&#xff1a; 简单易用&#xff1a;EasyLogging的API设计简洁明了&#xff0c;使用起来非常方便。开发者只需包含头文件并初始化库&#xff0c;即可开始记录日志。 高效性&#xff1a;EasyLogging采用异步日志记录方式&#xff…

CSS3新增特性(二)

四、2D 转换 • 属性名&#xff1a;transform &#xff08;可用于制作2D转换&#xff0c;也可用于制作3D转转换&#xff1b;2D转换是平面上的转换&#xff0c;3D转换是在三维立体空间的转换&#xff09; • 作用&#xff1a;对元素进行水平或垂直方向的移动、缩放、旋转、拉长…

stable diffusion QA

Q&#xff1a;有关于扩散模型的一个点不太懂&#xff0c;就是损失为何是去噪Unt的输出跟随机噪声的均方差&#xff1f;假如是图像修复任务&#xff0c;那为何不是去噪结果与真实图像进行损失计算呢&#xff1f; A&#xff1a;扩散模型simple loss将U-Net的输出与随机噪声计算M…

原生小程序自定义vantUI中van-collapse手风琴组件的标题

可以根据官网的提示&#xff1a; Vant Weapp - 轻量、可靠的小程序 UI 组件库 自己做的&#xff1a; <van-collapse accordion value"{{ activeName }}" bind:change"onChange"><van-collapse-item name"{{index}}"><!-- 这是自…

二. 搭建Nginx 直播流程服务器

目录 1. 前言 2. 安装 Nginx 依赖 3.下载源码 4. 编译安装 5.配置 rtmp 服务 6.验证配置 1. 前言 服务器由 NGINX+RTMP 构成。 NGINX 是 HTTP 服务器, RTMP 是附加模块。 其中 NGINX 我选择的是用 源码编译方式 进行安装,因为这种方式可以自定义安装指定的…

React 之 内置方法setState改变state(一)

简述 this.setState 方法是React组件类&#xff08;React.Component 的子类&#xff09;的一个内置方法。当你在创建一个React组件类时&#xff0c;你继承自 React.Component&#xff0c;因此你的组件类会自动获得this.setState 方法。this.setState 用于更新组件的state。当st…

DevOps(八)Jenkins的Maven和Git插件

一、Maven简介 Maven是一个构建生命周期管理和理解工具&#xff0c;用于Java项目。它提供了标准化的构建流程&#xff0c;并简化了从项目编译到文档生成等各种构建方面的管理。 Maven是由Apache软件基金会开发和维护的一个流行的项目管理工具。它的设计目的是简化Java项目的构…