xhs-web校验流程分析

news2025/2/20 22:19:55

经测试,cookie中需携带gid和timestamp2。参数整理有点乱,仅供参考。

xhsFingerprintV3VERSION: ‘2.1.2’


文章目录

    • 流程概述
    • timestamp2
    • 滑块验证参数
      • Params
      • 轨迹FN
    • captcha deviceId
    • ProfileData
    • x-s-common
        • x5生成
        • x8生成
        • x9生成
    • smidV2
    • a1
    • x-b3-traceid
    • x-sign
    • gid


在这里插入图片描述


流程概述

初次无cookie访问,先由 fe_api/burdock/v2/shield/registerCanvas?p=cc 接口返回 timestamp2。
在这里插入图片描述

gid 和 gid.sign 参数由 /fe_api/burdock/v2/shield/profile 接口返回。
在这里插入图片描述
此时的gid未经过验证校验,不可使用。

然后由 /ca/v1/register 接口注册验证码。
在这里插入图片描述
返回rid和验证码信息。

接着由 /ca/v2/fverify 接口提交验证信息。
在这里插入图片描述

验证后携带 cookie和 deviceId 信息,由 /fe_api/burdock/v2/shield/captcha?c=pp 接口认证设备和cookie信息。

在这里插入图片描述
验证成功后,携带gid和timestamp2可正常访问。


timestamp2

timestamp2和上个版本相同,不重复写了。
在这里插入图片描述

xhr定位即可。
在这里插入图片描述

在这里插入图片描述

sign = l(“G89CfW4k”, t,base64_t);

id = md5 ( sign + “RRq9y03tuV”)


滑块验证参数

Params

_0x225e91, _0xffa132 分别是DES加密时用到的 string 和 key
在这里插入图片描述

可复制到在线加密工具中测试,string为0.05,key为8bf2ae7b,加密结果和浏览器返回结果相同。

在这里插入图片描述

DES加密算法,模式ECB,填充 ZeroPadding,无iv。


轨迹FN

在这里插入图片描述

移动距离 253 。
在这里插入图片描述

轨迹参数用Des解密后,可发现最后一组数是拖动的距离。


captcha deviceId

最后 shield/captcha?c=pp 验证时需要用到 deviceId 。

SMSdk.getDeviceId()

在这里插入图片描述

在这里插入图片描述

getDeviceId()方法
在这里插入图片描述
在这里插入图片描述
可见_0x622d0e 还未加密,

在执行_0x645c91[_0x36bd7e(0x1c0)](_0x54a23b, _0x301c7f, _0x5deb6b);之后,返回了加密的 deviceId


ProfileData

shield/profile 注册gid时要用到profileData。

定位调试。
在这里插入图片描述
在这里插入图片描述

'{"x1":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36","x2":false,"x3":"zh-CN","x4":24,"x5":8,"x6":1,"x8":20,"x9":"1920;1080","x10":"1920;1040","x11":-480,"x12":"Asia/Shanghai","x13":true,"x14":true,"x15":true,"x16":false,"x17":true,"x18":"unknown","x19":"Win32","x20":"unknown","x21":"PDF Viewer,Portable Document Format,application/pdf,pdf,text/pdf,pdf;Chrome PDF Viewer,Portable Document Format,application/pdf,pdf,text/pdf,pdf;Chromium PDF Viewer,Portable Document Format,application/pdf,pdf,text/pdf,pdf;Microsoft Edge PDF Viewer,Portable Document Format,application/pdf,pdf,text/pdf,pdf;WebKit built-in PDF,Portable Document Format,application/pdf,pdf,text/pdf,pdf","x22":"10cfbbb02b2606dbc2ccb15a3cd2b558","x23":false,"x24":false,"x25":false,"x26":false,"x27":false,"x28":"0;false;false","x29":"4;7;8","x30":"swf object not loaded","x31":"124.04347527516074","x32":"id=;gid=a0034395f52573a18eca1fa7063d8fdcfc49bdd8deeb6a38a3db74db970fb504;audioinput;;id=;gid=a0034395f52573a18eca1fa7063d8fdcfc49bdd8deeb6a38a3db74db970fb504;audiooutput;","x33":0,"x34":0,"x35":0,"x36":1,"x37":"0|0|0|0|0|0|0|0|0","x38":"0|0|0|0|1|0|0|0|0|0"}'

代码比较简单,扣下来调用就行。

在这里插入图片描述

但是注意下提交的参数,x22是canvas,要和注册timestamp2的一致,x32是动态值。

