声明
本文章中所有内容仅供学习交流使用,不用于其他任何目的,不提供完整代码,抓包内容、敏感网址、数据接口等均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关!
本文章未经许可禁止转载,禁止任何修改后二次传播,擅自使用本文讲解的技术而导致的任何意外,作者均不负责,若有侵权,请在公众号【逆向那点事】联系作者立即删除!
目标:某CP
地址:aHR0cHM6Ly9iZWlhbi5taWl0Lmdvdi5jbg==
首先会弹出一种中文字符点选的验证码:
此验证码存在非常多字体与背景模糊不清的情况,处理起来比较麻烦,这里为了简单直接使用打码平台:极通识别来过即可
流程分析
首次访问首页会返回521状态码,同时设置一个__jsluid_s cookie:
然后带上__jsluid_s、__jsl_clearance_s两个cookie去访问首页:
接着会请求一个/icpproject_query/api/auth接口,这是一个POST表单请求,传递timeStamp和authKey两个参数分别表示当前时间戳和时间戳变体的md5值,返回bussiness、expire、refresh参数,分别表示token、剩余有效时间(毫秒)、刷新token,同时还返回一个cookie __jsluid_s :
验证码图片获取,请求头传递了auth接口返回的token过去:
请求体则是一个随机的clientUid,该uid用于后面验证码校验时的凭证:
返回内容bigImage是背景图的base64字符串,smallImage是小图的base64字符串,uuid此验证码的标识,secretKey用于加密识别结果的,wordCount表示字符数量:
验证码校验,也需要传递token请求头过去:
内容包含token是获取验证码图片时返回的uuid参数、clientUid是获取验证码图片时发送的clientUid参数、secretKey是获取验证码图片时返回的secretKey参数、pointJson则是验证码的点击坐标点的加密数据:
验证码校验结果包含,smallImage是一张表示验证结果的图片、sign则是用于后续的查询请求:
后续的查询请求,通过token、验证码的校验结果sign、获取验证码图片时返回结果中的uuid,以及一个名为__jsluid_s的32为长度字符串的cookie来访问即可,该cookie可以是前面的auth接口设置的也可以自己通过uuid等来生成:
整体流程就是:
①通过auth接口传递authKey和timeStamp来获取token
②通过token和clientUid获取验证码图片、uuid、secretKey
③对验证码图片进行识别,获取到结果的位点
④将位点用步骤②中返回的secretKey进行加密
⑤使用token、步骤②中的uuid、secretKey、clientUid以及步骤④中的加密数据来校验验证码,并获得sign参数
⑥通过步骤⑤中的校验结果sign来查询数据
这里面的关键是验证码识别位点的加密结果,而其又依赖于token、clientUid。
因此先分析auth接口,打上断点发现传递给auth接口的timeStamp是时间戳,而authKey是"testtest"+timeStamp后的md5值:
再来看看获取验证码的接口,进入断点后往上跟栈可以发现请求参数clientUid是localstorage中的point:
而point则是本地生成的uuid值:
下面开始分析验证码校验接口,打上XHR断点:
向上跟栈发现关键代码:
可以看到JSON.stringify(g.checkPointArr)应该是将位点的json对象序列化,并将secretKey参数传入。再往里跟豁然开朗,使用的是AES对称算法加密的:
校验下:
至此,获取验证码、校验、查询的过程所需参数分析完毕。