声明本文所有内容仅供学习交流,抓包内容、敏感网址、数据接口等内容均已处理已脱敏,严禁用于商业用途和非法使用,否则由此产生的一切后果与作者无关,如有侵权,请立即联系我删除!本文未经许可禁止转载,修改后禁止二次传播。对于因未经授权使用本文所解释的技术而导致的任何事故,作者概不负责。如有侵权,请第一时间联系作者公众号【K爬虫哥】删除!反向目标目标:A测试四代滑块验证码,w参数反向主页:aHR0cHM6Ly9ndDQuZ2VldGVzdC5jb20v加密算法:RSA,AES通信过程验证码流程分析进入网页后,打开开发者工具抓包,点击滑动拼图验证,这个在点击按钮开始验证之前,抓到一个名为load?captcha_id=xxx的包,QueryStringParameters包含一些参数:challenge:动态变化,由gtc4.js文件生成,稍后分析;client_type:表示web端;risk_type:验证码类型,比如slider是slide,senseless是ai;lang:语言;callback:geetest_+Timestamp,主要作用是防止缓存。响应预览中返回的关键内容如下。与三代相比,底图没有混淆:bg:背景图片地址;captcha_type:验证码类型;gct_path:gct4文件路径;lot_number:后续生成pow_msg和w的关键参数;payload:后续验证请求接口需要的参数;datetime:ISO8601扩展格式的日期,后续生成pow_msg的关键参数;process_token:后续验证请求接口需要的参数;slice:滑块图像地址。点击按钮开始验证,会弹出滑块验证码,滑动滑块,抓包验证?captcha_id=xxx,QueryStringParameters中还包含一些参数:captcha_id:与加载的请求头中的captcha_id一致界面;client_type:web端;lot_number:加载接口返回;risk_type:与加载界面一致,表示验证码类型;payload:由加载接口返回;process_token:加载接口返回;w:加密参数,由轨迹、滑动时间、滑动距离组成,Userresponse、device_id、pow_msg等参数被加密;callback:geetest_+timestamp,主要作用是防止缓存。响应预览返回内容如下,结果值为fail,表示验证失败,success表示验证通过,通过后携带seccode下的参数进行后续业务请求:反向解析captcha_id参数全局搜索captcha_id,跟进到gt4.js文件中:进入后,在307行设置断点,刷新页面就停止了。这个时候已经生成了captcha_id参数的值,在下一行定义了challenge参数:顺着栈往上看,也就是ad??aptive-captcha-demo.js文件中,你会发现它是一个固定值。事实上,这个值对于每个网站都是不同的。由管理员在Geetest后台应用中获取:前面提到的challenge参数,challenge参数定义在captcha_id参数的下一行,在gt4中。在js文件第309行打断点:可以看到challenge参数的值是由uuid函数生成的,减去即可。w参数从verify?captcha_id=xxx接口的栈开始跟栈:设置断点,滑动滑块停止后,跟栈直到s。如果你做过三代滑块测试的话,6249行有一个很熟悉的“\u0077”:r,“\u0077”是字母w的Unicode值,r是w参数的值:r参数在6237行定义,e也是类似第三代的参数,r是i参数和e参数的组合e参数转换成字符串是通过加密得到的:跟进栈,找到生成e参数中各部分定义的位置,跟着进入$_BHIH,_先生生成四个键值对:passtime和track就是大家熟悉的滑动时间和轨迹,setLeft是识别的间隙距离,userresponse是19593行定义,a为setLeft参数的值,t[$_GDFCG(1909)]为固定值1.0059466666666665:a/t[$_GDFCG(1909)]+2然后在$_BCFj中,e定义在行6201,下面几行定义了device_id,lot_number,pow_msg,pow_signine:device_id是同一个网站的固定值,lot_number是loadresponse返回的,控制台打印pow_msg,pow_sign的结果:pow_msg显然是由几部分组成的。pow_sign加密后,接着是init,分别在5837行和5838行定义。是d字典的key,根据key名取值:d定义在第5835行,还原这部分很明显:varc=t["toDataURL"]()["replace"]("data:image/png;base64,",""),_=neww["default"]["MD5"]()["hex"](c);a["options"]["deviceId"]=_;varh=a["options"],l=h["powDetail"],p=h["lotNumber"],f=h["captchaId"],d=v["default"](p,f,l["hashfunc"],l["version"],l["bits"],l["datetime"],"")跟进v["default"],函数定义在6945行,在6978行设置断点:pow_msg通过_获取+h,_在第6960行定义:_=i+"|"+r+"|"+n+"|"+s+"|"+t+"|"+e+"|"+o+"|";i:l["version"]r:l["bits"]n:l["hashfunc"]s:l["datetime"]t:f,h["captchaId"]e:p,h["lotNumber"]o:""h在6269行定义,后面是一个16位的随机数串,pow_sign为p,用MD5对pow_msg进行加密得到:至此,这四个都分析完了,并且还缺少下面部分:Em等固定值就不分析了,注意kqg5:"1557244628",这个参数值和三代slider中一样,每隔几个小时就会变化,follow栈到$_BCFj,在6207行设置断点,此时e中的值还没有tbeengenerated:在下一行设置断点,下一个断点,即执行n[$_CBHIE(791)](e);后,生成参数值,证明为n[$_CBHIE(791))]方法,后续:跳转到5766行,在5779行设置断点,此时n中还没有生成这个参数:execute_gct(n)并且生成了:可以看出它的生成位置在_gct方法中,跟着它之后会到gct4.js文件,从三代开始就不错了:可以导出值,至此e分析完毕,然后回到6238行,后续在11669行定义的加密函数d[$_CBHHO(84)]中,d[$_DIEHS(177)](c)+u的值为参数r,c是一个大数组,而u显然是加密过的,所以r参数的值是数组c加密后加上u得到的:先跟进u,它的定义在11705行。de-混淆,如下:u=newl["default"]()["encrypt"](i);所以u是i加密后得到的,在11702行定义了i:i=(0,d[$_DIEIq(103)])()之后是d[$_DIEIq(103)],定义在11702行852,又是熟悉的16位随机数:i是随机数,跟进加密函数l[($_DIEHS(84))],在12725行,在12741行设置断点,可以看到这是一个RSA加密,直接扣代码或者直接引用库:回到c参数,c参数的值是一个大数组,定义在11705行,去混淆后的内容如下:varc=s[a]["对称"]["加密"](e,i);之前分析过e,i是随机数,两个参数分析过,跟进加密方式,在12174行,在12186行设置断点,控制台打印混淆部分内容,很熟悉了,这里是AES加密,iv是初始向量,加密方式是CBC。对各种加密算法不熟悉的可以看K哥的文章【爬虫知识】爬虫常用加解密算法:c参数最后通过d[$_DIEHS(177)]函数加密。
