「技术分享」解密凡科网滑块验证:逆向JS、base64解码与Selenium应用插图

前提和大概思路概述

只是学习的途中有一些新的发现,分享给大家,希望对你们有帮助。

凡科网的JS逆向的闭包技巧应该是典型的闭包案例,很多人都有讲解,这里只做一个粗略介绍。

正常完成逆向之后,进行模拟登录,好像是因为我的多次请求,出现了滑块验证。

「技术分享」解密凡科网滑块验证:逆向JS、base64解码与Selenium应用插图1
「技术分享」解密凡科网滑块验证:逆向JS、base64解码与Selenium应用插图2

先要做的是拿到底图和完整图或者滑块,但凡科网的这里只能找到图片base64伪加密后的imgId和sliderId,发起对应请求想得到后解码,奈何自己实在试过一堆法子,一直请求失败,无奈下换用selenium做模拟登录,重要的还是做滑块的思路嘛(实际还是自己实力不够–)

「技术分享」解密凡科网滑块验证:逆向JS、base64解码与Selenium应用插图3
{'success': False, 'msg': {'dealType': 1, 'capErrno': -2}}
「技术分享」解密凡科网滑块验证:逆向JS、base64解码与Selenium应用插图4

转换思路selenium和验证滑块图片的获取处理

用到的库:

from selenium.webdriver import Chrome
import time
import requests
from selenium.webdriver.common.action_chains import ActionChains
import base64
import numpy as np
import cv2 as cv

先模拟登录一下试试:

# ***中输入你的账号和密码
web = Chrome()
web.get('https://i.fkw.com/')
time.sleep(1)
web.find_element_by_xpath('//*[@id="loginCacct"]').send_keys('***')
web.find_element_by_xpath('//*[@id="loginPwd"]').send_keys('***')
time.sleep(1)
web.find_element_by_xpath('//*[@id="login_button"]').click()
time.sleep(2)

好家伙一下子就进去了,可毕竟咱们是长见识为主,所以咱拿错误的账号密码来做试验(正确的重复多次登录后也会出现)。

现在的重点主要是获取到对应的图片base64编码后的数据,在进行解码,存储图片。(注意只需要base64后的数据,要对数据做一定处理)

「技术分享」解密凡科网滑块验证:逆向JS、base64解码与Selenium应用插图5
ImgId_str = web.find_element_by_xpath('/html/body/div[4]/div/div[2]/div/div/div[3]/div/div[1]/div[1]/img[1]').get_attribute('src')
ImgId = '/' + ImgId_str.strip('data:image/jpeg;base64,')
sliderId_str = web.find_element_by_xpath('/html/body/div[4]/div/div[2]/div/div/div[3]/div/div[1]/div[1]/img[2]').get_attribute('src')
sliderId = 'i' + sliderId_str.lstrip('data:image/jpeg;base64,')

发现得到的这大串玩意,看起来蛮爽。开始解码,好像规则里的整除加=不是很有作用,我试了试加不加都可以(可能是我忽略了细节),把滑块和底图都存储起来。

def decode_base64(strs,i):
    if(len(strs)%4 == 1):
        strs += "==="
    elif(len(strs)%4 == 2):
        strs += '=='
    elif(len(strs)%4 == 3):
        strs += '='
    imgdata = base64.b64decode(strs)
    file = open(f'{i}.jpg','wb')
    file.write(imgdata)
    file.close()

用cv.TM_CCOEFF_NORMED算法进行精度匹配,将一维位置转换为二维位置,得到x,y的坐标。

Img_ = cv.imread('1.jpg')
slider_ = cv.imread('2.jpg')
result = cv.matchTemplate(Img_, slider_, cv.TM_CCOEFF_NORMED)
yiwei_ = np.argmax(result)  
x, y = np.unravel_index(yiwei_, result.shape)  
time.sleep(2)
# print(x,y)

找到滑的地方,模拟人工滑动,即可完成。(注意传输的坐标值)

web.implicitly_wait(10)
btn = web.find_element_by_xpath('/html/body/div[4]/div/div[2]/div/div/div[3]/div/div[1]/div[2]/div[1]/div')
ActionChains(web).drag_and_drop_by_offset(btn, xoffset=y, yoffset=0).perform()

总结

对图片base64解码处理后的滑块验证,很多地方都可以优化,比如如何让匹配速度更快,模拟人工轨迹一步步滑等等。爬虫无上限,可能图片验证,滑块验证成功,账号密码正确,还是会显示验证码错误(12306目前是这样的),还有很多的selenium限制的地方。