JS逆向实战6-- x轴 y轴 过点触验证码

点触验证码是一种常见的反爬手段
解决方案有两种:一种是直接解决,这需要深度学习机器学习等图像处理技术,以大量的数据训练识别模型,最终达到模型足矣识别图片中的文字提示和应该点击的区域之间的对应关系。
这需要非常专业的设备,比如TPU运算,和专业的开发和维护人员。
因此市面上有专业解决此类问题的OCR解决提供商。也就是第二种间接解决的方案,调用第三方接口。

我们可以使用两种方案

  • selenium
  • 接口逆向

本文介绍是第二种方法 当然 属于比较简单的那种JS逆向实战6-- x轴 y轴 过点触验证码_第1张图片
验证码如上文所示

ocr的使用

我们使用DDDDocr去过这个验证,但是成功几率不高

镜像安装

pip install ddddocr -i https://pypi.tuna.tsinghua.edu.cn/simple

接口分析

过验证 首先分析接口JS逆向实战6-- x轴 y轴 过点触验证码_第2张图片
如上图 我们可知 这是发送了两个请求
经分析可知
我们先访问 http://www.yngp.com/api/captcha/captcha.get.svc check这个链接

拿到参数

然后拿到里面的参数 originalImageBase64 wordList secretKey token这些值
然后把这个originalImageBase64 这个值base64解码 得到图片
从而传入 DDDDocr中 解析图片 得到图片的xy轴
部分代码如下

data = {"captchaType": "clickWord", "clientUid": "point-c1db047e-ccf0-4826-a611-c05ea3eccf3c",
        "ts": int(time.time() * 1000)}
self.session.headers = self.headers
response = self.session.post('http://www.yngp.com/api/captcha/captcha.get.svc', data=data)
img_content = base64.b64decode(response.json()['data']['repData']['originalImageBase64'])
wordList = response.json()['data']['repData']['wordList']
key = response.json()['data']['repData']['secretKey']
token = response.json()['data']['repData']['token']
# 解析图片 得到图片的xy轴
img_xy = self.dd.decrypt(img_content)

二次分析

我们进入断点可知 这个postJson是我们所需要的值JS逆向实战6-- x轴 y轴 过点触验证码_第3张图片
可以看到 这个值是根据xy加密所得
只需要进行ECB模式下的AES加密即可完成解密

具体代码如下

# -*- coding: utf-8 -*-
# @Time    : 2022/9/16 15:43
# @Author  : lzc
# @Email   : [email protected]
# @File    : YunNanBidding.py
# @Software: PyCharm
import base64
import time
import requests
from requests.utils import add_dict_to_cookiejar

from utils.DDDDOCR import Ddddocr
from utils.InverseAlgorithm import InverseAlgorithm

ia = InverseAlgorithm()


class Bidding:
    cookies = {
        'route': 'a4dbdaac35560ad2faee898d4f49072d',
    }

    headers = {

        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36',
    }
    dd = Ddddocr()

    session = requests.session()

    requests.utils.add_dict_to_cookiejar(session.cookies, cookies)

    def get_text(self):
        data = {"captchaType": "clickWord", "clientUid": "point-c1db047e-ccf0-4826-a611-c05ea3eccf3c",
                "ts": int(time.time() * 1000)}
        self.session.headers = self.headers
        response = self.session.post('http://www.yngp.com/api/captcha/captcha.get.svc', data=data)
        img_content = base64.b64decode(response.json()['data']['repData']['originalImageBase64'])
        wordList = response.json()['data']['repData']['wordList']
        key = response.json()['data']['repData']['secretKey']
        token = response.json()['data']['repData']['token']
        img_xy = self.dd.decrypt(img_content)
        xy_data = ""
        # [{\"x\":49,\"y\":48},{\"x\":102,\"y\":116},{\"x\":242,\"y\":46}]
        # [{\"x\":55,\"y\":78},{\"x\":147,\"y\":79},{\"x\":228,\"y\":65}]
        for li in wordList:
            x, y = img_xy[li]

            xy_data += r'{"x":%d,"y":%d},' % (x, y)

            print(li, '坐标:', x, ',', y)
        en_text = f"[{xy_data[:-1]}]"
        pointjson = ia.aes_ECB_encrypt(key, en_text)
        print('成功', en_text)
        postdata = {"captchaType": "clickWord",
                    "pointJson": pointjson,
                    "token": token,
                    "clientUid": "point-01a36d7d-2bff-49d0-bd09-e10b6e744bb9",
                    "ts": int(time.time() * 1000)}
        self.session.post('http://www.yngp.com/api/captcha/captcha.check.svc',
                          json=postdata, verify=False)
        captchaCheckId = ia.aes_ECB_encrypt(key, str(str(token) + '---' + en_text))
        print(captchaCheckId)
        postdata = {'current': '1',
                    'rowCount': '10',
                    'searchPhrase': '',
                    'query_bulletintitle': '矿',
                    'query_bulletinclass': '',
                    'query_unitcode': '',
                    'query_startTime': '',
                    'query_endTime': '',
                    'query_districtcode': ''}
        url = 'http://www.yngp.com/api/procurement/Procurement.searchForMainList.svc?captchaCheckFlag=' + captchaCheckId + '&p=1'

        reson = self.session.post(
            url=url,
            data=postdata,
        )
        print(reson.text)


if __name__ == '__main__':
    Bidding().get_text()

你可能感兴趣的:(JS逆向)