个人网站用凡科建站好吗,如何使用seo进行综合查询,网站发稿平台,深圳做微信网站制作声明#xff1a;该专栏涉及的所有案例均为学习使用#xff0c;严禁用于商业用途和非法用途#xff0c;否则由此产生的一切后果均与作者无关#xff01;如有侵权#xff0c;请私信联系本人删帖#xff01; 文章目录 一、前言二、抓包流程分析1.刷新页面2.点击按钮进行验证… 声明该专栏涉及的所有案例均为学习使用严禁用于商业用途和非法用途否则由此产生的一切后果均与作者无关如有侵权请私信联系本人删帖 文章目录 一、前言二、抓包流程分析1.刷新页面2.点击按钮进行验证3.滑动验证码 三、图片还原四、w值①u值②l值③h值④l中的o值aa参数passtime参数userresponse参数rp参数 五、结果 一、前言
看一下极验3的流程分析
aHR0cHM6Ly93d3cuZ2VldGVzdC5jb20vU2Vuc2Vib3Q二、抓包流程分析
1.刷新页面
①第1个包register-slide 注册滑块条
返回gt和challenge
②第2个包gettype.php 获取验证码
携带①包的gt值
③第3个包get.php
携带的值
gt: ①返回的
challenge: ①返回的
lang: zh-cn
pt: 0
client_type: web
w:加密值可为空
callback: geetest_1705890896070而第二个get请求是携带gt和challenge和一个加密值w经测试w值可以不带
2.点击按钮进行验证 ④第4个包ajax.php 携带的值
gt: 第1个包返回
challenge: 第1个包返回
lang: zh-cn
pt: 0
client_type: web
w: 可以置空
callback: geetest_1705891494273返回 ⑤第五个包get.php 获取图片和新challenge 携带参数
is_next: true
type: slide3
gt: 第1个包返回
challenge: 第1个包返回
lang: zh-cn
https: true
protocol: https://
offline: false
product: embed
api_server: api.geetest.com
isPC: true
autoReset: true
width: 100%
callback: geetest_1705891493735返回了图片的下载地址其中包含打乱顺序的底图和滑块图还有新的challenge
3.滑动验证码
⑥第6个包ajax.php 校验滑块w参数包含轨迹携带gt和challenge
成功返回
失败返回 像前边除了校验的我们都可以直接请求出来 然后获取到图片后进行图片的还原
三、图片还原
在我们抓包的过程中我们抓到了图片的包是一个打乱的图片一共有两个打乱的图片一个是完整的底图一个是有滑块缺口的底图 我们写完前四个流程的代码第四个包返回的图片的url也是这样
而页面中的图片也是通过canvas渲染上去的 那我们就要想办法还原底图,我们直接勾选canvas断点
点击加载图片按钮会直接断住经过跟值会锁定的这个位置是底图还原的关键代码 这里会得到一个正确顺序的数组只要根据上诉算法还原即可。这里直接用十一姐大佬的代码 无序图 还原后
然后识别出距离即可这里还是用的ddddocr需要距离-10因为比实际多算了10px
四、w值
搞完前几部分只剩下w值这个w值应该会和滑动的轨迹相关。那我们分析一下这个w值从滑动的包的第一个堆栈进入
打上断点然后断住往上找堆栈很快就会找到这个位置 f值中的\u0077是w的Unicode编码它在这里生成
w h u
u r[$_CAHJS(737)]()
l V[$_CAHJS(392)](gt[$_CAIAK(254)](o), r[$_CAIAK(744)]())
h m[$_CAIAK(792)](l)由于极验是动态js这里的h和u名称是动态变化的这里暂时是u和h
①u值 先来看u值进入u值的断点看到返回的是e
大概就是将this[$_CBGAK(744)](t)生成的16位字符串用new U()[encrypt]进行了加密,我们看一下这个16位的字符串是怎么生成的 进入后 再进,挂住断点发现断不住需要重新刷新页面可以断住 该值就是一个随机数拼接自己创建个函数。 创建出16位的字符串后被new U()[encrypt]加密我们看一下new U()能看到setPublic一般RSA才有这些类似方法 而rsa需要两个参数加密文本公钥。获取公钥进入setPublic的函数 在这里打断点刷新一下页面 这个就是公钥
我们用python库实现
import rsa
from binascii import b2a_hexdef rsa_encrypt_text(key, _text: str):RSA加密:param key: 公钥的参数:param _text: 待加密的明文:return: 加密后的数据e int(010001, 16)n int(key, 16)pub_key rsa.PublicKey(ee, nn)return b2a_hex(rsa.encrypt(_text.encode(), pub_key)).decode()if __name__ __main__:key 00C1E3934D1614465B33053E7F48EE4EC87B14B95EF88947713D25EECBFF7E74C7977D02DC1D9451F79DD5D1C10C29ACB6A9B4D6FB7D0A0279B6719E1772565F09AF627715919221AEF91899CAE08C0D686D748B20A3603BE2318CA6BC2B59706592A9219D0BF05C9F65023A21D2330807252AE0066D59CEEFA5F2748EA80BAB81_text d4e0165efa3c7712result rsa_encrypt_text(key, _text)print(result) ②l值
再看h值h值参数是l需要先看l 控制台输出一下各个值清晰一点
l V[encrypt](gt[stringify](o), r[$_CCEV]())
h m[$_FEE](l)相当于在 V[encrypt]中传入了两个参数一个是那一个json串估计是加密值另一个经过跟栈就是上边生成的随机16个字符串最后结果是得到一个数组 o值应该包含轨迹加密暂时先放放我们先看看 V[encrypt] 在这里看到iv关键字是AES加密那么需要找到keyiv加密内容 经上边看到iv是0000000000000000,key是随机16位字符串与u值中使用的字符串要相等这里用js实现
var CryptoJS require(crypto-js);// 随机生成16位字符串
function get_random_str() {var random_str ;for (var i 0; i 4; i) {random_str (65536 * (1 Math[random]()) | 0)[toString](16)[substring](1);}return random_str;
}// aes
function aes_encrypt(key, _iv, value) {var e CryptoJS.enc.Utf8.parse(key);var iv CryptoJS.enc.Utf8.parse(_iv);var l CryptoJS.enc.Utf8.parse(value);return CryptoJS.AES.encrypt(l, e, {mode: CryptoJS.mode.CBC,padding: CryptoJS.pad.Pkcs7,iv: iv})
};var get_arry_i function (i, a) {var o [];for (var s 0; s a; s) {var c i[s 2] 24 - s % 4 * 8 255;o[push](c);}return o;
};var value {lang:zh-cn,userresponse:cccccc66c6c6688d75,passtime:350,imgload:64,aa:O!)(!!H(xysyttsysAt(!!(Zb--5-Y7*7*96$*8_,ep:{v:7.9.0,$_BIo:false,me:true,tm:{a:1680165934423,b:1680165934777,c:1680165934777,d:0,e:0,f:1680165934429,g:1680165934433,h:1680165934440,i:1680165934440,j:1680165934535,k:1680165934442,l:1680165934535,m:1680165934772,n:1680165934774,o:1680165934779,p:1680165935041,q:1680165935041,r:1680165935044,s:1680165935070,t:1680165935070,u:1680165935071},td:-1},h9s9:1816378497,rp:56f9ced1740a4656d430a1dfa0bd697b};
var aes_result aes_encrypt(get_random_str(), 0000000000000000, value);
var u get_arry_i(aes_result[ciphertext][words], aes_result[ciphertext][sigBytes]);console.log(u); ③h值
h m[$_CAIAj(783)](l)断点进入 再进去 这里我们抠出这个函数即可把这个函数对象的方法都扣下来 运行一下缺什么补什么 修改一下获取h的方法变量先用浏览器抠的固定值 都抠出来 运行一下 ④l中的o值
看刚才l的o值 示例 {lang: zh-cn,userresponse: cccccc66c6c6688d75,passtime: 350,imgload: 64,aa: O!)(!!H(xysyttsysAt(!!(Zb--5-Y7*7*96$*8_,ep: {v: 7.9.0,$_BIo: false,me: true,tm: {a: 1680165934423,b: 1680165934777,c: 1680165934777,...省略},td: -1},h9s9: 1816378497,rp: 56f9ced1740a4656d430a1dfa0bd697b}h9s9【可以写死】随机参数影响不大imgload【可以写死】图片加载时间随机生成ep【可以写死】涉及v和tmv是js文件的版本tm和window[performance][timing]相关可以根据Performance.timing 时间产生的先后顺序以及时间间隔用当前的时间戳减去相应的值来模拟。aa对轨迹和响应的c和s参数进行了加密passtime轨迹滑动总时长rp//gt 32 位 challenge passtime再经过 MD5 加密userresponse 滑动距离x challenge 的值
这些参数往上翻一点可以看到生成的地方
aa参数
这里看一下aa是第二个参数追上一个栈 就是这里的l l是由上一行的函数生成需要三个参数其中后两个是我们曾经抓包的响应c和s
第一个参数就是加密后的轨迹而前边的部分就是轨迹数组应该是x,y,t
进去这个函数看看怎么加密的轨迹 进来到这里使用了轨迹列表
看最后跟到这里变成了加密
我们直接把这个方法抠出来传一个轨迹 把使用的地方改为我们的轨迹 然后抠一个浏览器的轨迹运行缺什么补什么注意抠ct的时候有个坑需要补一下 最后抠出来这几个
拿浏览器的轨迹试验对比一下 到此轨迹的加密就获取出来了 接下来继续后边的参数是c和s直接断点抠下来就可以 至此这个l就是我们的aa参数
passtime参数
取轨迹的最后一个列表的的最后一位数
passtime track[-1][-1] #滑动时间userresponse参数 t为我们轨迹的滑动x距离另外一个为challenge然后H函数 抠出来修改亿点点
function H(t, e) {var $_CJES mwbxQ.$_Cg, $_BEGI_ [$_BEHCp].concat($_CJES), $_BEHAO $_BEGI_[1];$_BEGI_.shift();var $_DAJEI mwbxQ.$_DW()[9][13];for (; $_DAJEI ! mwbxQ.$_DW()[0][11];) {switch ($_DAJEI) {case mwbxQ.$_DW()[6][13]:for (var n e[$_CJES(187)](-2), r [], i 0; i n[$_CJES(192)]; i) {var o n[charCodeAt](i);r[i] 57 o ? o - 87 : o - 48;}n 36 * r[0] r[1];var s, a Math[$_CJES(158)](t) n, _ [[], [], [], [], []], c {}, u 0;i 0;$_DAJEI mwbxQ.$_DW()[6][12];break;case mwbxQ.$_DW()[0][12]:for (var l (e e[$_CJES(187)](0, -2))[length]; i l; i)c[s e[$_CJES(125)](i)] || (c[s] 1,_[u][$_CJES(137)](s),u 5 u ? 0 : u);var h, f a, d 4, p , g [1, 2, 5, 10, 50];while (0 f)0 f - g[d] ? (h parseInt(Math[random]() * _[d][length], 10),p _[d][h],f - g[d]) : (_[$_CJES(115)](d, 1),g[$_CJES(115)](d, 1),d - 1);return p;break;}}
}rp参数
这个值在w生成的上一点点 结果32位 有点像md5试验一下 至此所有参数搞定
五、结果
效果展示 其他情况
// challenge 不对
geetest_xxxxxxxxxxxxx({status: error, error: illegal challenge, user_error: 网络不给力, error_code: error_23})
// w 生成不对
geetest_xxxxxxxxxxxxx({status: error, error: param decrypt error, user_error: 网络不给力, error_code: error_03})
// 滑动验证没有轨迹
geetest_xxxxxxxxxxxxx({status: error, error: not proof, user_error: 网络不给力, error_code: error_21})
// 轨迹、缺口距离、参数问题
geetest_xxxxxxxxxxxxx({success: 0, message: fail})
geetest_xxxxxxxxxxxxx({success: 0, message: forbidden})