在这里插入图片描述

x32的gid是指webRTC中本地媒体MediaDevice的groupId,和cookie中的gid不同。
在这里插入图片描述
查看chrome的enumerateDevices:

navigator.mediaDevices.enumerateDevices()
  .then((list) => {
    console.log(list);
  });

这个Id每次访问会变更,可以自己随机生成一串。

所在设备在被限制时,可更换canvasId和enumerateDevices的Id。


x-s-common

x-s-common用的地方比较多,注册和校验都需要。

x-s-common定位。

在这里插入图片描述

x-s-common的生成主要依赖cookie中的smidV2,其他参数如下。

在这里插入图片描述

x5: Dt.a.get(“a1”),
x8: localStorage.getItem(“b1”),
x9: fn(P()(t = P()(n = “”.concat®).call(n, o)).call(t, localStorage.getItem(“b1”)))


x5生成

x5依赖cookie的a1参数

document = {}
document.cookie = 'smidV2=202210181839545813c4484407e8fd7dec32a81165dfce00c99e85a19023ff0; a1=1843b69be841gkjrtg498n4cr8tw29sxm8l4mk2cs00000809560; gid=yY4qDKjDSq68yY4qDKjDdYTJY4ykTVF9k4jY1SMI4SFY9488EJjMC6888Y8j2K88JfjSJK2y'

n = {
    read: function(e) {
        return '"' === e[0] && (e = e.slice(1, -1)),
        e.replace(/(%[\dA-F]{2})+/gi, decodeURIComponent)
    },
    write: function(e) {
        return encodeURIComponent(e).replace(/%(2[346BF]|3[AC-F]|40|5[BDE]|60|7[BCD])/g, decodeURIComponent)
    }
}
function x5_get(e) {
    if ("undefined" != typeof document && (!arguments.length || e)) {
        for (var t = document.cookie ? document.cookie.split("; ") : [], r = {}, o = 0; o < t.length; o++) {
            var i = t[o].split("=")
              , a = i.slice(1).join("=");
            try {
                var s = decodeURIComponent(i[0]);
                if (r[s] = n.read(a, s),
                e === s)
                    break
            } catch (c) {
                console.log(c)
            }
        }
        return e ? r[e] : r
    }
}

console.log("x5:",x5_get("a1"))

x8生成

定值 localStorage.getItem(“b1”)
在这里插入图片描述

x9生成

x9简化之后就是 fn(localStorage.getItem(“b1”))
在这里插入图片描述
主要生成代码如下:(部分太长的代码段没贴,如tn、cn、rn、en)

var fn = function(e) {
        for (var t, n, r = 240, o = 253, i = 258, a = 197, s = 264, c = 230, u = 209, l = 262, f = 237, p = 261, d = en, h = {
            zDTTc: function(e, t) {
                return e === t
            },
            nrqZm: d(251),
            MyaJd: function(e, t) {
                return e < t
            },
            fqoGO: function(e, t) {
                return e ^ t
            },
            qcRcu: function(e, t) {
                return e ^ t
            },
            yhYKD: function(e, t) {
                return e & t
            },
            qxGVA: function(e, t) {
                return e >>> t
            },
            jTaFf: function(e, t) {
                return e ^ t
            },
            kQlol: function(e, t) {
                return e >>> t
            }
        }, v = 256, m = []; v--; m[v] = t >>> 0)
            for (n = 8,
            t = v; n--; )
                t = 1 & t ? 3988292384 ^ h['kQlol'](t, 1) : h['kQlol'](t, 1);
        return function(e) {
            var t = d;
            if (h['zDTTc']('string', h['nrqZm'])) {
                for (var n = 0, r = -1; h['MyaJd'](n, e['length']); ++n)
                    r = h['fqoGO'](m[h['qcRcu'](h['yhYKD'](r, 255), e['charCod' + 'eAt'](n))], h['qxGVA'](r, 8));
                return h['qcRcu'](h['jTaFf'](r, -1), 3988292384)
            }
            for (n = 0,
            r = -1; n < e['length']; ++n)
                r = m[h['jTaFf'](255 & r, e[n])] ^ h['qxGVA'](r, 8);
            return -1 ^ r ^ 3988292384
        }
    }()

var x9 = fn("8utvIv7eYlPiIvcmIk0sxn5e6D3s0PwfQ0MAHZFRICH0+VthIhDaNom3nqt9aPwjI3LdKU7e3BkLmbPH+LENaqwMIkveTb5sVBAefVt18WukpqtVeVt4muw4IC6sx7YEIE3e0/Kekf6e0WPP87MfPMdsxVw/IhWNICu=")
console.log("x9:",x9)

