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

声明
本文章中所有内容仅供学习交流使用,不用于其他任何目的,不提供完整代码,抓包内容、敏感网址、数据接口等均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关!
本文章未经许可禁止转载,禁止任何修改后二次传播,擅自使用本文讲解的技术而导致的任何意外,作者均不负责,若有侵权,请在公众号【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服务…...
Chapter03-Authentication vulnerabilities
文章目录 1. 身份验证简介1.1 What is authentication1.2 difference between authentication and authorization1.3 身份验证机制失效的原因1.4 身份验证机制失效的影响 2. 基于登录功能的漏洞2.1 密码爆破2.2 用户名枚举2.3 有缺陷的暴力破解防护2.3.1 如果用户登录尝试失败次…...
日语AI面试高效通关秘籍:专业解读与青柚面试智能助攻
在如今就业市场竞争日益激烈的背景下,越来越多的求职者将目光投向了日本及中日双语岗位。但是,一场日语面试往往让许多人感到步履维艰。你是否也曾因为面试官抛出的“刁钻问题”而心生畏惧?面对生疏的日语交流环境,即便提前恶补了…...
Lombok 的 @Data 注解失效,未生成 getter/setter 方法引发的HTTP 406 错误
HTTP 状态码 406 (Not Acceptable) 和 500 (Internal Server Error) 是两类完全不同的错误,它们的含义、原因和解决方法都有显著区别。以下是详细对比: 1. HTTP 406 (Not Acceptable) 含义: 客户端请求的内容类型与服务器支持的内容类型不匹…...
MongoDB学习和应用(高效的非关系型数据库)
一丶 MongoDB简介 对于社交类软件的功能,我们需要对它的功能特点进行分析: 数据量会随着用户数增大而增大读多写少价值较低非好友看不到其动态信息地理位置的查询… 针对以上特点进行分析各大存储工具: mysql:关系型数据库&am…...
云启出海,智联未来|阿里云网络「企业出海」系列客户沙龙上海站圆满落地
借阿里云中企出海大会的东风,以**「云启出海,智联未来|打造安全可靠的出海云网络引擎」为主题的阿里云企业出海客户沙龙云网络&安全专场于5.28日下午在上海顺利举办,现场吸引了来自携程、小红书、米哈游、哔哩哔哩、波克城市、…...
可靠性+灵活性:电力载波技术在楼宇自控中的核心价值
可靠性灵活性:电力载波技术在楼宇自控中的核心价值 在智能楼宇的自动化控制中,电力载波技术(PLC)凭借其独特的优势,正成为构建高效、稳定、灵活系统的核心解决方案。它利用现有电力线路传输数据,无需额外布…...
1.3 VSCode安装与环境配置
进入网址Visual Studio Code - Code Editing. Redefined下载.deb文件,然后打开终端,进入下载文件夹,键入命令 sudo dpkg -i code_1.100.3-1748872405_amd64.deb 在终端键入命令code即启动vscode 需要安装插件列表 1.Chinese简化 2.ros …...
学习STC51单片机31(芯片为STC89C52RCRC)OLED显示屏1
每日一言 生活的美好,总是藏在那些你咬牙坚持的日子里。 硬件:OLED 以后要用到OLED的时候找到这个文件 OLED的设备地址 SSD1306"SSD" 是品牌缩写,"1306" 是产品编号。 驱动 OLED 屏幕的 IIC 总线数据传输格式 示意图 …...
unix/linux,sudo,其发展历程详细时间线、由来、历史背景
sudo 的诞生和演化,本身就是一部 Unix/Linux 系统管理哲学变迁的微缩史。来,让我们拨开时间的迷雾,一同探寻 sudo 那波澜壮阔(也颇为实用主义)的发展历程。 历史背景:su的时代与困境 ( 20 世纪 70 年代 - 80 年代初) 在 sudo 出现之前,Unix 系统管理员和需要特权操作的…...
Java线上CPU飙高问题排查全指南
一、引言 在Java应用的线上运行环境中,CPU飙高是一个常见且棘手的性能问题。当系统出现CPU飙高时,通常会导致应用响应缓慢,甚至服务不可用,严重影响用户体验和业务运行。因此,掌握一套科学有效的CPU飙高问题排查方法&…...
