【验证码逆向专栏】房某下登录滑块逆向分析

声明
本文章中所有内容仅供学习交流使用,不用于其他任何目的,不提供完整代码,抓包内容、敏感网址、数据接口等均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关!
本文章未经许可禁止转载,禁止任何修改后二次传播,擅自使用本文讲解的技术而导致的任何意外,作者均不负责,若有侵权,请在公众号【K哥爬虫】联系作者立即删除!
前言
K 哥之前在【JS 逆向百例】专栏中写过一篇文章:【JS 逆向百例】房某下登录接口参数逆向,该站如果通过输入账号和密码的方式进行登录,POST 请求参数中,密码 pwd 被加密处理了,对其进行了逆向分析。最近在某博客平台上,有粉丝在该篇文章的评论区询问能不能出一期该站的滑块逆向文章,经过研究发现通过手机动态码的方式登录,点击获取短信验证码时,会弹出滑块验证,本文将对另一种登录方式的反爬策略进行研究分析,既是满足粉丝需求,也是对该站登录逆向的补充完善。

逆向目标
- 目标:房某下手机动态码登录,滑块验证码逆向分析
- 网站:aHR0cHM6Ly9wYXNzcG9ydC5mYW5nLmNvbS8=

抓包分析
随便输入一串手机号码,点击获取短信验证码,即会弹出滑块验证,getslidecodeinit.api 接口响应返回 challenge 和 gt 参数的值,这两个参数在后面校验滑块验证和获取短信验证码的时候会用到:

c=index&a=jigsaw 接口响应返回的参数中,surl 为滑块验证码的背景图片,url 为滑块图片,完整的下载地址需要在前面加上 https://static.soufunimg.com/common_m/m_recaptcha/jigsawimg/:

需要注意的是,下载下来的背景图片(320x160)以及滑块图片(60x158)的长宽与网页上渲染出来的是不一致的:

渲染出来的背景图片为 300x150,滑块为 57x150,需要先对获取到的图片进行缩放处理后,再识别缺口距离:

拖动滑块进行验证,c=index&a=codeDrag 接口响应返回校验的结果,请求参数中 i 和 t 经过了加密处理,需要逆向还原出加密算法,后文会进行研究分析,callback 生成方式如下:
"fangcheck_" + (parseInt(1e4 * Math.random()) + (new Date).valueOf())
- 1e4 * Math.random():生成一个介于 0 到 10000 之间的随机数;
- (new Date).valueOf():获取当前的时间戳(以毫秒为单位)。
challenge 和 gt 参数是前面所说的 getslidecodeinit.api 接口响应返回,start 和 end 为滑动轨迹开始及结束的时间戳:

滑块验证失败,code 有两种状态码:
101 —> 参数校验失败

102 —> 缺口识别错误

滑块验证成功,code 为 100:

验证成功之后,会响应返回 validate 参数,携带该参数请求 loginsendmsm.api 接口,即可成功发送短信验证码:

发送成功,响应返回的 message 为 Success,失败则为 Error:

逆向分析
i 参数
先来分析下 i 参数是如何加密生成的,从验证接口跟栈到 jigsawpc.1.0.1.js 文件中:

ctrl + f 搜索 i:,只有一个结果:

在第 204 行打下断点,滑动滑块即会断住,可以看到,l 即滑动轨迹,由 x 轴、y 轴距离以及时间戳组成,后面再对轨迹进行分析,前文所讲到的 start、end 在此验证了,为滑动的开始及结束时间:

从第 203 行,跟进到 x.compress 方法中去:

可以看到,i 参数的值就是由 x.baseCompress 方法生成的,传入的 e 参数很像是由一些值拼接而成的:

回到第 203 行,e 参数是由 function(e) {...} 方法生成的,点击前大括号,找到该函数结束的位置,在第 301 行打下断点,断住后会发现,e 参数的值是先通过 join( ) 方法将 r 数组的所有元素用 !! 符分隔后连接成一个字符串,再使用 encodeURIComponent( ) 方法进行编码后得到的:

那 r 数组是由哪些元素组成的呢?往上跟到第 296 行就会发现,r 数组中的元素如下,包括一些浏览器环境,最后确实校验了,但不多:
["textLength", "HTMLLength", "documentMode", "screenLeft", "screenTop", "screenAvailLeft", "screenAvailTop", "innerWidth", "innerHeight", "outerWidth", "outerHeight", "browserLanguage", "browserLanguages", "systemLanguage", "devicePixelRatio", "colorDepth", "userAgent", "cookieEnabled", "netEnabled", "screenWidth", "screenHeight", "screenAvailWidth", "screenAvailHeight", "localStorageEnabled", "sessionStorageEnabled", "indexedDBEnabled", "CPUClass", "platform", "doNotTrack", "timezone", "canvas2DFP", "canvas3DFP", "plugins", "maxTouchPoints", "flashEnabled", "javaEnabled", "hardwareConcurrency", "jsFonts", "timestamp", "performanceTiming", "cwidth"]
下面是对数组中各环境属性的简单描述,可供参考:
- textLength:用于测量 HTML 元素文本内容的长度;
- HTMLLength:获取当前文档中 HTML 根元素的内部 HTML 内容的长度;
- documentMode:用于在 Internet Explorer 浏览器中确定文档的呈现模式;
- screenLeft,screenTop:窗口左上角相对于屏幕左上角的坐标;
- screenAvailLeft,screenAvailTop:可用屏幕空间左上角相对于屏幕左上角的坐标;
- innerWidth,innerHeight:浏览器窗口的内部宽度和高度,不包括浏览器工具栏和滚动条;
- outerWidth,outerHeight:浏览器窗口的外部宽度和高度,包括浏览器边框和工具栏;
- browserLanguage,browserLanguages:浏览器当前使用的语言或语言列表;
- systemLanguage:操作系统的默认语言;
- devicePixelRatio:设备像素比,用于在不同分辨率屏幕上进行适配;
- colorDepth:屏幕颜色深度;
- userAgent:浏览器的用户代理字符串,通常包含浏览器和操作系统信息;
- cookieEnabled:表示浏览器是否启用了 Cookie;
- screenWidth,screenHeight:屏幕的宽度和高度;
- screenAvailWidth,screenAvailHeight:可用屏幕的宽度和高度;
- localStorageEnabled,sessionStorageEnabled:表示浏览器是否启用了本地存储和会话存储;
- indexedDBEnabled:表示浏览器是否启用了 IndexedDB;
- CPUClass:表示 CPU 的等级或类别;
- platform:操作系统平台信息;
- doNotTrack:表示用户是否启用了 “不跟踪” 功能;
- timezone:用户所在时区;
- canvas2DFP,canvas3DFP:Canvas 防指纹技术,用于保护用户隐私;
- plugins:浏览器安装的插件列表;
- maxTouchPoints:设备支持的最大触摸点数;
- flashEnabled:表示浏览器中是否启用了 Flash;
- javaEnabled:表示浏览器中是否启用了 Java 插件;
- hardwareConcurrency:表示设备的逻辑处理器核心数;
- jsFonts:浏览器已安装的字体列表;
- timestamp:时间戳,通常用于测量性能和时间间隔;
- performanceTiming:访问有关页面加载和性能计时的信息。
至此 e 参数的构成方法分析完了,再回到 x.compress 方法中,也就是第 505 行,前文分析了,i 参数由 x.baseCompress 方法生成,该方法传入了三个参数,前两个已经分析完了,来看看第三个函数部分:
function(e) {return x.toChart16(t(e))
}
t 方法定义在第 502 行,就是 String.fromCharCode( ),它用于将一组 Unicode 值(UTF-16 编码)转换成对应的字符串,每个参数都是一个表示 Unicode 值的整数。再跟进到 x.toChart16 方法中去,定义在第 628 行,直接扣下来就行了:

最后直接将 baseCompress 方法扣下来即可,i 参数就分析完了:

t 参数
生成 t 参数的方法定义在第 302 行,同样搜 t: 就可以找到,和 i 一样,也是几个自执行函数,直接跟到第 392 行,打下断点,断住后验证了,t 参数就是在这里生成的:

t 参数是于一长串二进制字符串 e 中从前往后依次截取六位字符,再通过 parseInt 方法将截取到的二进制字符串转换为整数,即索引,最后使用 charAt 方法根据索引从固定字符串 E 中取值,循环 e.length / 6 次后拼接而成的:

那一长串二进制字符串怎么来的呢?生成 t 参数的函数是个自执行函数,传入的参数是 l,l 定义在第 368 行,生成方法逐个跟,扣下来即可:

接着往上跟到 return 处,即第 360 行,此时传入的 e 为鼠标轨迹,很明显,这里对轨迹做了处理,不再是前文所讲的 x、y、t 形式,被转换成了一个大数组:

相关转换算法在第 180 行,即 e 参数,轨迹校验的不是很严格,模拟构造即可:

结果验证

