banner
约 1,200 字
4 分钟

【JS逆向练习】极验三代滑块模式验证码逆向分析(下)

无标签

n[$_CJJJU(985)][$_CJJJU(1073)]()是生成轨迹的函数,进入分析下。

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

this[$_BEGJO(359)]就是轨迹,改造下函数,把轨迹当成参数传进去。

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

然后把其余代码扣下来,就完成了轨迹加密。

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

至此o还原完成,再把V函数和m函数扣下,报错缺什么再补下,h就还原成功了。

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

参考代码

JavaScript
var V = function () {
    var $_BADJt = mwbxQ.$_Cg,
        $_BADIa = ["$_BAECr"].concat($_BADJt),
        $_BAEAV = $_BADIa[1];
    $_BADIa.shift();
    var $_BAEBA = $_BADIa[0];
    var t,
        n = Object[$_BADJt(332)] || function () {
            var $_BAEEE = mwbxQ.$_Cg,
                $_BAEDl = ["$_BAEHS"].concat($_BAEEE),
                $_BAEFj = $_BAEDl[1];
            $_BAEDl.shift();
            var $_BAEGA = $_BAEDl[0];

    .........省略
}();
var m = {
    "$_DJw": {
        "$_EAW": $_CJFt(278),
        "$_EBT": $_CJES(24),
        "$_ECO": 7274496,
        "$_EDf": 9483264,
        "$_EEO": 19220,
        "$_EFn": 235,
        "$_EGX": 24
    },
    "$_EAW": $_CJFt(278),
    "$_EBT": $_CJES(24),
    "$_ECO": 7274496,
    .....省略
    
function get_w3(gt2, challenge2, random_str, distance, pass_time, trace, c, s, rp2) {
    let u = new U()["encrypt"](random_str);
    let param = get_o(distance, challenge2, pass_time, trace, c, s, rp2);
    let o = V["encrypt"](JSON.stringify(param), random_str);
    let h = m["$_FEX"](o);
    let w = h + u;
    return w;
}

至此第三个w也就还原完成

其它#

三个w还原完成后,我们还需要还原下滑块底图和滑动轨迹模拟。

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

根据第二个get.php的缺口背景图片和滑块图片地址,拿到图片还原下。地址前缀可以通过这个请求自己看下,是一样的

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

底图还原工具代码参考 乱序映射表 ut需要对canvas下断自己分析,有很多大佬写过了可以自行找下。

JavaScript
def restore_picture():
    img_list = ["./img/乱序缺口背景图.jpg", "./img/乱序背景图.jpg"]
    for index, img in enumerate(img_list):
        image = Image.open(img)
        s = Image.new("RGBA", (260, 160))
        ut = [39, 38, 48, 49, 41, 40, 46, 47, 35, 34, 50, 51, 33, 32, 28, 29, 27, 26, 36, 37, 31, 30, 44, 45, 43, 42,
              12, 13, 23, 22, 14, 15, 21, 20, 8, 9, 25, 24, 6, 7, 3, 2, 0, 1, 11, 10, 4, 5, 19, 18, 16, 17]
        height_half = 80
        for inx in range(52):
            c = ut[inx] % 26 * 12 + 1
            u = height_half if ut[inx] > 25 else 0
            l_ = image.crop(box=(c, u, c + 10, u + 80))
            s.paste(l_, box=(inx % 26 * 10, 80 if inx > 25 else 0))

        if index == 0:
            s.save("./img/缺口背景图片.png")

        else:
            s.save("./img/背景图片.png")

还原底图后,还需要模拟轨迹,工具代码如下。

JavaScript
import random


def __ease_out_expo(sep):
    '''
        轨迹相关操作
    '''
    if sep == 1:
        return 1
    else:
        return 1 - pow(2, -10 * sep)


def get_slide_track(distance):
    """
    根据滑动距离生成滑动轨迹
    :param distance: 需要滑动的距离
    :return: 滑动轨迹<type 'list'>: [[x,y,t], ...]
        x: 已滑动的横向距离
        y: 已滑动的纵向距离, 除起点外, 均为0
        t: 滑动过程消耗的时间, 单位: 毫秒
    """

    if not isinstance(distance, int) or distance < 0:
        raise ValueError(f"distance类型必须是大于等于0的整数: distance: {distance}, type: {type(distance)}")
    # 初始化轨迹列表
    slide_track = [
        [random.randint(-50, -10), random.randint(-50, -10), 0],
        [0, 0, 0],
    ]
    # 共记录count次滑块位置信息
    count = 10 + int(distance / 2)
    # 初始化滑动时间
    t = random.randint(50, 100)
    # 记录上一次滑动的距离
    _x = 0
    _y = 0
    for i in range(count):
        # 已滑动的横向距离
        x = round(__ease_out_expo(i / count) * distance)
        # y = round(__ease_out_expo(i / count) * 14)
        # 滑动过程消耗的时间
        t += random.randint(10, 50)
        if x == _x:
            continue
        slide_track.append([x, _y, t])
        _x = x
    slide_track.append(slide_track[-1])
    return slide_track, slide_track[-1][2]

有了滑动距离,轨迹,滑动时间,再对o的还原时候填入相应参数,整个滑动验证过程就结束了。

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

END