ks滑块验证码逆向分析与python识别

文章目录

  • 1. 写在前面
  • 3. 接口分析
  • 3. 算法实现

【🏠作者主页】:吴秋霖
【💼作者介绍】:擅长爬虫与JS加密逆向分析!Python领域优质创作者、CSDN博客专家、阿里云博客专家、华为云享专家。一路走来长期坚守并致力于Python与爬虫领域研究与开发工作!
【🌟作者推荐】:对爬虫领域以及JS逆向分析感兴趣的朋友可以关注《爬虫JS逆向实战》《深耕爬虫领域》
未来作者会持续更新所用到、学到、看到的技术知识!包括但不限于:各类验证码突防、爬虫APP与JS逆向分析、RPA自动化、分布式爬虫、Python领域等相关文章

作者声明:文章仅供学习交流与参考!严禁用于任何商业与非法用途!否则由此产生的一切后果均与作者无关!如有侵权,请联系作者本人进行删除!

1. 写在前面

  目前很多场景下很是容易就会弹出滑块验证的,所以想要做到完整的业务自动化流程就必须要解决滑块验证处理的问题。整个流程还是比较清晰的,分析起来倒不是特别难。要主要的就是轨迹跟环境,目前基本风控都是在轨迹上面,检测到了可能就封禁了

在这里插入图片描述

3. 接口分析

这里我们从登录入口开始分析,v2这个接口则是登录接口,提交账号密码即可(不过同样账密有加密),大致看了一下,貌似是RSA的一个加密(感兴趣的可以自行去研究一下、难度不大),这个接口我们提交登录的时候是必然会出现滑块验证的,如下所示:

在这里插入图片描述

当出现滑块验证的时候,我们是可以通过接口响应来判别的。比如result的结果值400002即代表出现滑块。这里我们需要拿一个关键的参数值,也是后续提交验证的核心参数!

如上图,就是captchaSession参数,在v的接口响应跟后续提交验证的config接口的请求中都能看到,如下所示:

在这里插入图片描述

请求config接口的时候记得携带Cookie参数中did,响应结果字段还是蛮多的。如下所示:

{"result": 1,"desc": "ok","captchaSn": "Cgp6dC5jYXB0Y2hhEvkCo5aBtplfuTMJKPP4elMkoeGHwD6DRDVR_Do1W92hq1McGZ9kyrefCHrILkt03oI1acxT6TyLDIfgWhxqtHGmjcWsGtbWr7BM4zcClrXOQz-PWrgzLqD5XWDjKVcidXjqfvx_DHlSCW9APTEU78VoW27bs3nrU2UcEVf7E6P7m7REt7XQlGEm-QBGVGs4pAGIJiGtHz7afR6N6GqFyP1H8TfDXkTf1nZwp4IoVk-dlWX8Tyf-NAbIhjt5IZUnVh8g1kcIvU42TGsGZ3JFEoKu2eaeAN9Ed3xW9wfZGVsMpZH98QglhK_Gg1to8_y8wWlZ2ehk1Mo5KhGVjVGMsUaVDBt0BqBQHwxrBylQhqUefHdFZnIlp22H-RbEdbaGaepcVp2a2fdwCnrMd0mqBX4MOA6iFTjuoHmr3Gz39R71DWJx9SGcreVEX9SotPXfI3jVAt_gzasUwdFv87-EvXt6r_EYLK2stqY5K2jRiYxDQhPWMfshurniyZcaEs0SRXZhpgX7OQIs-8MFfIBJ5SgFMAI","bgPicUrl": "https://captcha.zt.kuaishou.com/rest/zt/captcha/sliding/bgPic","cutPicUrl": "https://captcha.zt.kuaishou.com/rest/zt/captcha/sliding/cutPic","bgPicWidth": 686,"bgPicHeight": 400,"cutPicWidth": 122,"cutPicHeight": 122,"disX": 16,"disY": 150,"verifyUrl": "https://captcha.zt.kuaishou.com/rest/zt/captcha/sliding/verify","refSes": "https://captcha.zt.kuaishou.com/rest/zt/captcha/refSes","collectLimit": 1000,"verifyUrl2": "https://captcha.zt.kuaishou.com/rest/zt/captcha/sliding/kSecretApiVerify","a": 7,"q": 2.7228154734627554,"sx": 1,"ix": 79,"sy": 4,"iy": 66
}
  • captchaSn参数主要就是通过拼接下面的背景、缺口URL字段来获取到完整的图片
  • a、q、sx、ix、sy、iy这几个参数是比较重要的,滑块轨迹生成算法的重要参数值

剩余那些参数就不值一提了,图片的宽高以及后续用来提交验证的接口,提交验证的接口这里我们再看看,如下所示:

在这里插入图片描述

验证接口提交一个verifyParam参数,提交验证出现的情况场景还是比较多的,先说说常规的result状态码分别所对应的情况,如下所示:

  • 350002(缺口识别有问题-没对上~
  • 350014(轨迹有问题
  • 350005(加密参数有问题

还有一个概率性场景,就是在通过滑块之后会再次触发二次验证(可能是旋转滑块验证码、也有可能是点选验证码~~

不过只要你的IP质量足够的优质、那么最后这个概率性的风控场景也是可以规避的!!!

在这里插入图片描述

看上图,是滑块验证成功接口返回的数据,captchaToken参数是我们需要的,将它的值放到登录提交的参数ztIdentityVerificationCheckToken内提交即可完成登录

3. 算法实现

接着上面接口的流程分析,首先第一步我们需要对上面config接口中返回所拼接的背景、缺口图片进行一个简单的请求并识别,实现代码如下所示:

import ddddocr
import numpy as np
import cv2def match_slider_captcha(background, target, output_path=None, is_path=False):ocr_detector = ddddocr.DdddOcr(det=False, ocr=False, show_ad=False)if is_path:with open(target, 'rb') as f:target_bytes = f.read()with open(background, 'rb') as f:background_bytes = f.read()else:target_bytes = targetbackground_bytes = backgroundresult = ocr_detector.slide_match(target_bytes, background_bytes)if output_path:top_left = result['target'][:2]bottom_right = result['target'][2:]bg_image_data = np.frombuffer(background_bytes, np.uint8)bg_image = cv2.imdecode(bg_image_data, cv2.IMREAD_COLOR)cv2.rectangle(bg_image, top_left, bottom_right, (0, 0, 255), 2)cv2.imwrite(output_path, bg_image)return result['target'][:2]

拿到识别的坐标后,我们需要生成最重要的轨迹数组!生成轨迹数组将会用到上面我们分析的config接口返回的a、q、sx、ix、sy、iy几个参数,这里我们还是参考并通过构造贝塞尔曲线的方式直接来生成轨迹点。具体的算法实现代码如下:

import math
import random
import numpy as npclass BezierCurve:def __init__(self, start, end, points, order=1, deviation=0, bias=0.5, motion_type=0, oscillations=0, osc_range=10):self.start = np.array(start)self.end = np.array(end)self.points = pointsself.order = orderself.deviation = deviationself.bias = biasself.motion_type = motion_typeself.oscillations = oscillationsself.osc_range = osc_rangedef _calculate_bezier(self, trajectory):def bezier_func(t):n = len(trajectory) - 1return sum(math.comb(n, i) * (t ** i) * ((1 - t) ** (n - i)) * np.array(point)for i, point in enumerate(trajectory))return bezier_funcdef _generate_motion_curve(self, x_range):interval = (x_range[1] - x_range[0]) / self.pointsif self.motion_type == 1:return [(i * interval) ** 2 for i in range(self.points)][::-1]elif self.motion_type == 2:return [(i * interval - x_range[1]) ** 2 for i in range(self.points)]else:return [i * interval for i in range(self.points)][::-1]def create_curve(self):control_points = []if self.order != 1:step = (1 - self.bias) / (self.order - 1)control_points = [[self.bias + step * i, self.bias + step * (i + 1)] for i in range(self.order - 1)]trajectory = [self.start]for interval in control_points:px = self.start[0] + (self.end[0] - self.start[0]) * (random.random() * (interval[1] - interval[0]) + interval[0])py = self._calculate_bezier([self.start, self.end])(px) + random.choice([-1, 1]) * self.deviationtrajectory.append([px, py])trajectory.append(self.end)return self._calculate_bezier(trajectory)def generate_track(self):track = []bezier_func = self.create_curve()x_values = self._generate_motion_curve([self.start[0], self.end[0]])for x in x_values:track.append([x, bezier_func(x)])return np.array(track).astype(int)def generate_slider_trace(distance, offset_x, offset_y, scale_x, scale_y, control_x, control_y, complexity):start_x = random.randint(0, 10)start_y = random.randint(5, 25)end_y = random.randint(10, 40)total_points = random.randint(100, 500)osc_count = random.randint(5, 40)osc_range = random.randint(7, 30)speed_type = random.randint(0, 2)end_deviation = random.randint(0, 30)random_bias = random.random()bezier = BezierCurve(start=[start_x, start_y],end=[distance, end_y],points=total_points,order=complexity,deviation=end_deviation,bias=random_bias,motion_type=speed_type,oscillations=osc_count,osc_range=osc_range)track_list = bezier.generate_track().tolist()track_list = [[x * scale_x + offset_x, y * scale_y + offset_y] for x, y in track_list]result = [f"{x}|{y}" for x, y in track_list]return ",".join(result)# 传递参数第一个是滑块移动的距离、剩下的几个参数在config接口拿
print(generate_slider_trace(distance, ix, iy, sx, sy, a, q, d))

解决完轨迹以后,接下来需要处理验证接口提交的verifyParam参数,这个是加密的!这里直接关键词搜索就能够定位到关键位置,如下所示:

在这里插入图片描述

a的生成在一堆case的控制流里面,直接AST后往上分析能够看到生成调用流程,如下所示:

在这里插入图片描述

Tt[‘a’]这个方法则是具体的加密逻辑,跟进去后可以看到verifyParam请求参数的明文信息,包含了轨迹、图片信息、前面接口所返回的一些密文…如下所示:

在这里插入图片描述

一共是10个参数,大部分都很熟悉。这里说一下gpuInfo、captchaExtraParam、trajectory三个参数,从前往后分别对应的显卡指纹、浏览器指纹、轨迹

在这里插入图片描述

接下来就是扣取verifyParam加密算法了,加密算法扣下来的话也就1000来行。大致的一个加密流程就是将这10个参数进行拼接编码、转换为uint8数组、位移得到新数组、最后对这个数组进行一个Base64的编码,加密算法运行如下所示:

在这里插入图片描述

最后作者也是封装完成了整个滑块验证识别的流程,测试效果如下所示(处理好轨迹跟环境以及IP基本还是非常稳定的):

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/3268893.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

从零搭建pytorch模型教程(八)实践部分(二)目标检测数据集格式转换

前言 图像目标检测领域有一个非常著名的数据集叫做COCO,基本上现在在目标检测领域发论文,COCO是不可能绕过的Benchmark。因此许多的开源目标检测算法框架都会支持解析COCO数据集格式。通过将其他数据集格式转换成COCO格式可以无痛的使用这些开源框架来训…

在MATLAB中使用importrobot导入机械臂刚体树时没有找到模型文件,只显示坐标;改为使用loadrobot

没有mesh文件夹,所以找不到模型文件 改为使用loadrobot,直接加载刚体树数据

【C++题解】1782. 字符图形2-星号倒直角

问题&#xff1a;1782. 字符图形2-星号倒直角 类型&#xff1a;嵌套循环、图形输出 题目描述&#xff1a; 打印字符图形。 输入&#xff1a; 一个整数&#xff08; 0<n<10 &#xff09;。 输出&#xff1a; 一个字符图形。 样例&#xff1a; 输入&#xff1a; 3…

重生之我当程序猿外包

第一章 个人介绍与收入历程 我出生于1999年&#xff0c;在大四下学期进入了一家互联网公司实习。当时的实习工资是3500元&#xff0c;公司还提供住宿。作为一名实习生&#xff0c;这个工资足够支付生活开销&#xff0c;每个月还能给父母转1000元&#xff0c;自己留2500元用来吃…

深入探讨 I/O 多路复用:提升系统 I/O 效率的关键技术

摘要 I/O&#xff08;输入/输出&#xff09;操作是计算机系统中不可或缺的一部分&#xff0c;而 I/O 多路复用技术则是提高系统 I/O 效率的重要手段。本文将浅谈 I/O 的基本概念&#xff0c;重点探讨 I/O 多路复用技术的原理、优势以及在现代系统中的应用。 引言 在现代计算…

LoRaWAN设备的两种入网方式(ABP和OTAA)

目录 一、OTAA 1、名词解释 2、入网流程 二、ABP 三、两种入网方式的比较 一、OTAA 1、名词解释 &#xff08;1&#xff09;AppEUI&#xff1a;64位&#xff08;8字节&#xff09;的唯一标识符&#xff0c;用于标识特定的应用程序或组织&#xff08;如果用的是chirpstac…

Android BLE蓝牙广播发送数据

1. 调试BLE蓝牙广播数据 参考 android蓝牙BLE&#xff08;四&#xff09; —— 实战 android蓝牙BLE&#xff08;四&#xff09; —— 实战 - 简书 2. Android机可直接安装调试助手 BLE调试助手下载2024安卓手机版_手机app免费下载

【linux】在多核CPU下,好像看到不同进程在不同CPU调度

在2353这行打印的情况来看&#xff0c;操作系统好像给不同的进程分配不同的CPU&#xff0c;从上图来看&#xff0c;同一个进程好像基本使用的相同的CPU&#xff1a; 其实摸索syscall文件系统操作&#xff0c;本意是想找到内核文件系统中文件的创建&#xff0c;写入&#xff0c;…

Windosw下Visual Studio2022编译FFmpeg(支持x264、x265、fdk-acc)

FFmpeg 7.0 版本移除了 6.0 之前已弃用的 API&#xff0c;无法向下兼容。所以编译的版本选择FFmpeg 6.1.1。 一、安装Visual Studio2022 可参考另外一篇文章&#xff1a;Windows安装Visual Studio2022 QT5.15开发环境_qt5.15.2 vs2022-CSDN博客 二、安装MSYS2 下载地址&…

宝塔Docker部署Nuxt3 BBS项目

体验地址 BBS&#xff1a;http://bbs.sourcebyte.vip Nuxt3&#xff1a;https://nuxt.com.cn BBS项目介绍 BBS是开源字节最新研发的社区项目&#xff0c;包含产品中心&#xff0c;需求墙&#xff0c;工具&#xff0c;资讯4大板块。 1、产品中心&#xff1a;开源字节有众多…

Kafka知识总结(分区机制+压缩机制+拦截器+副本机制)

文章收录在网站&#xff1a;http://hardyfish.top/ 文章收录在网站&#xff1a;http://hardyfish.top/ 文章收录在网站&#xff1a;http://hardyfish.top/ 文章收录在网站&#xff1a;http://hardyfish.top/ 分区机制 分区策略 分区策略是决定生产者将消息发送到哪个分区的…

MySQL 存储

关系型数据库是基于关系模型的数据库&#xff0c; 而关系模型是通过二维表来保存的&#xff0c;所以关系型数据库中的数据的村方式就是行列组成的表&#xff0c;每一列代表一个字段&#xff0c;每一行代表一条记录。表可以看作某个实体的集合&#xff0c;实体之间存在的联系需要…

【区块链】如何发行自己的加密货币到以太坊测试网络,remixIDE发行自己的数字货币

如何发行自己的加密货币到以太坊测试网络 环境 reminx在线编辑器&#xff1a;https://remix.ethereum.org/安装有小狐狸钱包插件&#xff08;MetaMask&#xff09; 如何部署代币&#xff1f; 创建一个名字叫做HelloMyToken.sol的文件。编写好智能合约&#xff0c;这边我要发…

bug+测试用例

bug的概念&#xff1a; 1.当且仅当规格说明是存在的并且正确&#xff0c;程序与规格说明之间的不匹配才是错误。 2.当需求规格说明书没有提到的功能&#xff0c;判断标准以最终用户为准&#xff1b;当程序没有实现其最终用户合理预期的功能要求时&#xff0c;就是软件错误 bug…

大模型算法面试题(十三)

本系列收纳各种大模型面试题及答案。 1、领域模型词表扩增是不是有必要的? 领域模型词表扩增是否必要&#xff0c;取决于多个因素&#xff0c;主要包括以下几个方面&#xff1a; 领域复杂性&#xff1a;如果领域本身非常复杂&#xff0c;包含大量专业术语、缩写、行业特定表达…

mybatis插入mysql数据:中文乱码

1.问题描述 中文字段乱码&#xff0c;不能正常显示 2.解决方法 猜测是未指定编码造成的&#xff0c;在配置文件mybatis-config.xml添加配置。 <environment id"development"><transactionManager type"JDBC"/><dataSource type"POO…

golang设置远程调试

1. 目标机器构建安装dlv https://github.com/go-delve/delve go build之后将编译号的dlv命令路径添加到PATH里 2. 目标机器下载源代码并且运行dlv dlv debug --headless --listen:2345 --api-version2 --accept-multiclient 3.本机添加go remote 4. 设置断点即可

web前端开发一、VScode环境搭建

1、VScode安装live server插件&#xff0c;写完代码后&#xff0c;保存就会在浏览器自动更新&#xff0c;不需要再去浏览器点击刷新了 2、创建html文件 3、在文件中输入感叹号 &#xff01; 4、选择第一个&#xff0c;然后回车&#xff0c;就会自动输入html的标准程序 5、…

Python酷库之旅-第三方库Pandas(047)

目录 一、用法精讲 166、pandas.Series.max方法 166-1、语法 166-2、参数 166-3、功能 166-4、返回值 166-5、说明 166-6、用法 166-6-1、数据准备 166-6-2、代码示例 166-6-3、结果输出 167、pandas.Series.mean方法 167-1、语法 167-2、参数 167-3、功能 167…

Mysql中如何实现两列的值互换?给你提供些思路。

文章目录 Mysql中如何实现两列的值互换1、第一感觉此sql应该能处理问题了2、需要一个地方存要替换的值&#xff0c;不然两列搞不定。2.1 加第三列&#xff1f;&#xff08;能解决&#xff0c;但是看起来呆呆&#xff09;2.2 上临时表&#xff08;搞点弯路走走&#xff09; 示例…