js逆向百度旋转验证码并通过验证
在公众号之前的一篇文章写到用pyppeteer模拟轨迹进行识别。https://mp.weixin.qq.com/s/aHeYmRMx4NIfN5shch-WfA 大家可以自行前往学习了解。本次带来一个更加轻松的识别通过,就是通过js完成距离通过验证。下面就主要讲解一下思路,具体操作验证还需要完善一下代码。
旋转验证码逆向的主要问题是解决动态参数,只要解决动态的参数的来源就可以。经过测试发现fs是变化的
进入断点测试,给相应位置打上断点。可以看到fs是通过AES加密
除了fk字段需要通过补js环境进行还原,其次就是as、backstr字段需要获取,这个可以requests模拟请求进行解析获取即可
然后就是angle角度的识别,角度的识别,推荐文章:预测旋转角度推荐nanda大佬的文章:https://mp.weixin.qq.com/s/G5Bm0DfoUDy_a2KOc_gNRw
在r.rzData中ac_c=round((o / 212),2),而o是滑动的距离,o=angle*212/360 (angle)是识别的角度。然后backstr是前面返回的,其他的所有参数都可固定,包括轨迹。那么ac_c = (angle*212/360/212).toFixed(2).
接下来在代码中进行复现还原一下。
首先是获取旋转图片和backstr,图片地址和backstr都会在这个请求中响应,拿到响应数据就可以进行解析了。
def getImg(self): self.session.get(self.url,headers=self.headers) params = { 'callback': 'jQuery110204891335603986202_' + str(time.time()*1000), 'ak':'c27bbc89afca0463650ac9bde68ebe06', 'tk':'5186ttnIrhB1fBEkLt2uExpiLynx575uW1bx1HchF8dIw5m1j2PMQ5M4LGvMDVkzsNJED+1NmBKZjNwb+DoGQMwpSEETXal5AvVi9LjiHsOc9nnbIpz1iydwbSFWtFQKl2ggAufwNwxaINHUAZKgbwb5zQ==', 'scene':'', 'isios': 0, 'type': 'spin', '_': str(time.time()*1000) } styleUrl = 'https://wappass.baidu.com/viewlog/getstyle' resp = self.session.get(url=styleUrl,headers=self.headers,params=params).text jsonStr = re.findall(r'.*?\((.*?)\)',resp,re.S)[0] jsonDict = json.loads(jsonStr) print(jsonDict) self.backstr = jsonDict['data']['backstr'] print(self.backstr) imgUrl = unquote(jsonDict['data']['ext']['img']) imgContent = self.session.get(url=imgUrl,headers=self.headers).content image = Image.open(BytesIO(imgContent)) image.save('1.png')
这样运行后,图片就保存到本地了,我们在本地查看一下待旋转的图片
其次就是获取as字段信息,as字段在一开始的请求响应中会出现,同样解析一下就可以获取
def getAs(self): self.session.get(self.url,headers=self.headers) params = { 'callback': 'jQuery110204591104788231357_' + str(time.time()*1000), 'ak':'c27bbc89afca0463650ac9bde68ebe06', '_': str(time.time()*1000) } resp = self.session.get(url=self.verifyUrl,headers=self.headers,params=params).text jsonStr = re.findall(r'.*?\((.*?)\)',resp,re.S)[0] jsonDict = json.loads(jsonStr) self.aas = jsonDict['data']['as'] print(self.aas)
接下来重要的就是补crypto.js环境,然后获取fk字段参数信息。这里的r就是最终的fk字段信息了。
在python代码中调用fk信息。
def getFk(self): with open('code.js','r') as f: codejs = f.read() aesObj = execjs.compile(codejs).eval(f"get_fk({self.aas},{self.angle},{self.backstr})")
一切准备就绪,剩下的就是运行了,只要运行的op=1,那么验证码就识别通过了。
核心问题已经解决,由于时间关系,具体运行代码还需要完善,完善过后就可以正常调用接口进行识别距离,并通过验证。如果有朋友百度旋转验证码感兴趣,可以私信我获取源码,并教会大家使用。但是需要一定的有偿获取。