极验验证码(6.0.9)破解(四) 之 'aa' 参数调试和分析

共 9854字,需浏览 20分钟

 ·

2020-12-06 02:11

文章目录


  • 文章目录

    • 1. 回顾

    • 2. 1 针对aa参数的js断点调试

    • 3. 总结


1. 回顾


  1. 上篇文章[1] 介绍了'userresponse' 参数调试和分析,并将js执行过程整理出来,整理成python代码。
  2. 今天我们继续进行极验破解,这次我们介绍 'aa'参数的生成,距离上篇文章,已经过去快三个月了,工作很忙,又忙着结婚,一直抽不出来空,或者静不下心来写博客,今天总算是忙里偷闲,也让自己沉淀一下,准备更新极验破解第4篇
  3. 正当我撸起袖子准备大干一番的时候,发现我的目标网站,关闭了相关功能页面,不过还好基础页面还在,我还能接着用它的极验滑块接着干,哈哈

不废话了,这次我们直接进入正题

2.  针对aa参数的js断点调试


根据前面的分析,我们先看一下文件geetest.6.0.9.js的第1387行,不知道为啥直接定位这一行的,可以看下之前的文章我们先在1382行处打一个断点,期望能够获取变量‘F7z ’的值,而由

F7z = p7B["t"](V7z["A"] + p7B["B"]("REFb0UEJ") + F7z

我们知道,这里已经有了右侧F7z的值,因此,我们尝试在geetest.6.0.9.js文件中搜索'F7z' ,看能否找到F7z的变量声明的地方,我们找到了 1410行因此这里也需要打上断点此时就可以开始js调试了,根据调试过程和变量追踪,还是要自己耐住性子一步步来,关于断点调试要说的东西太多,这里还是跳过调试过程,直接给出我整理出'aa'参数生成的js代码(用反混淆之后的js代码)

//V7z["b"] = 1562138812095   2019-07-03 15:26:52
// F7z = "B-/./.(!!Bs(y((((yyysssssssss(!!($)L34434343443B3VB$.3e$)G$,V"
          ""
//           B-/./.(!!BsR(y((((yyysssssssss(!!($)L344343(43443B3VVB$.3e$)G$,V


// var g7z = parseInt(a7z), F7z = e7B["t"](V7z["b"]);
function e7B_t(K1z{
    var X8r = 27;
    while (X8r !== 19) {
        switch (X8r) {
        case 27:
            var o5r = 6;
            X8r = 24;
            break;
        case 24:
            var N1z, X1z = s6z(c7B["a"]("arr", K1z)), f1z = [], B1z = [], o1z = [], t1z = 0, j1z = X1z["length"];
            X8r = 13;
            break;
        case 13:
            X8r = o5r * (o5r + 1) % 2 + 8 && t1z < j1z ? 2 : 20;
            break;
        case 2:
            N1z = u6z(X1z[t1z]),
            N1z ? B1z["push"](N1z) : (f1z["push"](O6z(X1z[t1z][0])),
            B1z["push"](O6z(X1z[t1z][1]))),
            o1z["push"](O6z(X1z[t1z][2]));
            o5r = o5r >= 17705 ? o5r / 3 : o5r * 3;
            X8r = 28;
            break;
        case 20:
            return f1z["join"]("") + "!!" + B1z["join"]("") + "!!" + o1z["join"]("");
            X8r = 19;
            break;
        case 28:
            t1z++;
            X8r = 13;
            break;
        }
    }
};

c7B["a"] = function(X2z, B2z{
    var V0r = 27;
    while (V0r !== 24) {
        switch (V0r) {
        case 27:
            return c7B["Na"][B2z][X2z];
            V0r = 24;
            break;
        }
    }
};

// F6z = [-21, -21, 0], [0, 0, 0], [1, 0, 96], [5, 0, 106], [8, 0, 117], [14, 0, 128], [19, 0, 138], [25, 0, 149], [30, 0, 159], [33, 0, 170], [36, 0, 180], [39, 0, 191], [40, 0, 202], [41, 0, 212], [42, 0, 233], [43, 0, 243], [44, 0, 284], [45, 0, 305], [46, 0, 640], [47, 0, 691], [48, 0, 782], [48, 0, 1018]
s6z = function(F6z{
    var R1r = 27;
    while (R1r !== 19) {
        switch (R1r) {
        case 27:
            var N5r = 9;
            R1r = 24;
            break;
        case 13:
            R1r = J6z < l6z && N5r * (N5r + 1) % 2 + 7 ? 2 : 20;
            break;
        case 2:
            Y6z = Math["round"](F6z[J6z + 1][0] - F6z[J6z][0]),
            g6z = Math["round"](F6z[J6z + 1][1] - F6z[J6z][1]),
            a6z = Math["round"](F6z[J6z + 1][2] - F6z[J6z][2]),
            P6z["push"]([Y6z, g6z, a6z]),
            0 == Y6z && 0 == g6z && 0 == a6z || (0 == Y6z && 0 == g6z ? D6z += a6z : (E6z["push"]([Y6z, g6z, a6z + D6z]),
            D6z = 0));
            N5r = N5r > 34958 ? N5r / 6 : N5r * 6;
            R1r = 28;
            break;
        case 24:
            var Y6z, g6z, a6z, E6z = [], D6z = 0, P6z = [], J6z = 0, l6z = F6z["length"] - 1;
            R1r = 13;
            break;
        case 28:
            J6z++;
            R1r = 13;
            break;
        case 20:
            return 0 !== D6z && E6z["push"]([Y6z, g6z, D6z]),
            E6z;
            R1r = 19;
            break;
        }
    }
};

// R6z = [21, 21, 0]
u6z = function(R6z{
    var t8r = 27;
    while (t8r !== 21) {
        switch (t8r) {
        case 2:
            t8r = R6z[0] == z6z[h6z][0] && R6z[1] == z6z[h6z][1] ? 38 : 28;
            break;
        case 24:
            var z6z = [[10], [20], [1-1], [11], [01], [0-1], [30], [2-1], [21]]
              , h6z = 0
              , C6z = z6z["length"];
            t8r = 13;
            break;
        case 27:
            var f5r = 9;
            t8r = 24;
            break;
        case 38:
            return "stuvwxyz~"[h6z];
            t8r = 21;
            break;
        case 13:
            t8r = h6z < C6z && f5r * (f5r + 1) % 2 + 7 ? 2 : 19;
            break;
        case 20:
            h6z++;
            t8r = 13;
            break;
        case 19:
            return 0;
            t8r = 21;
            break;
        case 28:
            f5r = f5r >= 62252 ? f5r - 6 : f5r + 6;
            t8r = 20;
            break;
        }
    }
};

//r6z = 26
O6z = function (r6z{
    var C1r = 27;
    while (C1r !== 38) {
        switch (C1r) {
        case 27:
            var d6z = "()*,-./0123456789:?@ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqr"
              , m6z = d6z["length"]
              , Z6z = ""
              , H6z = Math["abs"](r6z)
              , W6z = parseInt(H6z / m6z);
            W6z >= m6z && (W6z = m6z - 1),
            W6z && (Z6z = d6z["charAt"](W6z)),
            H6z %= m6z;
            var q6z = "";
            return r6z < 0 && (q6z += "!"),
            Z6z && (q6z += "$"),
            q6z + Z6z + d6z["charAt"](H6z);
            C1r = 38;
            break;
        }
    }
};
var F7z = e7B_t(V7z["b"]);
//v1z = [12, 58, 98, 36, 43, 95, 62, 15, 12]
// T1z = "764b354e"

F7z = e7B["u"](F7z, V7z["d"]["c"], V7z["d"]["s"]);
function e7B_u(Q1z, v1z, T1z{
    var B8r = 27;
    while (B8r !== 14) {
        switch (B8r) {
        case 20:
            x1z += 2;
            var n1z = parseInt(i1z, 16)
              , M1z = String["fromCharCode"](n1z)
              , I1z = (y1z * n1z * n1z + k1z * n1z + L1z) % Q1z["length"];
            c1z = c1z["substr"](0, I1z) + M1z + c1z["substr"](I1z);
            B8r = 31;
            break;
        case 27:
            var K5r = 2;
            var j5r = 4;
            B8r = 13;
            break;
        case 13:
            B8r = (!v1z || !T1z) && j5r * (j5r + 1) * j5r % 2 == 0 ? 2 : 38;
            break;
        case 2:
            return Q1z;
            B8r = 14;
            break;
        case 31:
            K5r = K5r > 10375 ? K5r / 8 : K5r * 8;
            B8r = 28;
            break;
        case 28:
            B8r = (i1z = T1z["substr"](x1z, 2)) && K5r * (K5r + 1) * K5r % 2 == 0 ? 20 : 23;
            break;
        case 38:
            var i1z, x1z = 0, c1z = Q1z, y1z = v1z[0], k1z = v1z[2], L1z = v1z[4];
            B8r = 28;
            break;
        case 23:
            return c1z;
            B8r = 14;
            break;
        }
    }
};



将js逻辑改写成pyhon代码

#!/usr/bin/env python
# -*- coding: utf-8 -*-

# @Time : 2019/7/4 9:41
# @Author : SpiritedAway1106
# @File : aa
# @Software: PyCharm
# @Description : 获取aa参数的值


# 对aa 进行二次加密,拿到最后结果
def e7B_u(Q1z=None, v1z=None, T1z=None):
'''TODO
对aa进行二次加密
参数:
Q1z 首次加密的aa值 eg 'B-/./.(!!Bs(y((((yyysssssssss(!!($)L34434343443B3VB$.3e$)G$,V'
v1z 极验配置的c参数 eg [12, 58, 98, 36, 43, 95, 62, 15, 12]
T1z 极验配置的参数 eg '764b354e'
返回值:
aa二次加密结果 eg
'''
Q1z, v1z, T1z = 'B-/./.(!!Bs(y((((yyysssssssss(!!($)L34434343443B3VB$.3e$)G$,V',[12, 58, 98, 36, 43, 95, 62, 15, 12],'764b354e'
if v1z and T1z :
i1z = ''
x1z = 0
c1z = Q1z
y1z = v1z[0]
k1z = v1z[2]
L1z = v1z[4]
while 1:
i1z = T1z[x1z:x1z+2]
if i1z:
x1z += 2
n1z = int(i1z, 16)
M1z = chr(n1z)
I1z = (y1z * n1z * n1z + k1z * n1z + L1z) % len(Q1z)
c1z = c1z[:I1z] + M1z + c1z[I1z:]
else:
return c1z
else:
return Q1z

# 返回aa的首次加密值,传入滑动轨迹tracks
def e7B_t(tracks=[]):
'''TODO
对aa 进行首次加密
参数:
tracks 滑动路径,三元组列表[[x,y,time]] eg [[-21, -21, 0], [0, 0, 0], [1, 0, 96], [5, 0, 106], [8, 0, 117], [14, 0, 128], [19, 0, 138], [25, 0, 149],
[30, 0, 159], [33, 0, 170], [36, 0, 180], [39, 0, 191], [40, 0, 202], [41, 0, 212], [42, 0, 233],
[43, 0, 243], [44, 0, 284], [45, 0, 305], [46, 0, 640], [47, 0, 691], [48, 0, 782], [48, 0, 1018]]
返回值:

'''
o5r = 6
N1z = ''
tracks = [[-21, -21, 0], [0, 0, 0], [1, 0, 96], [5, 0, 106], [8, 0, 117], [14, 0, 128], [19, 0, 138], [25, 0, 149],
[30, 0, 159], [33, 0, 170], [36, 0, 180], [39, 0, 191], [40, 0, 202], [41, 0, 212], [42, 0, 233],
[43, 0, 243], [44, 0, 284], [45, 0, 305], [46, 0, 640], [47, 0, 691], [48, 0, 782], [48, 0, 1018]]
X1z = s6z(tracks)
f1z = []
B1z = []
o1z = []

for t1z, X in enumerate(X1z):
if o5r * (o5r + 1) % 2 + 8:
N1z = u6z(X)
if N1z:
B1z.append(N1z)
else:
f1z.append(O6z(X[0]))
B1z.append(O6z(X[1]))
o1z.append(O6z(X[2]))
o5r = o5r / 3 if o5r >= 17705 else o5r * 3

return ''.join(f1z) + "!!" + ''.join(B1z) + "!!" + ''.join(o1z)


def O6z(r6z=26):
'''TODO
按规则映射数字和字符
参数:
r6z eg 26
返回值:
目标字符 G
'''
d6z = "()*,-./0123456789:?@ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqr"
m6z = len(d6z)
Z6z = ""
H6z = abs(r6z)
W6z = int(H6z / m6z)
if W6z >= m6z:
W6z = m6z - 1

if W6z:
Z6z = d6z[W6z]

H6z %= m6z
q6z = ""

if r6z < 0:
q6z += "!"
if Z6z:
q6z += "$"

return q6z + Z6z + d6z[H6z]


def u6z(R6z=[]):
'''TODO
将路径映射成单个字符
参数:
R6z 处理后路径中的其中一个元组 eg [21, 21, 0]
返回值:
映射结果 eg 0
'''
R6z = [21, 21, 0]
z6z = [[1, 0], [2, 0], [1, -1], [1, 1], [0, 1], [0, -1], [3, 0], [2, -1], [2, 1]]

for h6z ,z in enumerate(z6z):
if R6z[0] == z6z[h6z][0] and R6z[1] == z6z[h6z][1]:
return "stuvwxyz~"[h6z]
return 0


def s6z(F6z=[]):
'''TODO
规整滑动路径列表,整理成[x移动距离,y移动距离,时间间隔]元组
参数:
F6z 滑动路径 eg [[-21, -21, 0], [0, 0, 0], [1, 0, 96], [5, 0, 106], [8, 0, 117], [14, 0, 128], [19, 0, 138], [25, 0, 149],
[30, 0, 159], [33, 0, 170], [36, 0, 180], [39, 0, 191], [40, 0, 202], [41, 0, 212], [42, 0, 233],
[43, 0, 243], [44, 0, 284], [45, 0, 305], [46, 0, 640], [47, 0, 691], [48, 0, 782], [48, 0, 1018]]
返回值:
规整后路径位移元组 eg [[21, 21, 0], [1, 0, 96], [4, 0, 10], [3, 0, 11], [6, 0, 11], [5, 0, 10], [6, 0, 11], [5, 0, 10], [3, 0, 11], [3, 0, 10], [3, 0, 11], [1, 0, 11], [1, 0, 10], [1, 0, 21], [1, 0, 10], [1, 0, 41], [1, 0, 21], [1, 0, 335], [1, 0, 51], [1, 0, 91], [0, 0, 236]]

'''
# F6z = [[-21, -21, 0], [0, 0, 0], [1, 0, 96], [5, 0, 106], [8, 0, 117], [14, 0, 128], [19, 0, 138], [25, 0, 149],
# [30, 0, 159], [33, 0, 170], [36, 0, 180], [39, 0, 191], [40, 0, 202], [41, 0, 212], [42, 0, 233],
# [43, 0, 243], [44, 0, 284], [45, 0, 305], [46, 0, 640], [47, 0, 691], [48, 0, 782], [48, 0, 1018]]
Y6z = 0
g6z = 0
a6z = 0
E6z = []
D6z = 0 # 滑动消耗总时间
P6z = []
l6z = len(F6z) - 1
for J6z, F in enumerate(F6z):
if J6z < l6z:
Y6z = round(F6z[J6z + 1][0] - F6z[J6z][0])
g6z = round(F6z[J6z + 1][1] - F6z[J6z][1])
a6z = round(F6z[J6z + 1][2] - F6z[J6z][2])
P6z.append([Y6z, g6z, a6z])
if 0 == Y6z and 0 == g6z and 0 == a6z:
pass
else:
if 0 == Y6z and 0 == g6z:
D6z += a6z
else:
E6z.append([Y6z, g6z, a6z + D6z])
D6z = 0
else:
if 0 != D6z:
E6z.append([Y6z, g6z, D6z])
return E6z

def main():
print(e7B_u())


if __name__ == '__main__':
main()

3. 总结

  1. 再次强调,反混淆之后的js文件很重要,如果有耐心,甚至可以不在线调试js,直接剥离出‘aa’参数的相关js和执行顺序
  2. 调试一定要有耐心!!!!,几乎每次都会在总结里说
  3. 代码中的注释还算详细,调试过程中,可根据js中实际变量值,替换py文件中的变量,验证代码是否有效和正确

Reference

[1]

极验验证码(6.0.9)破解(三) 之 'userresponse' 参数调试和分析: https://blog.csdn.net/SpiritedAway1106/article/details/98958925


浏览 84
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报