ks滑块逆向及流程分析

声明

本文章中所有内容仅供学习交流使用,不用于其他任何目的,不提供完整代码,抓包内容、敏感网址、数据接口等均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关!

介绍

想做快手的数据采集需要解决一个 did,这个 did 会由请求页面直接返回,但是却不能直接使用,需要后续发包激活。而只要滑过验证码,携带返回的 captchaToken 去请求数据,不仅能够拿到正确结果,还能激活 did 进行后续使用。所以,做ks数据采集,过验证码还是很有必要的,且验证码逆向难度不是很大,也可以当做练手项目来学习。

逆向目标

拿到一个视频链接,打开后清缓存,刷新就会出现滑块。抓包随便滑一下,可以看到验证接口为 captcha/sliding/kSecretApiVerify

此接口只有一个参数 verifyParam ,那么本次目标就是分析此参数是如何生成的。

分析

通过搜索 verifyParam 可以快速定位到加密点。

在这里插入图片描述

可以看到加密点在一个平坦流中,那么我们的断点可以打在 switch 语句上,一步步进行调试。

分支 0

首先进入分支 0,分支 0 中执行了一个语句 i[Jt("0x34")](Tt["a"], c);

其中 Tt["a"] 是一个函数,c 则是一个对象,里面有许多明文数据。我们先分析 c 的内容

c 内容分析
{
    "captchaSn": "Cgp6dC5jYXB0Y2hhEtgCyWw9CbLiBYsQuiKZDriENd0wgRuOcpjp18c0mLiC-KGoQc4cg8PMrLW7UnOEVg1xHeCTP6m6R2PreatN3qSRwN3OF2u50S0b4WdZjTHjP6zRH6fJSEuif21DnFRelxFCKqEosJLc1bCykcCrp2dEAm6oMofzkY8hSHhlNHmObaey7pz9bf6OELLjWYTwsEXo4SwX7oRxYqAEldaioef8sf9RIRcvEaBOy8I_Jr2Cug91PkogroYtHG5SQBk_kbjH4w8vSnJ06Lj3k0zTjbPYmVwk5hsbpzpARp7o7vjWf_ef1t9eisjPreKz0x2LZVMogVcFXwIDcnRr4tKyTZgu7SkHjKHEioot-J6F2mnWkR7eo7bqGVen4sYA7nCWL_B0EWrGxVbPMQ_RDwKql4113uC6mCEr-STsJcuXlbTYFO1rgTc327bsqvhADEKW48a1p7QEGOZ-OCcaEleIHYY8IfeWArTHzyF818xZgigFMAI",
    "bgDisWidth": 316,
    "bgDisHeight": 184,
    "cutDisWidth": 56,
    "cutDisHeight": 56,
    "relativeX": 165,
    "relativeY": 58,
    "trajectory": "3|24|0,7|24|14,10|24|15,14|24|17,18|24|22,21|24|23,25|24|26,28|24|31,32|24|32,225|112|35,39|24|39,43|24|41,47|24|44,50|24|51,54|24|52,54|23|55,57|23|55,61|23|62,341|111|64,68|23|69,72|23|78,76|23|80,79|23|82,83|23|88,86|23|90,90|23|92,94|23|98,469|111|100,101|23|103,105|23|111,108|23|112,112|23|113,115|23|123,119|23|127,123|23|134,126|23|177,601|111|178,134|23|180,137|23|185,141|23|187,144|23|188,144|24|192,148|24|192,152|24|194,155|24|195,717|112|197,163|24|198,166|24|200,170|24|202,173|24|203,177|24|204,181|24|207,188|24|208,192|24|210,861|112|212,199|24|213,202|24|215,206|24|216,210|24|217,213|24|218,217|25|221,221|25|222,224|25|224,993|113|224,231|25|226,235|25|228,239|25|230,242|25|231,246|25|234,250|25|234,253|25|235,257|25|237,1121|113|239,264|25|239,268|25|242,271|25|242,275|25|244,278|25|246,282|25|248,286|25|248,289|25|250,1253|113|250,297|25|252,300|25|254,304|26|254,307|26|256,311|26|258,318|26|259,322|26|261,326|26|262,1397|114|263,333|26|264,340|26|264,347|26|267,351|26|267,355|26|269,362|26|270,369|26|272,373|26|272,1585|114|274,384|26|274,387|26|276,391|26|277,398|26|278,402|26|279,409|26|280,413|26|281,420|26|282,1773|114|282,431|26|284,434|26|285,442|26|286,445|26|287,452|26|287,456|26|288,460|26|290,467|26|291,1965|114|291,474|26|294,485|26|295,489|26|296,496|26|298,500|26|298,503|26|299,507|26|300,510|26|301,2153|114|303,521|26|304,525|26|304,528|26|305,532|25|306,539|25|309,543|25|310,550|25|313,554|25|315,2309|113|318,561|25|320,565|25|323",
    "gpuInfo": "{\"glRenderer\":\"WebKit WebGL\",\"glVendor\":\"WebKit\",\"unmaskRenderer\":\"ANGLE (NVIDIA, NVIDIA GeForce GTX 1050 Ti Direct3D11 vs_5_0 ps_5_0, D3D11)\",\"unmaskVendor\":\"Google Inc. (NVIDIA)\"}",
    "captchaExtraParam": "{\"ua\":\"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36\"xxx"
}

