爬虫逆向实战小记——解决captcha滑动验证码

news2025/4/22 8:54:05

注意!!!!某XX网站实例仅作为学习案例,禁止其他个人以及团体做谋利用途!!!

IGh0dHBzOi8vY2FwdGNoYS5ydWlqaWUuY29tLmNuLw==

第一步: 分析请求网址和响应内容

滑动验证码
(1)通过观察,滑块滑动到指定位置即认为验证成功
验证码请求网址
(2)验证码请求网址和参数。ts 是毫秒级时间戳,clientUid和captchaType固定
请求验证码响应内容
(3)请求验证码的响应内容,可以看到有2张图片编码形式的字段originalImageBase64jigsawImageBase64(一张原始图,一张滑块图), secretKeytoken
验证码check请求
(4)滑动滑块后无论是否成功,会存在一个check验证码 的网址和参数。可以看出pointJson 是加密的,token对应get验证码请求的响应内容(如果不太懂,自己请求一下即可明白)
check验证码请求响应内容
(5) check验证码响应内容如上图所示即为成功,否则均为失败

第二步:解决参数加密(逆向)

逆向解决pointJson_1
(1) 在XHR处添加 /captcha/check, 重新请求,可以看到会在 标蓝 处停住,通过堆栈查看,能够看到在end处,为pointJson的加密生成。
逆向解决pointJson_2
(2) 去掉XHR的勾选,在(1)中找到的end中,var r 打断点,重新请求。此处猜测r 为滑块的位移值(r 比真实位移值大需要将真实位置+一个数值区间, 可将浏览器请求的图片放在本地进行对比,在此不在赘述),同时pointJson 生成调用了a 并传入了转为JSON字符串的{x,y}坐标
逆向解决pointJson_3
(3)a 函数可以看出是AES加密ECB模式PKcs7。参数t 是 secretKey(这个可以再实战操作时验证)

第三步: 验证滑块是否成功

验证是否成功验证成功
浏览器上check 验证码响应成功展示

第四步: 部分代码展示

JS 加密部分

// 加密部分
CryptoJS = require('crypto-js')
function H(e, t) {
    var i = CryptoJS.enc.Utf8.parse(t)
      , n = CryptoJS.enc.Utf8.parse(e)
      , r = CryptoJS.AES.encrypt(n, i, {
        mode: CryptoJS.mode.ECB,
        padding: CryptoJS.pad.Pkcs7
    });
    return r.toString()
}

python 请求部分

# -*- coding:utf-8 -*-
# @Time : 2025/2/18 14:31
# @Author: 水兵没月
# @File : captcha_滑块验证码.py
# @Software: PyCharm
import base64
import random
import time

import execjs
import requests
from fake_useragent import UserAgent

from shuibingmeiyue import req_payload # 可以写成requests.post(url, body=json.dumps(data), headers=headers)

s = requests.Session()
headers = {
    "Accept": "application/json, text/plain, */*",
    "Accept-Encoding": "gzip, deflate, br, zstd",
    "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6",
    "Cache-Control": "no-cache",
    "Connection": "keep-alive",
    "Content-Length": "106",
    "Content-Type": "application/json; charset=UTF-8",
    "Host": "captcha.ruijie.com.cn",
    "Origin": "https://captcha.ruijie.com.cn",
    "Pragma": "no-cache",
    "Referer": "https://captcha.ruijie.com.cn/",
    "User-Agent": UserAgent().Chrome,
}
# 此处忽略一些非重点代码
# 此处忽略一些非重点代码
# 此处忽略一些非重点代码
def get_slide(target_bytes, background_bytes):
	'''获取滑块位移值'''
    import ddddocr
    # 关闭广告显示
    ocr = ddddocr.DdddOcr(show_ad=False, det=False, ocr=False, )
    res = ocr.slide_match(target_bytes, background_bytes, simple_target=True)
    print(res)
    target_json = float(res["target"][0] + float(
        '{}'.format(random.choice([15.5, 16.5]))))
    # target_json = res["target"][0]
    return target_json
def get_AES():
	'''获取AES的JS源码'''
    with open('./captche_AES.js', 'r', encoding="utf-8")as f:
        AES_source = f.read()
    f.close()
    return AES_source