smidV2

hook cookie。hook代码可到 工具站 查找。

在这里插入图片描述
定位分析,
在这里插入图片描述

在注册设备id过程中,_0x622d0e时生成了smidV2
在这里插入图片描述
这样看,deviceId 和x-s-common参数有关联关系。


a1

生成 x-s-common 时需要a1,注册sig时也需要。

a1用hook插件hook。
在这里插入图片描述

在这里插入图片描述
a1 = M
在这里插入图片描述
M = P()(S = “”.concat(I)).call(S, N).substring(0, 52)

格式化一下

var j, A, k, C, S, R = 0, E = "000", 
    I = P()(j = P()(A = P()(k = P()(C = "".concat((+new Date).toString(16))).call(C, zt(30))).call(k, R)).call(A, 0)).call(j, E), 
    N = sn(I), 
    M = P()(S = "".concat(I)).call(S, N).substring(0, 52);

代码段翻译一下,先生成I,I = “”.concat((+new Date).toString(16)) + 随机30个字符 + 00000
再生成N, N = sn(I)
最后M = (I +N).substring(0, 52)

a1生成代码

function rn() {
  var e = ["bdXdq", "length", "susu", "zDTTc", "q42KWYj", "xLgpd", "0DSfdik", "nFsLu", "30jemUol", "fHjkg", "saFEz", "hECvuRX", "HjBDl", "yhYKD", "x3VT16I", "EYvYO", "pKSXB", "bnEJJ", "pngG8yJ", "oHQtNP+", "rQkvJ", "ETash", "suu", "5843672pCKTGz", "ZmserbB", "3044202AJYnvI", "8973318KqrDXr", "HQdfx", "bYHmD", "14nymtFk", "lGBrI", "sussusu", "join", "charCod", "qcRcu", "FoGzb", "XitqP", "JPbAI", "1171539qrVTtq", "ZuEEa", "BeOkX", "qxGVA", "alAuw", "qTmwS", "kQlol", "WeSiH", "auZwG", "BcSKa", "99515NEInyQ", "lUAFM97", "mVZzE", "284tzkRbL", "wOcza/L", "IXpoi", "nxSCy", "string", "Xcesv", "nrqZm", "6045636qIaDIN", "fromCha", "HWcOv", "2MGcsTE", "MyaJd", "99oQgoiy", "350367CQNruQ", "jTaFf", "eAt", "pbhrw", "fqoGO", "rCode", "lJSzd", "NshPR", "LREye", "push", "HyBFO", "charAt", "ZcEyb", "Mduoa"];
  return e
}

function en(e, t) {
        var n = rn();
        return (Yt = function(e, t) {
            return n[e -= 191]
        }
        )(e, t)
}

var sn = function(e) {
    for (var t, n = 268, r = 194, o = 233, i = 197, a = en, s = {
        nxSCy: function(e, t) {
            return e & t
        },
        LREye: function(e, t) {
            return e ^ t
        },
        ZcEyb: function(e, t) {
            return e >>> t
        },
        JPbAI: function(e, t) {
            return e >>> t
        },
        alAuw: function(e, t) {
            return e ^ t
        }
    }, c = [], u = 0; u < 256; u++) {
        t = u;
        for (var l = 0; l < 8; l++)
            t = s['nxSCy'](1, t) ? s['LREye'](3988292384, s['ZcEyb'](t, 1)) : s['JPbAI'](t, 1);
        c[u] = t
    }
    for (var f = -1, p = 0; p < e['length']; p++)
        f = s['alAuw'](s['JPbAI'](f, 8), c[s['nxSCy'](255, s['alAuw'](f, e['charCod' + 'eAt'](p)))]);
    return s['JPbAI'](-1 ^ f, 0)
};

var lx1 = '';
  for (i = 0; i < 30; i++) {
    lx1 += "abcdefghijklmnopqrstuvwxyz1234567890"[Math.floor(36 * Math.random())]
  }

var I = "".concat((+new Date).toString(16))+lx1+"00000"

console.log(I)
console.log(sn(I))
console.log((I+sn(I)).substring(0, 52));

x-b3-traceid

.在这里插入图片描述
翻译为python代码。

import random,math
e = ""
for t in range(16):
    e+="abcdef0123456789"[math.floor(16 * random.random())]
print(e)