相关文章:
【验证码逆向专栏】房某下登录滑块逆向分析
声明 本文章中所有内容仅供学习交流使用,不用于其他任何目的,不提供完整代码,抓包内容、敏感网址、数据接口等均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关! 本文章未…...
Python 3.11 版本是对线程安全做了什么更改吗
问题:这份代码在 3.11.3 中它居然输出 0 ,一度以为自己写错了,抱着不信邪的态度,又搞了个 Python 3.9.7 的环境试了下,果然还是符合自己预期,输出不为 0,想问下 3.11 版本中是做了什么修改吗&am…...
【Docker】镜像的创建、管理与发布
镜像的获取 镜像可以从以下方式获得: 从远程镜像仓库拉取,可以是公有仓库,也可以是私有仓库从Dockerfile构建从文件导入(离线)从容器提交 镜像的基本操作 跟镜像相关的命令如下: $ docker image --help…...
移动硬盘或U盘无法弹出的解决方法
以下内容源于网络资源的学习与整理,如有侵权请告知删除。 最近在红米本win11中总遇到“该设备正在使用中”而无法弹出硬盘的问题。 解法该问题的思路:先定位占用该设备的进程,然后结束该进程。 定位进程 既然设备被占用,那肯定…...
(leetcode1761一个图中连通三元组的最小度数,暴力+剪枝)-------------------Java实现
(leetcode1761一个图中连通三元组的最小度数,暴力剪枝)-------------------Java实现 题目表述 给你一个无向图,整数 n 表示图中节点的数目,edges 数组表示图中的边,其中 edges[i] [ui, vi] ,…...
【漏洞复现】金和OA C6任意文件读取漏洞
漏洞描述 金和OA协同办公管理系统C6软件共有20多个应用模块,160多个应用子模块,涉及的企业管理业务包括协同办公管理、人力资源管理、项目管理、客户关系管理、企业目标管理、费用管理等多个业务范围,从功能型的协同办公平台上升到管理型协同…...
2023年全国大学生数学建模B题
多波束测线问题 1.问题提出 单波束测深是利用声波在水中的传播特性来测量水体深度的技术。声波在均匀介质中作匀 速直线传播,在不同界面上产生反射,利用这一原理,从测量船换能器垂直向海底发射声波信号,并记录从声波发射到信号接…...
【LeetCode】2651.计算列车到站时间
题目 给你一个正整数 arrivalTime 表示列车正点到站的时间(单位:小时),另给你一个正整数 delayedTime 表示列车延误的小时数。 返回列车实际到站的时间。 注意,该问题中的时间采用 24 小时制。 示例 1:…...
Redis——认识Redis
简单介绍 Redis诞生于2009年,全称是Remote Dictionary Server,远程词典服务器,是一个基于内存的键值型NoSQL数据库。 特征 键值(Key-value)型,value支持多种不同数据结构,功能丰富单线程&…...
通讯录怎么导入新手机?3个推荐小妙招
最近刚换了新手机,旧手机里的联系人太多了,不想在新手机上一个个重新添加。有没有什么快速简单的方法能够将通讯录导入新手机? 大家在更换新手机之后都是怎么导入通讯录的呢?换手机最重要的就是把数据进行完整转移,那么…...
Geoserver发布shp、tiff、瓦片等格式的GIS数据
这里写目录标题 1 发布shp矢量数据1.1 添加shp作为数据源1.2 发布shp图层1.3 预览服务1.4 配置样式 2 发布Postgres数据库2.2 发布数据 3 发布 tif 栅格数据3.1 添加 tif 数据源3.2 发布tif数据3.3 预览服务3.4 配置地图样式 关于中文标注乱码的问题 1 发布shp矢量数据 发布sh…...
读书笔记-《ON JAVA 中文版》-摘要24[第二十一章 数组]
文章目录 第二十一章 数组1. 数组特性2. 一等对象3. 返回数组4. 多维数组5. 泛型数组6. Arrays的fill方法7. Arrays的setAll方法8. 数组并行9. Arrays工具类10. 数组拷贝11. 数组比较12. 流和数组13. 数组排序14. binarySearch二分查找15. 本章小结 第二十一章 数组 1. 数组特…...
go语言基本操作---五
error接口的使用 Go语言引入了一个关于错误处理的标准模式,即error接口,它是Go语言内建的接口类型 type error interface {Error() string }package mainimport ("errors""fmt" )type Student struct {name stringid int }func …...
【sgLazyTree】自定义组件:动态懒加载el-tree树节点数据,实现增删改、懒加载及局部数据刷新。
特性 可以自定义主键、配置选项支持预定义节点图标:folder文件夹|normal普通样式多个提示文本可以自定义支持动态接口增删改节点可以自定义根节点Id可以设置最多允许添加的层级深度 sgLazyTree源码 <template><div :class"$options.name" v-lo…...
Rust个人学习笔记
感悟:感觉rust好像缝合怪,既有python的影子,又有java和cpp的影子,可能这就是新型编程语言趋势吧。而且他的各种规范很严格很规范,比java还更工程,各种规范不对都有warning。 命名规范:蛇形命名…...
Java根据身份证号码提取出省市区,JSON数据格式
package com.rdes.talents.utils;import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern;/*** Author: 更多实用源码 www.cx1314.cn* Date: 2023/9/7 …...
MySQL知识笔记——初级基础(实施工程师和DBA工作笔记)
老生长谈,MySQL具有开源、支持多语言、性能好、安全性高的特点,广受业界欢迎。 在数据爆炸式增长的年代,掌握一种数据库能够更好的提升自己的业务能力(实施工程师)。 此系列将会记录我学习和进阶SQL路上的知识…...
javaee 事务的传播行为
事务的传播行为 事务的第一个方面是传播行为(propagation behavior)。当事务方法被另一个事务方法调用时,必须指定事务应该如何传播。例如:方法可能继续在现有事务中运行,也可能开启一个新事务,并在自己的…...
C#-SQLite-使用教程笔记
微软官网资料链接(可下载文档) 教程参考链接:SQLite 教程 - SQLite中文手册 项目中对应的system.dat文件可以用SQLiteStudio打开查看 参考文档:https://d7ehk.jb51.net/202008/books/SQLite_jb51.rar 总结介绍 1、下载SQLiteS…...
Tomcat详解 一:tomcat的部署
文章目录 1. Tomcat的基本介绍1.1 Tomcat是什么1.2 Tomcat的构成组件1.2.1 Web容器1.2.2 Servlet容器1.2.3 JSP容器(JAVA Scripts page) 1.3 核心功能1.3.1 Container 结构分析 1.4 配置文件1.5 Tomcat常用端口号1.6 启动和关闭Tomcat 2. 部署Tomcat服务…...
HTML 语义化
目录 HTML 语义化HTML5 新特性HTML 语义化的好处语义化标签的使用场景最佳实践 HTML 语义化 HTML5 新特性 标准答案: 语义化标签: <header>:页头<nav>:导航<main>:主要内容<article>&#x…...
UE5 学习系列(三)创建和移动物体
这篇博客是该系列的第三篇,是在之前两篇博客的基础上展开,主要介绍如何在操作界面中创建和拖动物体,这篇博客跟随的视频链接如下: B 站视频:s03-创建和移动物体 如果你不打算开之前的博客并且对UE5 比较熟的话按照以…...
聊聊 Pulsar:Producer 源码解析
一、前言 Apache Pulsar 是一个企业级的开源分布式消息传递平台,以其高性能、可扩展性和存储计算分离架构在消息队列和流处理领域独树一帜。在 Pulsar 的核心架构中,Producer(生产者) 是连接客户端应用与消息队列的第一步。生产者…...
unix/linux,sudo,其发展历程详细时间线、由来、历史背景
sudo 的诞生和演化,本身就是一部 Unix/Linux 系统管理哲学变迁的微缩史。来,让我们拨开时间的迷雾,一同探寻 sudo 那波澜壮阔(也颇为实用主义)的发展历程。 历史背景:su的时代与困境 ( 20 世纪 70 年代 - 80 年代初) 在 sudo 出现之前,Unix 系统管理员和需要特权操作的…...
(转)什么是DockerCompose?它有什么作用?
一、什么是DockerCompose? DockerCompose可以基于Compose文件帮我们快速的部署分布式应用,而无需手动一个个创建和运行容器。 Compose文件是一个文本文件,通过指令定义集群中的每个容器如何运行。 DockerCompose就是把DockerFile转换成指令去运行。 …...
网络编程(UDP编程)
思维导图 UDP基础编程(单播) 1.流程图 服务器:短信的接收方 创建套接字 (socket)-----------------------------------------》有手机指定网络信息-----------------------------------------------》有号码绑定套接字 (bind)--------------…...
3-11单元格区域边界定位(End属性)学习笔记
返回一个Range 对象,只读。该对象代表包含源区域的区域上端下端左端右端的最后一个单元格。等同于按键 End 向上键(End(xlUp))、End向下键(End(xlDown))、End向左键(End(xlToLeft)End向右键(End(xlToRight)) 注意:它移动的位置必须是相连的有内容的单元格…...
基于matlab策略迭代和值迭代法的动态规划
经典的基于策略迭代和值迭代法的动态规划matlab代码,实现机器人的最优运输 Dynamic-Programming-master/Environment.pdf , 104724 Dynamic-Programming-master/README.md , 506 Dynamic-Programming-master/generalizedPolicyIteration.m , 1970 Dynamic-Programm…...
AGain DB和倍数增益的关系
我在设置一款索尼CMOS芯片时,Again增益0db变化为6DB,画面的变化只有2倍DN的增益,比如10变为20。 这与dB和线性增益的关系以及传感器处理流程有关。以下是具体原因分析: 1. dB与线性增益的换算关系 6dB对应的理论线性增益应为&…...
android RelativeLayout布局
<?xml version"1.0" encoding"utf-8"?> <RelativeLayout xmlns:android"http://schemas.android.com/apk/res/android"android:layout_width"match_parent"android:layout_height"match_parent"android:gravity&…...