def get_image_Base64(img_json):
	'''获取图片编码以及其他参数'''
    img_repData = img_json.get("repData")
    secretKey = img_repData.get("secretKey")
    originalImageBase64 = img_repData.get("originalImageBase64")
    jigsawImageBase64 = img_repData.get("jigsawImageBase64")
    token = img_repData.get("token")
	
	# origin_Base64和jigsaw_Base64 已被忽略。作用保存图片
    origin_Base64(originalImageBase64)
    jigsaw_Base64(jigsawImageBase64)

    # 读取滑块图片和背景图片的二进制数据
    # read_origin和read_jigsaw 已被忽略。 作用读取图片 
    target_bytes = read_origin()
    background_bytes = read_jigsaw()
    # 得到滑块位移
    target_json = get_slide(target_bytes, background_bytes)
    return secretKey, target_json, token

def get_pic():
	'''请求验证码网址'''
    url = "https://captcha.ruijie.com.cn/captcha/get"
    data = {"captchaType":"blockPuzzle","clientUid":"slider-9d5611b7-e5a0-40a2-a813-a18ecf0ccaf9","ts":int(time.time()*1000)}
    res = req_payload(s, url, headers, data)
    res_json = res.json()
    secretKey, target_json, token = get_image_Base64(res_json)
    return secretKey, target_json, token

def check_captcha(secretKey, target_json, token):
	'''检测验证码是否成功'''
    print(target_json)
    i = int(target_json)
    i = 310 * i / int(330)
    e = '{"x":' + str(i) + ',"y":5}'
    AES_source = get_AES()
    AES_ctx = execjs.compile(AES_source)
    get_AES = AES_ctx.call("H", e, secretKey)
    print('get_AES--', get_AES, len(get_AES))
    #
    url = "https://captcha.ruijie.com.cn/captcha/check"
    pointJson = get_AES
    data = {"captchaType":"blockPuzzle","pointJson":pointJson,"token":token}
    print(data)
    res = req_payload(s, url, headers, data)
    print(res.text)

secretKey, target_json, token = get_pic()
check_captcha(secretKey, target_json, token)

验证成功展示

仅作为笔记记录,如有问题请各位大佬来指导

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

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

相关文章

Spring Boot3+Vue3极速整合: 10分钟搭建DeepSeek AI对话系统(进阶)

Spring Boot3Vue3极速整合: 10分钟搭建DeepSeek AI对话系统(进阶) 前言 在上次实战指南《Spring Boot3Vue2极速整合: 10分钟搭建DeepSeek AI对话系统》引发读者热议后,我通过200真实用户反馈锁定了几个问题进行优化进阶处理: 每次对话都需重复上下文背…

Java 第十一章 GUI编程(2)

目录 GUI 事件处理 基本思路 添加事件监听器 对话框 实例 GUI 事件处理 对于采用了图形用户界面的程序来说,事件控制是非常重要的;到目前为止, 我们编写的图形用户界面程序都仅仅只是完成了界面,而没有任何实际的功能&…

anaconda 安装geemap配置详细教程

本章教程,主要介绍如何通过anaconda 安装ee 和geemap模块 一、示例代码 创建一个测试文件:geemapTets.ipynb # 导入 Google Earth Engine (GEE) 库,用于处理地理空间数据 import ee # 导入 geemap 库,用于可视化和交互式处理 GEE 数据 import geemap # 创建一个 geemap.M…

4G工业路由器在公交充电桩中的应用与优势

随着电动公交车的普及,公交充电桩的稳定运行和高效管理是交通营运部门最关心的问题。4G工业路由器凭借其卓越的数据采集和通讯能力,成为实现充电桩智能化管理的关键。 公交充电桩运维管理需求概述: 1.实时性:实时监控充电状态、剩…

【设计模式】单例模式|饿汉模式|懒汉模式|指令重排序

目录 1.什么是单例模式? 2.如何保证单例? 3.两种写法 (1)饿汉模式(早创建) (2)懒汉模式(缓执行,可能不执行) 4.应用场景 🔥5.多…

01. HarmonyOS应用开发实践与技术解析

文章目录 前言项目概述HarmonyOS应用架构项目结构Ability生命周期 ArkTS语言特性装饰器状态管理 UI组件与布局基础组件响应式布局样式与主题 页面路由与参数传递页面跳转参数接收 数据绑定与循环渲染数据接口定义循环渲染 条件渲染组件生命周期最佳实践与性能优化组件复用响应式…

【NLP 30、文本匹配任务 —— 传统机器学习算法】

目录 一、文本匹配任务的定义 1.狭义解释 2.广义解释 二、文本匹配的应用 1.问答对话 2.信息检索 3.文本匹配任务应用 三、智能问答 1.智能问答的基本思路 依照基础资源划分: 依照答案产出方式划分 依照NLP相关技术划分 四、智能问答的价值 1.智能客服 2.Faq知识库问…

爬虫Incapsula reese84加密案例:Etihad航空

