JS逆向解密教程3:某吧mouse_pwd鼠标轨迹加密算法完整解析

JS逆向解密教程3:某吧mouse_pwd鼠标轨迹加密算法完整解析

在某吧的发帖/回帖接口/f/commit/post/add中,除了我们《JS逆向解密教程1:某吧用户关注功能jt参数分析与解密》中分析过的jt参数《JS逆向解密教程2:贴吧发帖接口_BSK参数分析与解密》中分析过的_BSK参数外,mouse_pwd是请求体中的最后一个关键加密参数。这个参数记录了用户的鼠标行为轨迹,是某吧反爬机制的重要组成部分。掌握了它的生成方式,配合之前分析的参数,就能实现完整的API自动化发帖回帖功能。本章将详细分享mouse_pwd参数的JS逆向解密全过程。

本文目录

  1. 数据抓包:定位mouse_pwd参数
  2. 全局搜索:定位mouse_pwd生成位置
  3. 代码分析:理解MousePwd模块结构
  4. 核心函数:u()方法深度解析
  5. 最小化扣取:只提取u()函数依赖
  6. JS逆向解密扣代码
  7. 本地运行验证
  8. 常见问题与解决方案
  9. 获取完整课件
1. 数据抓包:定位mouse_pwd参数

在进行数据抓包实战时,打开浏览器开发者工具(F12),切换到Network面板并勾选”Preserve log”。在某吧中执行发帖或回帖操作,观察网络请求。

目标接口/f/commit/post/add的Form Data中包含三个关键参数:

  • mouse_pwd:鼠标轨迹加密数据(如:”61,61,1,1,0,4,2,61,5,13,6,4,24,5,4,12,4,17583472597520″)
  • mouse_pwd_t:时间戳
  • mouse_pwd_isclick:是否点击标志(0或1)
图1: 发帖接口中的mouse_pwd相关参数

在Sources面板使用Ctrl+Shift+F全局搜索mouse_pwd=,可以找到参数赋值的关键代码:

i._data.mouse_pwd = i.MousePwd.report().c,
i._data.mouse_pwd_t = i.MousePwd.time,
i._data.mouse_pwd_isclick = i.MousePwd.MOUSEPWD_CLICK,
搜索mouse_pwd=

通过断点调试,我们可以确认i.MousePwd.report().c就是生成mouse_pwd值的核心方法,其中report()方法对应的就是我们要分析的u()函数。

js逆向解密断点确认
3. 代码分析:理解MousePwd模块结构

MousePwd模块虽然包含多个函数,但我们只需要关注u()函数(即report()方法)及其直接依赖的函数。通过分析,我们发现u()函数调用了以下关键函数:

  • r():获取鼠标坐标信息
  • s():获取轨迹序列
  • f():加密函数

这些函数构成了mouse_pwd参数生成的核心逻辑链。

4. 核心函数:u()方法深度解析

u()函数是生成mouse_pwd的核心,其完整逻辑如下:

function u() {
    if (m) return c;
    var t = [
        r(), // 获取鼠标坐标
        s(), // 获取轨迹序列  
        (new Date).getTime() - this.UTSTART, // 时间差值
        [screen.width, screen.height].join(",") // 屏幕分辨率
    ].join("\t");
    
    return c.c = f(t) + "," + g + this.MOUSEPWD_CLICK,
    m = !0,
    c
}

该函数将四个维度的信息用制表符连接后进行加密:

  • 鼠标坐标:通过r()函数获取最后记录的鼠标位置
  • 轨迹序列:通过s()函数获取鼠标移动的01序列
  • 时间信息:从初始化到当前的时间差值
  • 设备信息:屏幕分辨率信息
5. 最小化扣取:只提取u()函数依赖

我们只需要扣取u()函数直接依赖的三个核心函数:

// 坐标获取函数
function r() {
    var t = h.ma.length;
    if (t > 0) {
        var e = h.ma[t - 1];
        return e[e.length - 1]
    }
    return "0,0" // 默认坐标
}