x-sign

目前来看同url的x-sign是固定的

‘https://www.xiaohongshu.com/fe_api/burdock/v2/shield/captcha?c=pp’

def get_xsign(url):
    screen_key = "WSUDD"
    _st = url.split(".com")[-1] + screen_key
    import hashlib
    m = hashlib.md5()
    m.update(_st.encode(encoding='UTF-8'))
    md5String = m.hexdigest()
    return "X" + md5String

gid

gid 和 注册时的 IP 绑定。需要x-s-common和profileData

通过 /fe_api/burdock/v2/shield/profile接口注册。
在这里插入图片描述
先本地生成 smidV2和a1。
然后生成headers中的 x-s-common 、 x-b3-traceid 、x-sign。
接着生成profileData。
最后构建请求注册gid。

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

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

相关文章

Jenkins配置linux节点

之前在Windows下安装Jenkins 但是通过windows节点进行构建有诸多的不便&#xff0c;于是想到通过Jenkins里添加linux节点&#xff0c;让构建的时候&#xff0c;使用远程的linux服务器构建 目录一、配置凭据二、配置节点一、配置凭据 Manage Jenkins → Manage Credentials→Je…

Cadence Allegro PCB设计88问解析(十三) 之 Allegro中artwork层的建立

一个学习信号完整性的layout工程师 作为layout工程师&#xff0c;我们经常接触到的是PCB文件&#xff0c;用Cadence设计的是.brd文件。但是我们发给板厂的都是gerber文件。这就涉及到在我们设计好PCB文件之后&#xff0c;怎么把这些文件给到板厂。也就是我们Allegro中的artwork…

Java知识点--IO流(上)

Java知识点--IO流&#xff08;上&#xff09;一、文件1、文件的含义2、文件流二、常用的文件操作1、创建文件对象相关构造器和方法2、创建文件案例演示&#xff08;三种创建方法&#xff09;3、获取文件相关信息的方法4、获取文件相关信息方法案例演示5、目录的操作与删除6、应…

电脑系统重装下载的系统在哪找到

​因为现在很多人都在使用小白一键重装系统&#xff0c;但是很多人都不太能够了解小白系统重装下载的系统在哪儿&#xff0c;下面是小编提供的具体位置供大家参考。 工具/原料&#xff1a; 系统版本&#xff1a;win10 品牌型号&#xff1a;联想yoga13 软件版本&#xff1a;小白…

期货开户有什么规定

有很多朋友刚刚接触到资本市场&#xff0c;当他们听到期货时&#xff0c;他们觉得它非常遥远和高端&#xff0c;这是普通人无法接触到的。但事实上&#xff0c;情况并非如此。期货是一种非常普通的金融产品&#xff0c;很容易接触。让我们来看看期货开户有哪些必要条件以及有什…

postman环境变量的设置

背景&#xff1a;由于我们项目接口入参都有加密&#xff0c;每次接口调试都得启动项目&#xff0c;运行项目才能把对应的参数给传到后台&#xff0c;然后后台再解密参数&#xff0c;才能进行接口调试&#xff0c;很麻烦&#xff08;启动前端项目&#xff09;&#xff0c;如果接…

Linux篇【3】:Linux环境基础开发工具使用(中)

目录 一、Linux 编译器&#xff1a;gcc/g 的使用 1.1、知识拓展&#xff1a; 1.2、如何安装 C/C 标准静态库&#xff1a; 1.3、头文件与库文件&#xff1a; 1.4、静态库&#xff0c;静态链接&#xff0c;动态库&#xff0c;动态链接&#xff1a; 二、简单 vim 配置 2.1、…

【SpringBoot】一文了解SpringBoot热部署

文章目录前言手动启动热部署热部署种类手动进行热部署自动启动热部署热部署范围配置热部署的关闭总结&#x1f315;博客x主页&#xff1a;己不由心王道长&#x1f315;! &#x1f30e;文章说明&#xff1a;一文彻底搞懂SpringBoot热部署&#x1f30e; ✅系列专栏&#xff1a;Sp…

深入理解Java虚拟机:Java类的加载机制

本篇内容包括&#xff1a;Java 类的加载机制&#xff08;Jvm 结构组成、Java 类的加载&#xff09;、类的生命周期&#xff08;加载-验证-准备-解析-初始化-使用-卸载&#xff09;、类加载器 以及 双亲委派模型。 一、Java 类的加载机制 1、 Jvm 结构组成 Jvm 整体组成可分为…

