吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 8077|回复: 38
收起左侧

[Web逆向] 某验滑块加密分析下

  [复制链接]
冷空气鑫 发表于 2021-8-1 18:48
本帖最后由 冷空气鑫 于 2021-8-2 14:22 编辑

最近公司事多,淘宝拼多多的风控头痛。极验就耽搁了,废话不说了 直接开始分析。
一,定位到加密位置。

跟以前一样你可以堆栈,xhr断点,或者搜索去定位,我们这里直接搜索定位就行了。
搜"\u0077"  在slide这个js里面
image.png
跟上篇的加密大同小异,var s = n[sKmJ(766)]()  这行js我就不细说了,加密方式跟上篇的加密一模一样,这里直接跳过。
接下来看var u = ee[rndd(365)](me[sKmJ(57)](o), n[sKmJ(753)]());  里面的o  我们多次滑动做个对比
image.png image.png
可以明显看出来aa,imgload,passtime,rp,userresponse变了,其中aa是轨迹加密,imgload这个值可以随便传,passtime就是滑动时间,rp是一个md5,userresponse也是个加密。
先找aa,向上看可以看到aa就是t,而t是传进来的,所以打个断点先。
image.png
然后堆栈,看从哪里传的。可以看到t就是f
image.png
而f又是var f = r[KnGa(1063)][LsRU(1020)](r[LsRU(1063)][LsRU(1047)](), r[KnGa(210)][KnGa(1071)], r[LsRU(210)][LsRU(223)]); 这里生成的,我们在这一行打断点 ,看看都是些什么参数。在控制台输出他们
image.png
不难发现r[LsRU(1063)][LsRU(1047)]()是一个经过加密的轨迹,r[KnGa(210)][KnGa(1071)]是上一次请求的json里面返回的一个数组,r[LsRU(210)][LsRU(223)]也是上一次请求的json里面返回的s值
那就先扣第一个r[LsRU(1063)][LsRU(1047)]()的生成,控制台输入r[LsRU(1063)][LsRU(1047)]  然后点进去 或者选中r[LsRU(1063)][LsRU(1047)] 点进去都行
image.png
这里说一下这个方法,你们可以直接把这个方法复制出来看,放进notepad++
分析下,先定义了e r n三个function,然后var t = e(this[LHLJ(329)]);开始真正的执行 ,所以我们断点要下在var t = e(this[LHLJ(329)]); 和他下面一行
image.png
这里有个坑,很多人以为e(this[LHLJ(329)]);就是轨迹的数组,然后直接在这里传轨迹,最后得到的是错误的加密,其实this[LHLJ(329)]才是轨迹的数组,e给数组小小的更改了一下,控制台输出这个数组看看长啥样
image.png
大概讲一下这是啥,一个大数组里面很多个小数组,小数组由x,y,time组成,这个大数组里面的最后一个小数组小标为2的值就是passtime也就是滑动时间,下标0的就是鼠标移动的x距离,下标1的就是鼠标移动的y轴距离,都是以滑块按钮为起点来计算的,好了到这里 我们就面临如何生成一个轨迹数组了,正常的浏览器是记录了你的鼠标轨迹,而你代码运行的时候是没有鼠标的,这时就要自己写一个算法来生成了。
轨迹的生成算法我就不说了,这个网上可以搜到 ,比较容易。接下来直接改写。var t = e(this[LHLJ(329)]);因为没有轨迹 所以得穿进来 这行改成var t = e(treack); 然后"\u0053\u004f\u0051\u0064": function() {这一行 改成"\u0053\u004f\u0051\u0064": function(treack) {    然后定义一个全局变量slideGj接收"\u0053\u004f\u0051\u0064": function() {外面的YqSr[VPOz(82)]
image.png
接着写个function调用
[JavaScript] 纯文本查看 复制代码
function  get_gjenc(){
var t=slideGj['\u0053\u004f\u0051\u0064'](treack)
return t
}
console.log(get_gjenc())

运行
image.png

没问题,r[LsRU(1063)][LsRU(1047)]() 这个扣完了 ,剩下两个参数是返回的直接取出来用就是了,r[KnGa(1063)][LsRU(1020)]找这个函数的方法在哪,控制台输出r[KnGa(1063)][LsRU(1020)],
点进去发现"\u006e\u0053\u0074\u0046":这个跟上一次轨迹加密的地方都在YqSr[VPOz(82)]   直接用就行了,吧刚刚那个自定义的function改写下
[JavaScript] 纯文本查看 复制代码
function get_gjenc(){
var t=slideGj['\u0053\u004f\u0051\u0064'](treack)
var aa=slideGj['\u006e\u0053\u0074\u0046'](t,[12,58,98,36,43,95,62,15,12],"696a3356")

return aa
}
console.log(get_gjenc())

运行一下
image.png
看着跟web生成的没啥两样,好的轨迹加密完毕,接下来找userresponse
image.png
在这里可以看到7910行就是生成userresponse的地方,U(e, i[rndd(189)])  直接输出看看这两个 参数是什么
image.png
e就是滑动距离,i[rndd(189)] 就是challenge值,这个challenge值改变过 不是网页刚开始请求到的challenge值,而是拿到滑动图片的接口里面返回的34位challenge值
这个U,点进去然后全局变量接收 这里不细说了。
接下来看rp值得生成
image.png

在7929行 就是rp的生成位置,控制台输出i[rndd(173)] + i[sKmJ(189)][sKmJ(141)](0, 32) + o[sKmJ(791)]这三个值看看,
image.png
分别是gt值 然后challenge取32位,滑动时间也就是passtime,rp的生成就是MD5(gt+challenge[0:32]+passtime)
Q的扣法一样,全局变量接收。还有个ep这个参数,我测试ep写死也能过,这里就不扣了,生成位置在n[sKmJ(799)]() 这一行,里面是一些浏览器打开窗口记录,画布的时间戳,极验没有检测,感兴趣的可以自己伪造。
极验还有个小心机,
image.png
这个参数是每天都会变动的,他的js代码是动态的,js代码的地址就在拿滑动图片的json里面的gct_path
他的代码入口在这里
image.png

跟进去看看 并在第一个return下断点
image.png
然后跟进return的函数,在这里下断
image.png
可以看到e值就是json里面的那个key,而FIkH(GKEj[TrXT(27)]() + FIkH(FIkH[UAHS(27)]())) + TrXT(39);就是value

接下来分析下他的加密算法FIkH(GKEj[TrXT(27)]() + FIkH(FIkH[UAHS(27)]())) + TrXT(39); 把它反混淆下 FIkH(GKEj[“toString”]() + FIkH(FIkH[“toString”]())) +“”;
粗略看出,他是把着GKEj和FIkH方法全部tostring转成字符串,而且FIkH里面还有用到这个字符串的长度,所以这种代码在运行时不能格式化(格式化会加很多空格换行符),不能随意的添加,但是不能添加代码我们就无法拿到值,所以我们可以hook tosting这个方法,让他执行tostring的时候用我们自己写的方法,这样就可以随便改变代码。
简单实现下,首先在整个大funciton外面定义两个全局变量来接收key和value  
var rkey;
var rvalue;
接着你需要在}后面写上用rkey=e;rvalue=t[e];来接收你需要的参数
image.png
然后hook tostring方法,在return function前面写上
[JavaScript] 纯文本查看 复制代码
asynctest = GKEj;
var aaa = GKEj.toString();
                GKEj.toString = function (){
                    return aaa.replace("rkey=e;rvalue=t[e];", "")
                }



这样你就把tostring改自己的了,接着你要调用这个方法GKEj这个方法,自己定义一个function来运行,
最后的成果就是
[JavaScript] 纯文本查看 复制代码
var rkey;var rvalue;!(function(){ABvYx.Bdg=function(){var ekn=2;for(;ekn!==1;){switch(ekn){case 2:return{fsT:function(gsh){var htP=2;for(;htP!==14;){switch(htP){case 5:htP=iWO<jeZ.length?4:7;break;case 2:var kwI='',jeZ=decodeURI('%10U%3E%1A%0A%05%10n%10%1A%0A%05+H%3E+&/=n%10%1A%0A%05%10n%10%1A%0A%05%15_,.18:%10%01&%3E%3E-D%13%1A%0A%05%10n%100;%08:B\'*3%05%10S/(8%05%10n%10%1A18,%02%10%1A%0A%05%10n%10%1A%0A%05%10n(1:8:Y!*%0A%05%10n%10%1A%0A%05%10n%10%1A%0A%05%10n%10%1B38:n%3E6;/!D741%05!R$!7/%10n-,5)%0D_*!%15/%10n%10%1A%0A%05%10n%10%1A%0A%05%10n%10%1A%0A7/%5E)%1A%0A:#T%10%1A%0A%05%10n%22!:%3C:X%10%1A!5*U(-:%3E*n%10%1A%13%3E+D+7%20%05%10');htP=1;break;case 1:var iWO=0,ljk=0;htP=5;break;case 4:htP=ljk===gsh.length?3:9;break;case 8:iWO++,ljk++;htP=5;break;case 3:ljk=0;htP=9;break;case 9:kwI+=String.fromCharCode(jeZ.charCodeAt(iWO)^gsh.charCodeAt(ljk));htP=8;break;case 7:kwI=kwI.split('^');return function(mBt){var neB=2;for(;neB!==1;){switch(neB){case 2:return kwI[mBt];break;}}};break;}}}('N0NDT[')};break;}}}();ABvYx.COR=function(){var oFV=2;for(;oFV!==1;){switch(oFV){case 2:return{ptV:function qZY(rOL,sPY){var tZk=2;for(;tZk!==10;){switch(tZk){case 4:uTR[(vib+sPY)%rOL]=[];tZk=3;break;case 13:wBv-=1;tZk=6;break;case 9:var xhm=0;tZk=8;break;case 8:tZk=xhm<rOL?7:11;break;case 12:xhm+=1;tZk=8;break;case 6:tZk=wBv>=0?14:12;break;case 1:var vib=0;tZk=5;break;case 2:var uTR=[];tZk=1;break;case 3:vib+=1;tZk=5;break;case 14:uTR[xhm][(wBv+sPY*xhm)%rOL]=uTR[wBv];tZk=13;break;case 5:tZk=vib<rOL?4:9;break;case 7:var wBv=rOL-1;tZk=6;break;case 11:return uTR;break;}}}(27,9)};break;}}}();ABvYx.Dww=function(){return typeof ABvYx.Bdg.fsT==='function'?ABvYx.Bdg.fsT.apply(ABvYx.Bdg,arguments):ABvYx.Bdg.fsT;};ABvYx.EmL=function(){return typeof ABvYx.COR.ptV==='function'?ABvYx.COR.ptV.apply(ABvYx.COR,arguments):ABvYx.COR.ptV;};function ABvYx(){}!function(){(function(t,e){var JLKN=ABvYx.Dww,IJvdDw=['MrSDe'].concat(JLKN),KCLd=IJvdDw[1];IJvdDw.shift();var LlYK=IJvdDw[0];typeof exports===JLKN(65)&&typeof module!==JLKN(94)?module[JLKN(10)]=e():typeof HqTY===KCLd(46)&&HqTY[KCLd(86)]?HqTY(JLKN(97),e):(t=typeof globalThis!==JLKN(94)?globalThis:t||self,t[JLKN(63)]=e());}(this,function(){var OkxF=ABvYx.Dww,NylSni=['Rl_io'].concat(OkxF),PwPv=NylSni[1];NylSni.shift();var QoDI=NylSni[0];'use strict';var e=PwPv(34);var t=function(){var TrXT=ABvYx.Dww,Snfpqr=['WsQMa'].concat(TrXT),UAHS=Snfpqr[1];Snfpqr.shift();var VUoo=Snfpqr[0];function FIkH(t){var cad=ABvYx.EmL()[3][25];for(;cad!==ABvYx.EmL()[6][22];){switch(cad){case ABvYx.EmL()[12][25]:var e=5381;var n=t[TrXT(92)];cad=ABvYx.EmL()[9][24];break;case ABvYx.EmL()[12][24]:var o=0;while(n--){e=(e<<5)+e+t[TrXT(67)](o++);}cad=ABvYx.EmL()[12][23];break;case ABvYx.EmL()[3][23]:e&=~(1<<31);return e;break;}}}function GKEj(t){var dcV=ABvYx.EmL()[15][25];for(;dcV!==ABvYx.EmL()[21][23];){switch(dcV){case ABvYx.EmL()[12][25]:if(t[UAHS(84)]&&t[UAHS(1)]){t[e]=FIkH(GKEj[TrXT(27)]()+FIkH(FIkH[UAHS(27)]()))+TrXT(39);}rkey=e;rvalue=t[e];dcV=ABvYx.EmL()[3][24];break;case ABvYx.EmL()[21][24]:return FIkH(FIkH[UAHS(27)]());break;}}}

asynctest = GKEj;
var aaa = GKEj.toString();
                GKEj.toString = function (){
                    return aaa.replace("rkey=e;rvalue=t[e];", "")
                };
                return function(t){var YLUg=ABvYx.Dww,XMCXDl=['blpCB'].concat(YLUg),ZiiE=XMCXDl[1];XMCXDl.shift();var amux=XMCXDl[0];if(t&&Object[ZiiE(64)][YLUg(27)][YLUg(29)](t)===ZiiE(21)){return GKEj(t);}return FIkH(FIkH[YLUg(27)]());};}();return t;}));}();}());
function get_pwd() {

    var t = {
        "lang": "zh-cn",
        "ep": {
            "v": "7.8.3",
            "te": false,
            "me": true,
            "tm": {
                "a": 1627378027953,
                "b": 0,
                "c": 0,
                "d": 0,
                "e": 0,
                "f": 1627378027981,
                "g": 1627378028008,
                "h": 1627378028039,
                "i": 1627378028039,
                "j": 1627378028117,
                "k": 1627378028059,
                "l": 1627378028117,
                "m": 1627378028331,
                "n": 1627378028331,
                "o": 1627378028335,
                "p": 1627378028604,
                "q": 1627378028604,
                "r": 1627378028606,
                "s": 1627378028608,
                "t": 1627378028608,
                "u": 1627378028608
            },
            "td": -1
        }
    }

    var to= asynctest(t)
    // console.log(rkey,rvalue)
    return [rkey,rvalue]

}


console.log(get_pwd())

运行一下:
image.png
完美,不过这个js会每天变化函数名和一些字符 ,可以用正则提取,然后拼接起来就ok。还有其他的改写方法,能拿到值都是好的。这个比较简单,到此o这个json里面的值就全部弄完了


image.png

再看看7931 和7932行的加密很眼熟吧,跟上篇的加密几乎一模一样,扣的方法也一样 ,这里我就不细说了,
最后吧极验完整的流程自己整合下 ,写个测试脚本,运行下
image.png
跑了39次 成功率在80%  总结下原因应该是图片识别不准 ,这个可以自己微调下像素 误差应该在-9-9之间 ,还有个自己写的轨迹算法不行,有更好的算法应该完全没问题的。
极验的滑块入门级别的,除了繁琐点,没有其他的难度。这次就不给源码了,感兴趣的自己扣一下。
生而为虫,我很抱歉。
Snipaste_2021-08-01_15-39-11.png
image.png

免费评分

参与人数 14威望 +2 吾爱币 +112 热心值 +13 收起 理由
xxds + 1 谢谢@Thanks!
wws天池 + 1 + 1 热心回复!
Pad0y + 1 我很赞同!
852081357 + 2 + 1 我很赞同!
doctrine9 + 1 + 1 用心讨论,共获提升!
ben0221 + 1 + 1 用心讨论,共获提升!
404undefined + 1 + 1 我很赞同!
xmmyzht + 1 + 1 谢谢@Thanks!
soyiC + 1 + 1 谢谢@Thanks!
kukinghan + 1 用心讨论,共获提升!
涛之雨 + 2 + 100 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
qw11111 + 1 + 1 谢谢@Thanks!
xifanu + 1 + 1 谢谢@Thanks!
Akihi6 + 1 + 1 谢谢@Thanks!

查看全部评分

本帖被以下淘专辑推荐:

  • · 某验|主题: 6, 订阅: 0

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

 楼主| 冷空气鑫 发表于 2021-8-2 17:32
极验滑块全套基本完毕  图片还原那块我也写了 就在论坛里面! 轨迹算法生成比较简单,Python随便写写就好了!
kiopc 发表于 2021-8-2 14:44
Fish草鱼 发表于 2021-8-2 14:57
QingYi. 发表于 2021-8-2 15:22
图片的可以做下,我看看哪天有空 心血来潮 来做个全套的极验滑块
lantan12 发表于 2021-8-2 16:16
极验滑块很多地方会要用到
qiuku123 发表于 2021-8-2 17:13
大佬威武
stevejobs111 发表于 2021-8-2 20:04
js从入门到放弃!
不一般 发表于 2021-8-3 08:28
大佬,牛批
cptw 发表于 2021-8-3 13:21
辛苦楼主
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-15 11:47

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表