// 轨迹序列函数
function s() {
    var t = "", e = p.length;
    return e > 10 && (p = p.slice(e - 10)),
    t = p.join(",")
}

// 加密函数
function f(t) {
    for (var e = [], n = {}, o = g % 100, i = 0, r = t.length; r > i; i++) {
        var s = t.charCodeAt(i) ^ o;
        e.push(s),
        n[s] || (n[s] = []),
        n[s].push(i)
    }
    return e.join(',')
}

其中加密函数f采用了简单的异或加密算法,密钥为时间戳g对100取模的结果。

6. JS逆向解密扣代码

我们只需要实现u()函数及其依赖,在电脑上创建一个MousePwd.js代码如下:

class MousePwdSimulator {
    constructor() {
        this.UTSTART = Date.now();
        this.MOUSEPWD_CLICK = 1; // 默认为点击状态
        this.g = Date.now();
        this.m = false;
        this.c = {};
        
        // 模拟轨迹数据
        this.p = ['1', '0', '1', '1', '0', '1', '0', '1'];
        this.h = { ma: [[100, 200], [150, 250]] }; // 模拟鼠标坐标
    }

    // 坐标获取函数
    r() {
        if (this.h.ma.length > 0) {
            const lastPos = this.h.ma[this.h.ma.length - 1];
            return lastPos.join(',');
        }
        return "0,0";
    }

    // 轨迹序列函数
    s() {
        let sequence = this.p.join(',');
        if (this.p.length > 10) {
            this.p = this.p.slice(-10);
            sequence = this.p.join(',');
        }
        return sequence;
    }

    // 加密函数
    f(t) {
        const result = [];
        const key = this.g % 100;
        for (let i = 0; i < t.length; i++) {
            const encryptedChar = t.charCodeAt(i) ^ key;
            result.push(encryptedChar);
        }
        return result.join(',');
    }

    // 核心u函数
    u() {
        if (this.m) return this.c;
        
        const data = [
            this.r(), // 坐标
            this.s(), // 轨迹
            Date.now() - this.UTSTART, // 时间差
            '1920,1080' // 屏幕分辨率
        ].join('\t');
        
        this.c.c = this.f(data) + ',' + this.g + this.MOUSEPWD_CLICK;
        this.m = true;
        return this.c;
    }
}
// 正确导出类
module.exports = MousePwdSimulator;
7. 本地运行验证

创建测试文件验证加密结果:

// test.js
const MousePwdSimulator = require('./MousePwd);

const simulator = new MousePwdSimulator();
const result = simulator.u();

console.log('生成的mouse_pwd:', result.c);
console.log('时间戳:', simulator.g);
console.log('点击状态:', simulator.MOUSEPWD_CLICK);

// 在Node.js环境中直接运行验证
// 结果示例: "61,61,1,1,0,17583472597520,1"

运行node test.js即可看到生成的mouse_pwd参数,格式与浏览器中一致。

在node环境生成
8. 常见问题与解决方案
  • Q:生成的mouse_pwd与服务端验证不匹配
    A:检查屏幕分辨率、时间戳、轨迹序列等参数是否与真实环境一致
  • Q:如何模拟更真实的鼠标轨迹
    A:可以录制真实用户的鼠标移动轨迹数据,然后在代码中重放
  • Q:加密结果每次运行都不同
    A:正常现象,因为包含时间戳和随机轨迹数据
  • Q:是否需要完整的MousePwd模块
    A:不需要,只需要u()函数及其直接依赖的三个函数即可
9. 获取完整课件

关注公众号:孤狼网络科技,回复:mouse_pwd,获取完整代码课件和实战案例。

总结
通过本JS逆向教程,我们成功分析了某吧mouse_pwd参数的生成原理,掌握了最小化扣取代码的技巧。至此,我们已经解决了发帖接口请求体中的所有加密参数(jt、_BSK、mouse_pwd)。

下一步挑战:下一个需要攻克的参数是请求头中的acs-token,解决了这个参数后,就能实现完整的自动顶贴发帖功能了。本文由林石工作室提供技术支持。

Comments

No comments yet. Why don’t you start the discussion?

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注