c 的值比较重要,我们逐个讲解。

captchaSn

captchaSn 的值是由接口 captcha/sliding/config 返回的,该接口包含了验证码图片信息。

在这里插入图片描述

而请求该接口也需要提交一个参数 captchaSession。不用担心,此参数也是在该请求之前的接口中返回的。不过此参数包含一个小坑,很有迷惑性,我们下文再讲。

在这里插入图片描述

bgDisWidth|bgDisHeight|cutDisWidth|cutDisHeight

这个值分别为验证码背景图片长宽以及缺口的长宽,为固定值。

relativeX|relativeY

relativeX 为滑动距离,relativeY 为 captcha/sliding/config 接口中 disY 的值乘以 0.46 得来。

trajectory

这个很明显就是滑动轨迹了,由 x轴|y轴|时间 组成。滑动轨迹的生成也是比较棘手的,下文再讲。

gpuInfo|captchaExtraParam

这两个为设备指纹,可以直接固定。

我们接着分析加密流程。

分支 0 中会进入到 return e.Ueadz(n, t) 中,我们接着往下跟,会进入另一个函数中。i[Jt("0x34")](Tt["a"], c); 实际为 Tt["a"](c);

继续往下跟,会进到一个新的平坦流中。

在这里插入图片描述

这部分主要是对 c 的值进行序列化、转 Uint8Array。

继续往下跟会进到一个 Promise 中,也是本次逆向最关键的地方。

Jose 分析
new Promise((function(t, c) {
    Jose[r("0x2a")](n[r("0x28")], [e, l, {
        suc: t,
        err: c
    }])
}
))

这段代码的作用是创建一个 Promise 对象,并通过调用 Jose 对象的方法,将传递给 Promise 构造函数的成功和失败处理函数 tc 作为参数传递给该方法。

其中 n[r("0x28")]l 的值为固定的,e 则是上面对 c 处理后的值。

我们继续往下走的话会进到另一个文件中。到这里后,跟值就变得比较麻烦了。我们观察代码结构可以发现这是一个经过 webpack 打包后的代码,那么我们就可以使用最简单的方法,全局导出来解决这个问题。

在这里插入图片描述

我们知道最终加密参数的值由 Jose[r("0x2a")] 生成,所以我们需要拿到 Jose。通过搜索关键字我们可以找到

在这里插入图片描述

观察代码结构,这是一个自执行函数。结构如下

