JS逆向入门案例-99某某中心(滑块验证)-10

文章目录

    • 概要
    • 整体架构流程
    • 小结

概要

提示:仅供学习,不得用做商业交易,如有侵权请及时联系v:wzwzwz0613

逆向:99某某中心(滑块验证)

URL:aHR0cHM6Ly9hcS45OS5jb20vVjMvTkRVc2VyX0xvZ2luLmh0bQ==

目的:滑块验证

在这里插入图片描述

整体架构流程

提示:获取配置参数接口,获取滑块背景图片接口,验证滑块接口

一、点击登录按钮,出现俩个接口(一个是配置接口,一个是获取滑块背景图片接口):

在这里插入图片描述
1、Default接口:Data参数相当于appid,写死即可

	url = "https://xxx/Default.ashx"
    data = {
        "Action": "checkcodeinit",
        "Data": "xxx",
        "Business": "common"
    }
    response = requests.post(url, headers=headers, data=data).json()

返回响应参数(Message下个接口的请求参数challenge):
在这里插入图片描述
二、slide接口:
在这里插入图片描述
请求参数:challenge上个接口返回值,ts是时间戳
在这里插入图片描述
观察发现背景图片是乱的,所以我们得还原背景图片,我们可以通过事件监听器进行断点,也就是画布断点:
在这里插入图片描述
响应参数:
在这里插入图片描述
imageRandomPos:底图还原的数组
originalImageBase64:乱的背景图片
secretKey:加密密钥(后面验证接口的参数会用到)
sliderImageBase64:滑块图片
这里我就不说怎么还原了,直接帖代码:

# order:还原数组,img_data:originalImageBase64,_img:还原的图片地址
# 底图还原
def huanyuan(order, img_data, _img):
    img_data = base64.b64decode(img_data)
    # 创建图像对象
    img = Image.open(io.BytesIO(img_data))
    a = img.width  # 宽度
    s = img.height  # 高度
    i = a // len(order)  # 每个块的宽度

    # 创建新的空白图像
    new_img = Image.new('RGB', (a, s))

    d = 0  # 当前位置
    for v in range(len(order)):
        h = order[v]
        y = i if h != len(order) - 1 else a - i * (len(order) - 1)
        
        # 获取拼图块
        l = img.crop((d, 0, d + y, s))
        
        # 粘贴到新图像中
        new_img.paste(l, (h * i, 0))
        d += y
    
    new_img.save(_img)

三、验证滑块接口,通过启动器断点,往上找,会找到这个位置:

在这里插入图片描述

那么c就是我们验证接口的参数:
在这里插入图片描述

challenge:上个接口的
k:通过上个接口返回的secretKey对随机生成的16位字符串进行aes加密
i:通过上个接口返回的secretKey对随机生成的16位字符串进行aes加密

	from Crypto.Cipher import PKCS1_v1_5,AES
	from Crypto.PublicKey import RSA
	# Aes加密  Utf
	def aesEncrypt(text,key=None,iv=None):
	    cipher = AES.new(key.encode('utf-8'), AES.MODE_CBC, iv.encode('utf-8'))
	    pad = 16 - len(text) % 16
	    text = text + pad * chr(pad)
	    encrypted_text = cipher.encrypt(text.encode('utf-8'))
	    return base64.b64encode(encrypted_text).decode('utf-8')

最后就是w参数的生成,先看s生成:

	s = {
		  // 当前时间 new Date
		  t: a.stopTime,
		  // 滑块轨迹
          pj: a.trackArr,
          // 滑动时间
          ut: a.stopTime - a.startTime,
          // 背景图片宽
          iw: parseInt(a.bgImageWidth),
          // 背景图片高
          ih: parseInt(a.bgImageHeight),
          // 滑块背景图片 + new Date +'' 进行md5(大写)
          sm: zt.md5Encrypt(a.sliderImageBase64 + a.stopTime).toString().toUpperCase(),
          // 浏览器指纹信息
          bi: n.config.fp,
          // 配置接口Date参数
          bf: n.config.fpHash,
          ct: "slide"
          }

在这里插入图片描述
获取滑动距离代码:

	# 获取滑块距离
def identify_gap(bg, tp):
    """
    bg: 背景图片
    tp: 缺口图片
    out: 输出图片
    """
    # 读取背景图片和缺口图片
    bg_img = cv2.imdecode(np.frombuffer(bg, np.uint8), cv2.IMREAD_GRAYSCALE)
    tp_img = cv2.imdecode(np.frombuffer(tp, np.uint8), cv2.IMREAD_GRAYSCALE)  # 缺口图片
    yy = []
    xx = []
    for y in range(tp_img.shape[0]):
        for x in range(tp_img.shape[1]):
            r = tp_img[y, x]
            if r < 200:
                yy.append(y)
                xx.append(x)
    tp_img = tp_img[min(yy):max(yy), min(xx):max(xx)]
    # 识别图片边缘
    bg_edge = cv2.Canny(bg_img, 100, 200)
    tp_edge = cv2.Canny(tp_img, 100, 200)
    # 转换图片格式
    bg_pic = cv2.cvtColor(bg_edge, cv2.COLOR_GRAY2RGB)
    tp_pic = cv2.cvtColor(tp_edge, cv2.COLOR_GRAY2RGB)
    # 缺口匹配
    res = cv2.matchTemplate(bg_pic, tp_pic, cv2.TM_CCOEFF_NORMED)
    min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)  # 寻找最优匹配
    # # 绘制方框
    th, tw = tp_pic.shape[:2]
    tl = max_loc  # 左上角点的坐标
    br = (tl[0] + tw, tl[1] + th)  # 右下角点的坐标
    cv2.rectangle(bg_img, tl, br, (0, 0, 255), 2)  # 绘制矩形
    cv2.imwrite('distinguish.jpg', bg_img)  # 保存在本地
    # 返回缺口的X坐标
    return max_loc[0]

获取轨迹代码:

# 获取滑块轨迹1
def guiji(distance):
	trackList = 收集浏览器从头滑到尾的距离
	# 检查value是否在轨迹的x值中
    for trajectory in trackList:
        if trajectory['x'] == distance:
            # 如果找到,截取从轨迹开始到该点的子数组
            return [t for t in trackList if t['x'] <= distance]

    # 如果value不在x值中,找到最接近value的x值
    closest_x = None
    min_diff = float('inf')
    for trajectory in trackList:
        if abs(trajectory['x'] - distance) < min_diff:
            min_diff = abs(trajectory['x'] - distance)
            closest_x = trajectory['x']

    # 截取从轨迹开始到最接近的x值的子数组
    result = [t for t in trackList if t['x'] <= closest_x]
    result[-1]['x'] = distance
    return result

RSA加密:

# RSA加密
def RsaEncrypt(plaintext,key):
    key_bytes = base64.b64decode(key)
    public_key = RSA.importKey(key_bytes)
    cipher = PKCS1_v1_5.new(public_key)
    bits_len = int(public_key.size_in_bits() / 1024 * 100)
    ciphertext = b""
    for i in range(0, len(plaintext), bits_len):
        ciphertext += cipher.encrypt(plaintext[i:i + bits_len].encode())
    result = base64.b64encode(ciphertext).decode('utf-8')
    return result

四、最后我们看效果

在这里插入图片描述

小结

提示:学习交流群:v:wzwzwz0613

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值