声明: 该文章为学习使用,严禁用于商业用途和非法用途,违者后果自负,由此产生的一切后果均与作者无关 一、找出需要加密的参数 1.js运行 atob(‘aHR0cHM6Ly93d3cuZXRpaGFkLmNvbS96aC1jbi8=’) 拿到网址,F12打开调试工具,随便搜索航班,切换到network搜索一个时间点可以找…

【Vue教程】使用Vite快速搭建前端工程化项目 Vue3 Vite Node.js

??大家好!我是毛毛张! ??个人首页: ??今天毛毛张分享的是关于如何快速??♂搭建一个前端工程化的项目的环境搭建以及流程?? 文章目录 1.前端工程化环境搭建?? 1.1 什么是前端工程化1.2 nodejs的简介和安装 1.2.1 什么是Nodejs1.2.2 如何安装…

如何将飞书多维表格与DeepSeek R1结合使用:效率提升的完美搭档

将飞书的多维表格与DeepSeek R1结合使用,就像为你的数据管理和分析之旅装上一台涡轮增压器。两者的合作,不仅仅在速度上让人耳目一新,更是将智能化分析带入了日常的工作场景。以下是它们如何相辅相成并改变我们工作方式的一些分享。 --- 在…

算数操作符、赋值操作符、单目操作符、强制类型转换

一、算术操作符(、 -、 *、 /、 %) • - * / %操作符都是双⽬操作符,有**两个操作数**的符号就叫做双目操作符 10 4| || | 操作数1 操作数2// - % / * 以此类推•操作符也被叫做:运算符 1. 符号、符号 - 和 符号* •…

为AI聊天工具添加一个知识系统 之133 详细设计之74通用编程语言 之4 架构及其核心

本篇继续讨论 通用编程语言。 说明:本阶段的所有讨论都是围绕这一主题展开的,但前面的讨论分成了三个大部分(后面列出了这一段的讨论题目的归属关系)-区别distinguish(各别): 文化和习俗。知识…

RNN实现精神分裂症患者诊断(pytorch)

RNN理论知识 RNN(Recurrent Neural Network,循环神经网络) 是一种 专门用于处理序列数据(如时间序列、文本、语音、视频等)的神经网络。与普通的前馈神经网络(如 MLP、CNN)不同,RNN…

私有云基础架构

基础配置 使用 VMWare Workstation 创建三台 2 CPU、8G内存、100 GB硬盘 的虚拟机 主机 IP 安装服务 web01 192.168.184.110 Apache、PHP database 192.168.184.111 MariaDB web02 192.168.184.112 Apache、PHP 由于 openEuler 22.09 系统已经停止维护了&#xff…

rust学习笔记11-集合349. 两个数组的交集

rust除了结构体,还有集合类型,同样也很重要,常见的有数组(Array)、向量(Vector)、哈希表(HashMap) 和 集合(HashSet)字符串等,好意外呀…

超详细:数据库的基本架构

MySQL基础架构 下面这个图是我给出的一个MySQL基础架构图,可以清楚的了解到SQL语句在MySQL的各个模块进行执行过程。 然后MySQL可以分为两个部分,一个是server层,另一个是存储引擎。 server层 Server层涵盖了MySQL的大多数核心服务功能&am…

AI催化新一轮创业潮与创富潮:深圳在抢跑

作者:尺度商业大掌柜黄利明 2025年春节伊始至今,从DeepSeek R1开源模型持续引发全球围观,到腾讯混元Turbo S模型发布秀出了"秒回"绝活,再到国务院发布《新一代人工智能发展规划(2025-2030)》重磅…

Python:类型转换和深浅拷贝,可变与不可变对象

int():转换为一个整数,只能转换由纯数字组成的字符串 浮点型强转整型会去掉小数点及后面的数,只保留整数部分 #如果字符串中有数字和正负号以外的字符就会报错 float():整形转换为浮点型会自动添加一位小数 .0 如果字符串中有…

NAT 代理服务 内网穿透

🌈 个人主页:Zfox_ 🔥 系列专栏:Linux 目录 一:🔥 NAT 技术背景二:🔥 NAT IP 转换过程三:🔥 NAPT四:🔥 代理服务器🦋 正向…

高级课第五次作业

首先配置交换机,路由器 LSW1配置 [SW1]vlan batch 10 20 30 40 [SW1]int g0/0/2 [SW1-GigabitEthernet0/0/2]port link-type access [SW1-GigabitEthernet0/0/2]port default vlan 10 [SW1]int g0/0/3 [SW1-GigabitEthernet0/0/3]port link-type access […