极验2代验证码分析

18 篇文章 2 订阅
3 篇文章 0 订阅
  • 目标链接
'aHR0cDovL3d3dy5qc2dzai5nb3YuY246NTg4ODgvbWluaS9uZXR3ZWIvU01MaWJyYXJ5LmpzcA=='
  • 接口分析
  1. 点击搜索就会跳出验证码,netWebServlet.json 的请求,会返回 challenge 和 gt
    在这里插入图片描述

  2. 接着可以看响应请求图片信息的接口,可以看到请求参数包含challenge、gt、type(验证码类型)

在这里插入图片描述
响应数据新的challenge、验证码图片地址乱、序图片地址、c、s这些都是接下来用到的值
在这里插入图片描述

  1. 然后通过ajax.php 验证是否通过,通过之后返回一个 validate,请求里同样是需要我们逆向的 w 参数:
    在这里插入图片描述
    响应数据validate,拿着去请求就可获得参数
    在这里插入图片描述
  • 接口参数分析
    好像也就是一个w参数需要逆向,全局搜w是不太可能的了;可以从这里跟栈。
    在这里插入图片描述
  1. 也可以w 的 Unicode 值 \x77 即可定位。所以直接全局搜\x77
    在这里插入图片描述
    相当于要解决r7z 、H7z两个值
var H7z = V7zM9r.C8z(92)()
, q7z = n0B[M9r.R8z(699)](h7BM9r.C8z(105), V7zM9r.R8z(818))
, r7z = p7B
  1. 获取H7z值,跟栈可以发现这里就是生成H7z值的地方,查看原型可以发现包含setPublic所以属于RSA加密
    在这里插入图片描述
    直接导入库加密生成H7z值

  2. 获取 r7z值

在这里插入图片描述

q7z = n0B[M9r.R8z(699)](h7B[M9r.C8z(105)](Y7z), V7z[M9r.R8z(818)]())
r7z = p7B[M9r.R8z(260)](q7z)

可以看到其中有个变量 Y7z 参与了计算,先来看看他是怎么来的,直接搜索即可定位,可以发现同样是16进制的编码,由五个值组成:userresponse、passtime、imgload、aa、ep;需要往上找到Y7z生成的地方。
在这里插入图片描述

  1. 先分析userresponse值
    将滑动距离和 challenge 的值传入一个方法,得到一个 9 位字符串
    在这里插入图片描述

  2. 获取 passtime 值
    passtime 不用考虑是怎么通过函数获取的,含义就是滑动完成所花费的时间,直接取轨迹的最后一个值即可,这个也和三四代是一样的,获取语句为:var passtime = track[track.length - 1][2],如下图所示,轨迹的最后一个值时间为 871,passtime 的值同样也为 871。
    在这里插入图片描述

  3. 获取 imgload 值即使可以写死的。

  4. 获取 aa 值
    是通过轨迹进行加密的,加密进行了两次这里直接跟栈将代码扣下即可

  5. 获取 ep 值,从开始传入进来的
    在这里插入图片描述
    ep 的值就是一个版本号,此处是 {‘v’: ‘6.0.9’},写死即可。

  6. 获取 rp 值
    在这里插入图片描述
    自此 Y7z 的第一步生成就分析完毕了,注意接下来还有一步,向 Y7z 里新增了一个 rp 参数:在这里插入图片描述
    这个值的组成看起来很长,实际上是将 gt、challenge 前 32 位以及 passtime 相加经过 MD5 加密后得到的。

Y7z["rp"] = md5(gt + challenge.slice(0, 32) + passtime)
  1. 自此 Y7z 的值就搞定了,然后接着前面的看,也就是 q7z 的值,同样和三四代一样的,encrypt 是 AES 加密,Y7z 经过 JSON.stringify() 处理为字符串作为待加密对象,后面是 16 为随机字符串作为 AES 的 Key,注意这里的随机字符串应该和获取 H7z 值时的随机字符串一致,不然是验证不成功的。
    在这里插入图片描述
    跟栈下一步就是获取 r7z 的值,将上一步得到的 q7z 经过一个方法进行处理。
    在这里插入图片描述
function $_GJF(e) {
    var t = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789()";
    return e < 0 || e >= t["length"] ? "." : t["charAt"](e);
}

function $_HBO(e, t) {
    return e >> t & 1;
}

function $_HCX(e, o) {
    var i = this;
    o || (o = i);
    for (var t = function(e, t) {
        for (var n = 0, r = 24 - 1; 0 <= r; r -= 1)
            1 === $_HBO(t, r) && (n = (n << 1) + $_HBO(e, r));
        return n;
    }, n = "", r = "", s = e.length, a = 0; a < s; a += 3) {
        var c;
        if (a + 2 < s)
            c = (e[a] << 16) + (e[a + 1] << 8) + e[a + 2],
            n += $_GJF(t(c, 7274496)) + $_GJF(t(c, 9483264)) + $_GJF(t(c, 19220)) + $_GJF(t(c, 235));
        else {
            var _ = s % 3;
            2 == _ ? (c = (e[a] << 16) + (e[a + 1] << 8),
            n += $_GJF(t(c, 7274496)) + $_GJF(t(c, 9483264)) + $_GJF(t(c, 19220)),
            r = ".") : 1 == _ && (c = e[a] << 16,
            n += $_GJF(t(c, 7274496)) + $_GJF(t(c, 9483264)),
            r = "." + ".");
        }
    }
    return {
        "res": n,
        "end": r
    };
}

最好就是整个r7z还原成功了。

总结:

  1. RSA加密时候的随机值要和AES的相同
  2. 滑行时间需要跟你轨迹的最后一个参数相同
  3. 因为它的滑块图前面存在一定空白距离,需要减去否者一直失败
    在这里插入图片描述

报错总结

  1. 里面的rsa和aes的随机值时需要一样的,否者报错
geetest_xxxxxxxxxxxxx({"status": "error", "error": "param decrypt error", "user_error": "\u7f51\u7edc\u4e0d\u7ed9\u529b", "error_code": "error_03"})
  1. challenge不对
geetest_xxxxxxxxxxxxx({"status": "error", "error": "illegal challenge", "user_error": "\u7f51\u7edc\u4e0d\u7ed9\u529b", "error_code": "error_23"})
  1. 水平位移不对
geetest_1617617004437({"success": 0, "message": "fail"})
  1. 如果水平位移正确,轨迹被检测,需要更换轨迹代码
geetest_1617268400314({"success": 0, "message": "forbidden"})
  1. 存在时间问题passtime 滑行时间需要跟你轨迹的最后一个参数相同,否则w错误
    在这里插入图片描述
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值