zoukankan      html  css  js  c++  java
  • js逆向某东滑块 转载 https://mp.weixin.qq.com/s/eZSTfduYS63-LOvkAofxqA

    首先在此声明,本文章仅仅用于研究学习,不可用于任何商业活动,否则后果自负。如侵权请与我联系,立即删除。

    唠嗑

    俺来自河南,愿望我大河南平安!

    图片

        没错今天,我又来搞事情了,咱们今天学习一下某东登录时的滑块的加密。废话不多说了,开干。

    加密分析与定位

    当我们输入账号密码后,点击登录,首先映入眼帘的是一个滑块,那我们先分析一下滑块吧。

    图片

    上图是滑块的有关信息,左边的横线是请求的url,右边是参数,很显然,里面有好多参数。但经过分析,d就是滑块轨迹的加密,c跟下图获取滑块图片一起返回的,下图中challenge就是参数c,参数e可以从网页源码中获取到,而参数appId是定值,参数o就是我们的账号,

    图片

    下面我们就分析一下参数d,看它怎么加密。

    这里我是通过下图调用栈,找到的,点击下图画横线的,然后格式化一下,再搜索appId就可以找到。

    图片

    最后找到的就是下图这个,这里我已经打上断点。

    图片

    我们再次登录,会自动断在这里。我们滑动滑块,就会停到这里

    图片

    可以清除看到,g为一个数组,其实就是我一定滑块的轨迹,这里我们可以借鉴一个文章里面的滑块轨迹思路

    https://www.52pojie.cn/thread-1162979-1-1.html

    这里我提供一下代码(改写文章里面的)。

    # -*- encoding: utf-8 -*-
    """
    @File    :   trances.py
    @Contact :   jyj345559953@qq.com
    @Author  :   Esword
    """
    """
    用于生成坐标轨迹
    """
    import random
    import matplotlib.pyplot as plt
    import numpy as np



    class GTrace(object):
        def __init__(self):
            self.__pos_x = []
            self.__pos_y = []
            self.__pos_z = []

        def __set_pt_time(self):
            """
            设置各节点的时间
            分析不同时间间隔中X坐标数量的占比
            统计结果: 1. 80%~90%的X坐标在15~20毫秒之间
                    2. 10%~15%在20~200及以上,其中 [-a, 0, x, ...] 这里x只有一个,取值在110~200之间
                        坐标集最后3~5个坐标取值再50~400之间,最后一个坐标数值最大

            滑动总时间的取值规则: 图片宽度260,去掉滑块的宽度剩下200;
                            如果距离小于100,则耗时1300~1900之间
                            如果距离大于100,则耗时1700~2100之间
            """
            __end_pt_time = []
            __move_pt_time = []
            self.__pos_z = []

            total_move_time = self.__need_time * random.uniform(0.8, 0.9)
            start_point_time = random.uniform(110, 200)
            __start_pt_time = [0, 0, int(start_point_time)]

            sum_move_time = 0

            _tmp_total_move_time = total_move_time
            while True:
                delta_time = random.uniform(15, 20)
                if _tmp_total_move_time < delta_time:
                    break

                sum_move_time += delta_time
                _tmp_total_move_time -= delta_time
                __move_pt_time.append(int(start_point_time+sum_move_time))

            last_pt_time = __move_pt_time[-1]
            __move_pt_time.append(last_pt_time+_tmp_total_move_time)

            sum_end_time = start_point_time + total_move_time
            other_point_time = self.__need_time - sum_end_time
            end_first_ptime = other_point_time / 2

            while True:
                delta_time = random.uniform(110, 200)
                if end_first_ptime - delta_time <= 0:
                    break

                end_first_ptime -= delta_time
                sum_end_time += delta_time
                __end_pt_time.append(int(sum_end_time))

            __end_pt_time.append(int(sum_end_time + (other_point_time/2 + end_first_ptime)))
            self.__pos_z.extend(__start_pt_time)
            self.__pos_z.extend(__move_pt_time)
            self.__pos_z.extend(__end_pt_time)

        def __set_distance(self, _dist):
            """
            设置要生成的轨迹长度
            """
            self.__distance = _dist

            if _dist < 100:
                self.__need_time = int(random.uniform(500, 1500))
            else:
                self.__need_time = int(random.uniform(1000, 2000))

        def __get_pos_z(self):
            return self.__pos_z

        def __get_pos_y(self):
            _pos_y = [random.uniform(-40, -18), 0]
            point_count = len(self.__pos_z)
            x = np.linspace(-10, 15, point_count - len(_pos_y))
            arct_y = np.arctan(x)

            for _, val in enumerate(arct_y):
                _pos_y.append(val)

            return _pos_y

        def __get_pos_x(self, _distance):
            """
            绘制标准的数学函数图像: 以 tanh 开始 以 arctan 结尾
            根据此模型用等比时间差生成X坐标
            """
            # first_val = random.uniform(-40, -18)
            # _distance += first_val
            _pos_x = [random.uniform(-40, -18), 0]
            self.__set_distance(_distance)
            self.__set_pt_time()

            point_count = len(self.__pos_z)
            x = np.linspace(-1, 19, point_count-len(_pos_x))
            ss = np.arctan(x)
            th = np.tanh(x)

            for idx in range(0, len(th)):
                if th[idx] < ss[idx]:
                    th[idx] = ss[idx]

            th += 1
            th *= (_distance / 2.5)

            i = 0
            start_idx = int(point_count/10)
            end_idx = int(point_count/50)
            delta_pt = abs(np.random.normal(scale=1.1, size=point_count-start_idx-end_idx))
            for idx in range(start_idx, point_count):
                if idx*1.3 > len(delta_pt):
                    break

                th[idx] += delta_pt[i]
                i+=1

            _pos_x.extend(th)
            return _pos_x[-1], _pos_x

        def get_mouse_pos_path(self, distance):
            """
            获取滑动滑块鼠标的滑动轨迹坐标集合
            """
            result = []
            _distance, x = self.__get_pos_x(distance)
            y = self.__get_pos_y()
            z = self.__get_pos_z()
            for idx in range(len(x)):
                result.append([int(x[idx]), int(y[idx]), int(z[idx])])
            import matplotlib.pyplot as plt
            plt.plot(z,x)
            plt.show()
            return int(_distance), result

    import random
    import time

    from trances import GTrace
    def timestamp():
        return int(time.time()*1000)

    trace = GTrace()
    # distance = random.uniform(70, 150)
    distance = 125



    print("长度为: %d " % distance)
    distance, mouse_pos_path = trace.get_mouse_pos_path(distance)
    print("长度为: %d , 坐标为: " % distance, mouse_pos_path)
    # num = len(mouse_pos_path)
    # print(num)
    # 842,368
    base_t = timestamp()
    trace = []
    for i in mouse_pos_path:
        x,y,t = i
        x += 842
        y += 368
        t += base_t
        trace.append([str(x),str(y),t])
    print(trace)

    我们把数组copy下来,本地画一下图,然后看看是怎样的轨迹。

    图片

    (这里我就直接剽窃人家的图了,我的找不到了,哈哈哈,其实就是上面上面文章里面的。)

    基本上都是这样的一个轨迹。我们用那个文章的代码跑一下,然后生成跟g一样的数组,本地生成的数组替换滑块的,看看能不能过,经过我的尝试,是可以的,至于那个移动长度,其实数组的第一个(从第0个开始)的第0个参数,被最后一个数组的第0个减去,然后就是移动距离。

    [    [        "808",        "211",        1626942564294    ],    [        "856",        "240",        1626942564294    ],    [        "857",        "240",        1626942564406    ],    [        "859",        "240",        1626942564413    ],    [        "860",        "240",        1626942564421    ],    [        "861",        "240",        1626942564437    ],    [        "864",        "240",        1626942564445    ],    [        "865",        "240",        1626942564453    ],    [        "866",        "240",        1626942564461    ],    [        "867",        "240",        1626942564469    ],    [        "870",        "240",        1626942564477    ],    [        "872",        "240",        1626942564485    ],    [        "875",        "240",        1626942564502    ],    [        "877",        "240",        1626942564510    ],    [        "879",        "240",        1626942564517    ],    [        "881",        "240",        1626942564525    ],    [        "884",        "240",        1626942564533    ],    [        "886",        "240",        1626942564549    ],    [        "889",        "240",        1626942564557    ],    [        "891",        "240",        1626942564565    ],    [        "894",        "240",        1626942564574    ],    [        "895",        "240",        1626942564581    ],    [        "897",        "240",        1626942564589    ],    [        "899",        "240",        1626942564597    ],    [        "901",        "240",        1626942564605    ],    [        "904",        "240",        1626942564613    ],    [        "905",        "240",        1626942564621    ],    [        "907",        "240",        1626942564629    ],    [        "910",        "240",        1626942564637    ],    [        "914",        "240",        1626942564645    ],    [        "916",        "240",        1626942564653    ],    [        "920",        "240",        1626942564661    ],    [        "924",        "240",        1626942564669    ],    [        "926",        "240",        1626942564677    ],    [        "927",        "240",        1626942564685    ],    [        "931",        "240",        1626942564693    ],    [        "932",        "240",        1626942564701    ],    [        "936",        "240",        1626942564709    ],    [        "937",        "240",        1626942564717    ],    [        "940",        "240",        1626942564725    ],    [        "942",        "240",        1626942564733    ],    [        "945",        "239",        1626942564741    ],    [        "947",        "239",        1626942564749    ],    [        "950",        "239",        1626942564758    ],    [        "951",        "239",        1626942564765    ],    [        "954",        "239",        1626942564775    ],    [        "956",        "239",        1626942564781    ],    [        "957",        "239",        1626942564789    ],    [        "960",        "238",        1626942564797    ],    [        "962",        "238",        1626942564806    ],    [        "964",        "238",        1626942564813    ],    [        "965",        "238",        1626942564822    ],    [        "967",        "238",        1626942564829    ],    [        "969",        "238",        1626942564837    ],    [        "970",        "238",        1626942564845    ],    [        "972",        "238",        1626942564853    ],    [        "975",        "238",        1626942564861    ],    [        "976",        "238",        1626942564877    ],    [        "979",        "238",        1626942564885    ],    [        "980",        "238",        1626942564893    ],    [        "981",        "238",        1626942564910    ],    [        "982",        "238",        1626942565013    ],    [        "984",        "238",        1626942565678    ],    [        "983",        "238",        1626942565950    ],    [        "981",        "238",        1626942565974    ],    [        "980",        "238",        1626942566110    ],    [        "979",        "238",        1626942566126    ],    [        "981",        "238",        1626942568326    ],    [        "981",        "238",        1626942568861    ]]

    上面就是那个数组,距离就是981-856,则125就是移动距离。我本地生成一下。然后复制,令g = 本地生成的数组(控制台操作)。

    图片

    通过上图可以看出,g发生了改变,没错,就是我们本地生成的数组。我们接着让它运行,看一下结果。

    图片

    可以发现已经成功了,还有就是滑块缺口识别用opencv的模板匹配就好了,完全可以识别出来。

    图片

    上图是生成的轨迹图。

    下面我们就要看它的加密了,

    图片

    就是上图这个,我们点进去看一下,

    图片

    就是上面这个函数,这里很好扣的,就不多说了,扣下来,稍微改一改就好了,代码如下。

    function string10to64(d) {
        var c = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-~".split("")
            , b = c.length
            , e = +d
            , a = [];
        do {
            mod = e % b;
            e = (e - mod) / b;
            a.unshift(c[mod])
        } while (e);
        return a.join("")
    }

    function prefixInteger(a, b) {
            return (Array(b).join(0) + a).slice(-b)
        }

    function pretreatment(d, c, b) {
        var e = string10to64(Math.abs(d));
        var a = "";
        if (!b) {
            a += (d > 0 ? "1" : "0")
        }
        a += prefixInteger(e, c);
        return a
    }


    function getCoordinate(c) {
        var b = new Array();
        for (var e = 0; e < c.length; e++) {
            if (e == 0) {
                b.push(pretreatment(c[e][0] < 262143 ? c[e][0] : 262143, 3, true));
                b.push(pretreatment(c[e][1] < 16777215 ? c[e][1] : 16777215, 4, true));
                b.push(pretreatment(c[e][2] < 4398046511103 ? c[e][2] : 4398046511103, 7, true))
            } else {
                var a = c[e][0] - c[e - 1][0];
                var f = c[e][1] - c[e - 1][1];
                var d = c[e][2] - c[e - 1][2];
                b.push(pretreatment(a < 4095 ? a : 4095, 2, false));
                b.push(pretreatment(f < 4095 ? f : 4095, 2, false));
                b.push(pretreatment(d < 16777215 ? d : 16777215, 4, true))
            }
        }
        return b.join("")
    }

    function slide(array) {
        g = array
        return getCoordinate(g)

    }

    总结

        说实话京东这个滑块的加密不难,对我而言要学的就是怎么模拟生成这个轨迹,这里我们不要一味的复制别人的代码,而是要真正懂其原理,然后再化为己用,如果你也不会滑块轨迹生成,可以好好看看那个文章。

         这里仅仅是京东滑块的加密,后面还有,我们下期再见。

  • 相关阅读:
    一个SQL语句实现的统计功能
    VS2005中的全角BUG(C#代码)[转]
    Observer Pattern(观察者模式)及其在C#中的实现
    我觉得VS2003中最差的地方
    上班了,有点困:(
    GPRS
    今天是郁闷的一天
    今天上午给公司老总演示了SharePoint项目的产品雏形
    介绍一下SharePoint
    SharePoint Service里面的东东真让人头疼
  • 原文地址:https://www.cnblogs.com/testzcy/p/15060114.html
Copyright © 2011-2022 走看看