坤坤音效键盘(Python实现)

文章目录坤坤音效键盘说明坤坤音效键盘效果展示代码实现安装第三方库准备音频监听键盘播放音频编写逻辑引入线程打包成exe程序坤坤音效键盘说明 坤坤音效键盘说明&#xff1a; 单独按下 j、n、t、mj、n、t、mj、n、t、m 按键&#xff0c;会对应触发 “鸡”、“你”、“太”、…

科技视界杂志科技视界杂志社科技视界编辑部2022年第21期目录

科技视界杂志科技视界杂志社科技视界编辑部2022年第21期目录 科普论坛《科技视界》投稿&#xff1a;cnqikantg126.com 天敌昆虫——让农业生产更安全 季香云; 1-3 储粮昆虫三维模型Web可视化技术研究与应用 阎磊;马宏琳;李亮;李鹏翔;王义超; 4-6 科学实验 非均匀催…

wy的leetcode刷题记录_Day33

wy的leetcode刷题记录_Day33 时间&#xff1a;2022-11-4 目录wy的leetcode刷题记录_Day33754. 到达终点数字题目介绍思路代码收获199. 二叉树的右视图题目介绍思路代码收获754. 到达终点数字 今天的每日一题是&#xff1a;754. 到达终点数字 题目介绍 在一根无限长的数轴上…

CSS:变量函数var和自定义属性

文章目录CSS变量var()函数CSS变量 CSS变量分为两部分&#xff1a;变量声明和变量使用。 变量的声明是由CSS自定义属性和对应的属性朱组成的&#xff0c;比如&#xff1a; :root {--custom-color: deepskyblue;}在这段代码中&#xff0c;–custom-color是属于css的自定义属性名…

方法的使用

目录 1. 举例说明什么叫方法 2. 方法概念及使用 2.1 什么是方法(method) 1.2 方法定义 1.3 方法调用的执行过程 1.4 实参和形参的关系(重要) 2. 方法重载 2.1 为什么需要方法重载 2.3 方法签名 3. 递归 递归执行过程分析 1. 举例说明什么叫方法 我们利用面向对象的方…

2022年特色小镇行业研究报告

第一章 行业概况 特色小镇是在几平方公里土地上集聚特色产业、生产生活生态科技相融合、不同于行政建制镇和产业园区的创新创业平台。根据类型的不同&#xff0c;特色小镇可以分为三类&#xff0c;即产业类、社区类和旅游类。 产业类&#xff1a;通过招商引资吸引企业进入&…

门控循环单元(GRU)【动手学深度学习v2】

理论 候选隐藏状态。 圆圈 表示 按元素乘法。 这里面的 这个符号值得是 按元素相乘。 Rt理解为 和Ht 长度一样的一维向量。&#xff08;这么理解&#xff09; 这里如果Rt长的像0的话&#xff0c;那么乘出来的结果&#xff0c;就也像0。 要是像0 的话&#xff0c;相当于是说…

文件操作之文件系统

目录 一 磁盘 1 磁盘的物理结构 2 磁盘在物理结构上如何存储数据 CHS寻址 3 从物理结构到抽象结构 LBA寻址 4管理 二 块组 boot block super block inode table data blocks block bitmap GDT&#xff1a;Global Descriptor Table 块组描述符 三 文件名和目录之…

网课查题接口搭建

网课查题接口搭建 本平台优点&#xff1a; 多题库查题、独立后台、响应速度快、全网平台可查、功能最全&#xff01; 1.想要给自己的公众号获得查题接口&#xff0c;只需要两步&#xff01; 2.题库&#xff1a; 查题校园题库&#xff1a;查题校园题库后台&#xff08;点击跳…

字符串匹配算法(C/Java实现)

目录BF算法C语言实现Java实现KMP算法Java实现C语言实现next[]数组的优化BF算法 BF算法&#xff0c;即暴力(Brute Force)算法&#xff0c;是普通的模式匹配算法&#xff0c;BF算法的思想就是将目标串S的第一个字符与模式串T的第一个字符进行匹配&#xff0c;若相等&#xff0c;…

R语言代做实现:混合正态分布EM最大期望估计法

全文链接&#xff1a;http://tecdat.cn/?p4815 原文出处&#xff1a;拓端数据部落公众号 因为近期在分析数据时用到了EM最大期望估计法这个算法&#xff0c;在参数估计中也用到的比较多。然而&#xff0c;发现国内在R软件上实现高斯混合分布的EM的实例并不多&#xff0c;大多…