!function(r, o) {
                "object" == ("undefined" === typeof exports ? "undefined" : n(exports)) && "object" == n(t) ? t.exports = o() : "function" == typeof define && e("3c35") ? define([], o) : "object" == ("undefined" === typeof exports ? "undefined" : n(exports)) ? exports.Jose = o() : r.Jose = o()
            }(window, (function() {xxx})

exports.Jose = o()Jose 的值为参数 o ,而 o 为一个方法。通过执行这段代码,就可以得到 Jose 。这里我们将代码修改一下,为:

window = {}
!function(r, o) {
                window.Jose = o()
            }(window, (function() {xxx})

​ 这样我们执行完后就可以直接通过 window.Jose 来调用加密方法。当我们执行时会报一个错误 。ReferenceError: n is not defined

我们缺了一个 n方法,将它补上即可。

在这里插入图片描述

最后调整一下调用代码:

async function encrypt(e) {
    var l = "c7b645db-65e8-401f-b38c-4c07c5fff247";
    var n = {};
    console.log(e)
    return n.uNXrD = "$encrypt",
        new Promise((function (t, c) {
                window.Jose.call(n.uNXrD, [e, l, {
                    suc: t,
                    err: c
                }])
            }
        ))
}

到这里,最关键的部分就基本结束了,这段异步代码会返回一个长度与 e 相近的数组。

然后就是新平坦流剩余的部分。

在这里插入图片描述

这部分是对生成的数组进行处理,将数组转为 Uint8Array,然后对每个元素进行按位与操作。

var sent_ = new Uint8Array(sent_length)
for (var c = 0; c < sent_length; c += 1)
    sent_[c] = 255 & sent[c];

最后将新数组进行 base64 编码,到这里整个加密流程就结束了。

细节讲解

验证码图片信息获取

上文中我们提到了获取 captchaSession 时有一个小坑,就是这个参数值的获取有两种情况。

一般 captchaSession 可以从评论数据等接口中拿到,/graphql

但是这个接口会有两种响应信息,如下:

{‘errors’: [{‘message’: ‘Need captcha’…
{‘data’: {‘result’: 400002,

两种响应内容中都包含 captchaSession ,但是只有第一种的 captchaSession 是有效的。如果使用的是 400002 的 captchaSession ,即使过了滑块,拿到的 captchaToken 也是无法使用的。

轨迹

轨迹应该是ks最难处理的问题了,代码模拟随机生成的轨迹基本无法使用,重放轨迹验证,同一坐标相同的轨迹也无法使用,也就是一个轨迹只能用一次。
350014 基本上就是轨迹问题。
轨迹生成我尝试过多种方法:

随机生成:普通生成相似轨迹,基本无法使用,通过率10%以下。
缩放法:取一个真实轨迹,再根据当前缺口位置进行缩放,通过率30%左右。
缓动函数:通过率90%左右
自建轨迹库:手动录入真实轨迹,再对真实轨迹进行随机偏移,通过率80%左右,也是我在使用的方法。

关于轨迹可用率很低这种情况,我也怀疑是自己遗漏了某些细节导致。

响应信息

成功:

{'result': 1, 'desc': 'ok', 'unifiedType': 2, 'captchaToken': 'HEADCgp6dC5jYXB0Y2hhEskC0WTsg4gi79naGkKCVH985uiGGP-nkHVb8r3mqAFKXFntcP42UDrKFfe2QlEOWjDJAUXDPU4MO960Yi1joyLWHT14972aSw_lbfYnr3NbY7HmYPLzwnsMg95Q5NASCXHSaTpzyyNt_MJLmIbkzg_8Wm3dvia82kNiUjbacF8gXthNo1XzmTlxcSDbT-2vsEmtC1sIP9PKx6OL105PVHCwELO8-Ax2RP3kfHfH3uBXg3P0CmFlXiLuSRpM0xB41RXuuznO6bw6Dox4LZkPGvijL5YtPZOBCgAlykW8J7Y1fh-JNt79WKIN4A16oS89sLr8jt6tIdnmFNncnmjGKya1MkCtEQ7qHcP_uyrwaV3k5Is9Cra3gnslM1huvA2x8GD521Sn-dXNsjRkb2dG6cPbre2lk0N8JURgItzl2bjjKKqCimS0-VjszscaElTx5qdOA_0N2qfb3EUSeB2MrygFMAITAIL'}

轨迹问题:

{'result': 350014, 'desc': 'anti check err, try to get a new captchaSN to verify', 'unifiedType': 2}

加密参数生成错误:

{'result': 350005, 'desc': 'captchaSN err', 'unifiedType': 2}

缺口识别问题:

{'result': 350002, 'desc': 'verify err.try again', 'unifiedType': 2}

常见响应信息就是以上几种。

流程

基本流程如下:

1、请求内容页获取 did

2、graphql 通过该接口获取验证码相关信息,可以从评论中获取。

3、请求验证接口,获取 captchaToken

4、携带 captchaToken,请求一次内容接口

完成这几步后 did 就处于激活状态了,可以重复使用一段时间。

  • 10
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 36
    评论
好的,我明白了。关于你的问题,计算KS值和绘制KS曲线是大数据分析中常用的方法,Python也提供了相应的库来实现。下面是一些示例代码,可以用来计算KS值和绘制KS曲线。 首先,我们需要导入相关的库: ```python import pandas as pd import numpy as np import matplotlib.pyplot as plt from scipy import stats ``` 接下来,我们需要读入数据,假设数据存在一个名为"data"的DataFrame中,其中包含了预测值和真实值两列: ```python pred = data['pred'] true = data['true'] ``` 然后,我们可以使用scipy库中的stats模块来计算KS值: ```python ks = stats.ks_2samp(pred[true == 1], pred[true != 1]).statistic ``` 这里,我们使用了ks_2samp函数来计算KS值,其中第一个参数是预测值中真实值为1的样本,第二个参数是预测值中真实值不为1的样本。函数返回的是KS值。 最后,我们可以使用matplotlib库来绘制KS曲线: ```python fpr, tpr, thresholds = metrics.roc_curve(true, pred) ks = max(tpr-fpr) plt.plot(thresholds, 1.-fpr, label='False Positive Rate') plt.plot(thresholds, tpr, label='True Positive Rate') plt.plot(thresholds, tpr-fpr, label='KS curve (KS=%0.2f)' % ks) plt.xlabel('Threshold') plt.legend(loc='best') plt.show() ``` 这里,我们使用roc_curve函数来计算真正率和假正率,然后根据不同的阈值绘制出KS曲线。函数返回的是三个数组,分别是假正率、真正率和阈值。我们可以从中计算出KS值。 这就是使用Python计算KS值并绘制KS曲线的方法。希望能对你有所帮助!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 36
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

BuerCC

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值