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://www.mzph.cn/bicheng/50736.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

大模型技术:发展历程、经典模型、微调与应用[更新中...]

文章目录 一、预训练语言模型发展历程二、经典的Pre-trained任务2.1 Masked Language Modeling2.2 Next Sentence Prediction 三、Task-specific Fine-tuning 任务3.1 Single-text Classification (单句分类)3.2 Sentence-pair Classification (句子匹配/成对分类)3.3 Span Tex…

谷粒商城实战笔记-71-商品服务-API-属性分组-前端组件抽取父子组件交互

文章目录 一,一次性创建所有的菜单二,开发属性分组界面1,左侧三级分类树形组件2,右侧分组列表3,左右两部分通信3.1 子组件发送数据3.2,父组件接收数据 Vue的父子组件通信父组件向子组件传递数据子组件向父组…

vector的相关内容介绍及模拟实现

一.内容介绍 1.vector是一个模板,不支持流插入和流提取,因为它支持多种方式的输出,不需要局限于流提取的方式 2.关于vector所涉及的函数接口与string类的用法类似,有兴趣可参考小编的另一篇博客 3.vector的迭代器失效问题 1&g…

后端面试题日常练-day08 【Java基础】

题目 希望这些选择题能够帮助您进行后端面试的准备,答案在文末 Java中的静态变量和实例变量有何区别? a) 静态变量属于类,实例变量属于对象 b) 静态变量只能在静态方法中访问,实例变量只能在实例方法中访问 c) 静态变量在类加载时…

【BUG】已解决:The above exception was the direct cause of the following exception:

The above exception was the direct cause of the following exception: 目录 The above exception was the direct cause of the following exception: 【常见模块错误】 【解决方案】 欢迎来到英杰社区https://bbs.csdn.net/topics/617804998 欢迎来到我的主页&#xff0c…

【杰理蓝牙开发】AC695x 音频部分

本文主要记录 杰理蓝牙audio接口的使用,包括ADC和DAC原理的介绍和API接口的使用。 【杰理蓝牙开发】AC695x 音频部分 0. 个人简介 && 授权须知1. ADC【音频数据采集】硬件部分1.1 单片机引脚1.2 硬件电路设计1.3 MIC 输入通路解释 2. 【DAC】音频信号编解码…

JVM 高级面试题及答案整理,最新面试题

JVM中的垃圾收集器有哪些,它们的工作原理是什么? JVM中的垃圾收集器主要包括以下几种: 1、 Serial收集器:它是一个单线程收集器,工作时会暂停所有其他工作线程("Stop-The-World"),它的优点是简单高效(与其他收集器的单线程比),适用于单核处理器的环境。 2…

stm32F1xx外设GPIO的用法总结

目录 前言一、概念二、主要文件三、库函数和寄存器四、几个数据结构五、使用方式 前言 本文笔记总结stm32F1xx的GPIO的寄存器说明和标准库中的函数说明、用法,使用案例; 一、概念 GPIO为通用输入输出端口的简称,作为主控芯片的一个外设在芯片中是一个…

Super 4PCS配准算法

Nicolas Mellado,CNRS(Centre national de la recherche scientifique,法国国家科学研究中心)的研究员,在IRIT(Institut de Recherche en Informatique de Toulouse,图卢兹计算机科学研究所&…

SAPUI5基础知识20 - 对话框和碎片(Dialogs and Fragments)

1. 背景 在 SAPUI5 中,Fragments 是一种轻量级的 UI 组件,类似于视图(Views),但它们没有自己的控制器(Controller)。Fragments 通常用于定义可以在多个视图中重用的 UI 片段,从而提…

linux系统安装pytorch_中文地址命名实体识别案例

命名实体有关文章参考这篇文章 中文地址命名实体识别训练和预测 win10系统安装cuda环境参考这篇文章 搭建Pytorch的GPU环境超详细 1、下载python https://www.python.org/downloads/release/python-368/ 2、下载python包 https://pypi.org/search/?q=transformers 1、搜…

如何录制电脑内部声音?全方位介绍电脑录音软件:8款在线录音!(2024重新整理)

如何录制电脑内部声音?不管是娱乐圈还是现实生活,【录音】这个功能的重要性不言而喻。而电脑录音已在影视配音、音视频剪辑、会议记录、在线教育等多个领域发光发热! 本文将为您推荐8款电脑录音软件,并详细介绍电脑录音的多种方式…

Git 从入门到精通:全面掌握版本控制(IntelliJ IDEA 中 Git 的使用指南)

引言 Git 是目前世界上最流行的版本控制系统,由 Linux 内核的创始人 Linus Torvalds 开发。它不仅拥有强大的分支管理功能,还具备了优秀的合并能力。本文将从 Git 的基本概念开始,逐步深入到 Git 的使用和一些高级技巧。 Git 简介 Git 是一…

Python番外篇:变量是盒子还是标签

引言 前面通过几十篇文章,大概把Python的一些比较实用的基础做了一些介绍,学会这些,基本能应付日常的小的需求开发了,写一些小工具,提高工作的处理效率。 接下来,准备开始进入一个新的篇章,也…

del 语句

使用 del 语句可以删除任何对象,包括字典对象。删除之后,之前的引用将失效,尝试使用该对象会导致 NameError 错误。因此,删除字典对象的命令是 del myDict。 元组 (Tuple) 元组是不可变的,因此你不能修改元组的内容&a…

C#如何引用dll动态链接库文件的注释

1、dll动态库文件项目生成属性中要勾选“XML文档文件” 注意:XML文件的名字切勿修改。 2、添加引用时XML文件要与DLL文件在同一个目录下。 3、如果要是添加引用的时候XML不在相同目录下,之后又将XML文件复制到相同的目录下,需要删除引用&am…

MySQL之索引优化

1、在进行查询时,索引列不能是表达式的一部分,也不能是函数的参数,否则无法使用索引 例如下面的查询不能使用 actor_id 列的索引: #这是错误的 SELECT actor_id FROM sakila.actor WHERE actor_id 1 5; 优化方式:…

微信小程序安装vant组件库和使用

第一步打开终端输入 npm install vant/weapp --save 第二步 npm cache clean --force 第三步 npm i vant/weapp -S --production 第四步在app.json中的usingComponents输入 "van-button": "vant/weapp/button/index" 第五步直接在页面使用 <v…

SSM(Spring + Spring MVC + MyBatis)框架面试三道题

以下是三道关于SSM&#xff08;Spring Spring MVC MyBatis&#xff09;框架的面试题&#xff0c;由简单到困难进行排列&#xff1a; 1. 简答题&#xff1a;请简述Spring框架的核心特性。 答案&#xff1a; Spring框架的核心特性主要包括以下几个方面&#xff1a; 控制反转…

当设计模式牵手LLM

模版方法模式 何为模版设计模式 想象一下 如果我们要泡一杯茶 我们要循序渐进地 煮水温杯注水浸茶茶水入杯加点配料 如此&#xff0c;泡茶的工序就完成了&#xff0c;那么模板方法模式&#xff0c;相信各位也有了一定的概念&#xff1a;定义了一个算法的骨架&#xff0c;而…