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

打印 上一主题 下一主题

主题 928|帖子 928|积分 2784

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

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


(1)通过观察,滑块滑动到指定位置即认为验证乐成

(2)验证码请求网址和参数。ts 是毫秒级时间戳,clientUid和captchaType固定

(3)请求验证码的响应内容,可以看到有2张图片编码形式的字段originalImageBase64和jigsawImageBase64(一张原始图,一张滑块图), secretKey和token

(4)滑动滑块后无论是否乐成,会存在一个check验证码 的网址和参数。可以看出pointJson 是加密的,token对应get验证码请求的响应内容(假如不太懂,自己请求一下即可明白)

(5) check验证码响应内容如上图所示即为乐成,否则均为失败
第二步:解决参数加密(逆向)


(1) 在XHR处添加 /captcha/check, 重新请求,可以看到会在 标蓝 处愣住,通过堆栈检察,能够看到在end处,为pointJson的加密生成。

(2) 去掉XHR的勾选,在(1)中找到的end中,var r 打断点,重新请求。此处猜测r 为滑块的位移值(r 比真实位移值大需要将真实位置+一个数值区间, 可将浏览器请求的图片放在本地进行对比,在此不在赘述),同时pointJson 生成调用了a 并传入了转为JSON字符串的{x,y}坐标

(3)a 函数可以看出是AES加密ECB模式PKcs7。参数t 是 secretKey(这个可以再实战操作时验证)
第三步: 验证滑块是否乐成


浏览器上check 验证码响应乐成展示
第四步: 部分代码展示

JS 加密部分
  1. // 加密部分
  2. CryptoJS = require('crypto-js')
  3. function H(e, t) {
  4.     var i = CryptoJS.enc.Utf8.parse(t)
  5.       , n = CryptoJS.enc.Utf8.parse(e)
  6.       , r = CryptoJS.AES.encrypt(n, i, {
  7.         mode: CryptoJS.mode.ECB,
  8.         padding: CryptoJS.pad.Pkcs7
  9.     });
  10.     return r.toString()
  11. }
复制代码
python 请求部分
  1. # -*- coding:utf-8 -*-
  2. # @Time : 2025/2/18 14:31
  3. # @Author: 水兵没月
  4. # @File : captcha_滑块验证码.py
  5. # @Software: PyCharm
  6. import base64
  7. import random
  8. import time
  9. import execjs
  10. import requests
  11. from fake_useragent import UserAgent
  12. from shuibingmeiyue import req_payload # 可以写成requests.post(url, body=json.dumps(data), headers=headers)
  13. s = requests.Session()
  14. headers = {
  15.     "Accept": "application/json, text/plain, */*",
  16.     "Accept-Encoding": "gzip, deflate, br, zstd",
  17.     "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6",
  18.     "Cache-Control": "no-cache",
  19.     "Connection": "keep-alive",
  20.     "Content-Length": "106",
  21.     "Content-Type": "application/json; charset=UTF-8",
  22.     "Host": "captcha.ruijie.com.cn",
  23.     "Origin": "https://captcha.ruijie.com.cn",
  24.     "Pragma": "no-cache",
  25.     "Referer": "https://captcha.ruijie.com.cn/",
  26.     "User-Agent": UserAgent().Chrome,
  27. }
  28. # 此处忽略一些非重点代码
  29. # 此处忽略一些非重点代码
  30. # 此处忽略一些非重点代码
  31. def get_slide(target_bytes, background_bytes):
  32.         '''获取滑块位移值'''
  33.     import ddddocr
  34.     # 关闭广告显示
  35.     ocr = ddddocr.DdddOcr(show_ad=False, det=False, ocr=False, )
  36.     res = ocr.slide_match(target_bytes, background_bytes, simple_target=True)
  37.     print(res)
  38.     target_json = float(res["target"][0] + float(
  39.         '{}'.format(random.choice([15.5, 16.5]))))
  40.     # target_json = res["target"][0]
  41.     return target_json
  42. def get_AES():
  43.         '''获取AES的JS源码'''
  44.     with open('./captche_AES.js', 'r', encoding="utf-8")as f:
  45.         AES_source = f.read()
  46.     f.close()
  47.     return AES_source
  48. def get_image_Base64(img_json):
  49.         '''获取图片编码以及其他参数'''
  50.     img_repData = img_json.get("repData")
  51.     secretKey = img_repData.get("secretKey")
  52.     originalImageBase64 = img_repData.get("originalImageBase64")
  53.     jigsawImageBase64 = img_repData.get("jigsawImageBase64")
  54.     token = img_repData.get("token")
  55.        
  56.         # origin_Base64和jigsaw_Base64 已被忽略。作用保存图片
  57.     origin_Base64(originalImageBase64)
  58.     jigsaw_Base64(jigsawImageBase64)
  59.     # 读取滑块图片和背景图片的二进制数据
  60.     # read_origin和read_jigsaw 已被忽略。 作用读取图片
  61.     target_bytes = read_origin()
  62.     background_bytes = read_jigsaw()
  63.     # 得到滑块位移
  64.     target_json = get_slide(target_bytes, background_bytes)
  65.     return secretKey, target_json, token
  66. def get_pic():
  67.         '''请求验证码网址'''
  68.     url = "https://captcha.ruijie.com.cn/captcha/get"
  69.     data = {"captchaType":"blockPuzzle","clientUid":"slider-9d5611b7-e5a0-40a2-a813-a18ecf0ccaf9","ts":int(time.time()*1000)}
  70.     res = req_payload(s, url, headers, data)
  71.     res_json = res.json()
  72.     secretKey, target_json, token = get_image_Base64(res_json)
  73.     return secretKey, target_json, token
  74. def check_captcha(secretKey, target_json, token):
  75.         '''检测验证码是否成功'''
  76.     print(target_json)
  77.     i = int(target_json)
  78.     i = 310 * i / int(330)
  79.     e = '{"x":' + str(i) + ',"y":5}'
  80.     AES_source = get_AES()
  81.     AES_ctx = execjs.compile(AES_source)
  82.     get_AES = AES_ctx.call("H", e, secretKey)
  83.     print('get_AES--', get_AES, len(get_AES))
  84.     #
  85.     url = "https://captcha.ruijie.com.cn/captcha/check"
  86.     pointJson = get_AES
  87.     data = {"captchaType":"blockPuzzle","pointJson":pointJson,"token":token}
  88.     print(data)
  89.     res = req_payload(s, url, headers, data)
  90.     print(res.text)
  91. secretKey, target_json, token = get_pic()
  92. check_captcha(secretKey, target_json, token)
复制代码

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


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

正序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

美食家大橙子

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表