A certain shield – slider verification – automatically obtain the validate value – (reverse js+python)

I am the title

  • 1. From get? The website obtains the slider image and token
    • 1.1 Get fp value
    • 1.2 Get cb value
    • 1.3 Simulate contract delivery
  • 2. Get the slider movement distance
  • 3. Send the package to obtain the final validate value
    • 3.1 Trajectory generation
    • 3.2 Check website delivery
    • 3.3 Get data value
  • 4 Conclusion




This experiment is based on the XX shield sample website

Mainly divided into two parts

1. From get? The website obtains the slider image and token

2. Get the slider movement distance based on the obtained picture

3. Is the package sent to check based on the moving distance and token? The website gets the validate value

1. From get? The website obtains the slider image and token

To simulate a website sending a contract, you need to obtain the fp value and cb value.
yyyyyy

1.1 Get fp value

The js of the website has been obfuscated and looks messy, but it does not affect the reverse search. The js code and the specific method of deducting the code will not be introduced again.
You can directly search the keywords on the image to find the specific location of js on the website.

It should be noted that for confused arrays, the following two functions need to be added to change the order of the array to the correct order.
It should also be noted that fp is related to the domain name of the website, which is the domain name of the website where the verification application is applied, and is set as the input variable hrefff.

The location of the passed in variable

1.2 Get cb value

The js code for obtaining cb is also obfuscated. The following two functions need to be added. Note that there are two functions. The second function needs to pass in parameters.

The original cb code is in webpack and requires a loader.
The first box is the loader, which can use a template or copy the executor from the source website.
The second box is the required method, the dictionary search method. The original code uses hexadecimal array method to search. Specifically, you can look for 0x** from the loader of the source code to find the specific method.
The third box is to obtain the cb execution code.

1.3 Simulated contract delivery

All header files used in this article

import cv2
import numpy as np
import requests
import execjs
import json
import re
import os
import random
import time

Use python to simulate sending packages

 get_web = 'https://xxxxx/api/v3/get'
    payload ={<!-- -->
        "referer":"https://xxxxx/trial/jigsaw",
        "zoneId":"CN31",
        "dt":"yyyyyy",
        "acToken":"undefined",
        "id":"yyyyyy",
        "fp":Get_fp(),
        "cb":Get_cb(),
        "https":"true",
        "type":2,
        "version":"2.25.0",
        "dpr":"1.25",
        "dev":1,
        "ipv6":"false",
        "runEnv":10,
        "group":"",
        "scene":"","lang":"zh-CN","sdkVersion":"undefined","iv":3,
        "width":320,"audio":"false","sizeType":10,"smsVersion":"v3",
        "token":"",
        "callback":"__JSONP_4ti1bll_29"}
headers = {<!-- -->
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36'
}
    res = requests.get(get_web, params=payload, headers=headers)
    print(res.text)
    
    res_str = re.search("\((.*?)\);",res.text)#match
    res_json = json.loads(res_str.groups()[0])

    if (res_json['msg'] == 'ok'):
        bg_image = res_json['data']['bg']
        ft_image = res_json['data']['front']
        token = res_json['data']['token']
        save_image(bg_image,'bg_image.png')
        save_image(ft_image,'ft_image.png')

Execute js file

def js_from_file(file_name):
    """
    Read js file
    :return:
    """
    with open(file_name, 'r', encoding='UTF-8') as file:
        result = file.read()

    string = "\
    /*Solve browser environment issues*/\
    const {<!-- --> JSDOM }= require('jsdom');\
    const dom = new JSDOM('<!DOCTYPE html><p>Hello world</p>');\
    const window = dom.window;\
    const document = window.document;\
    XMLHttpRequest = window.XMLHttpRequest;\
    "

    return (string + result)
def Get_fp():
    # Compile and load js string
    context1 = execjs.compile(js_from_file('..\fp.js'),cwd=r'C:\Users\xxx\AppData\Roaming\\
pm\\
ode_modules' ) #Use the compile() method of the execjs class to compile and load the above JS string and return a context object
    fp = context1.call('fp','dun.163.com')
    #print(fp)
    return fp

def Get_cb():
    # Compile and load js string
    context1 = execjs.compile(js_from_file('..\\cb.js'),cwd=r'C:\Users\xxx\AppData\Roaming\\
pm\\
ode_modules' ) #Use the compile() method of the execjs class to compile and load the above JS string and return a context object
    cb = context1.eval("getcb()")
    #print(cb)
    return cb

2. Get the slider movement distance

The details will not be explained anymore. The main purpose is to match the marginalized images of grayscale images, and the distance between the two can be directly returned. Note that the distance is in both the x and y directions, and only the value in the x direction is returned.

#Get the position of the slider on the background
def slider_location(slider_img,bg_image):
    """
        TM_SQDIFF squared difference matching method This method uses squared difference for matching; the best matching value is 0; the worse the matching, the greater the matching value.
        TM_CCORR Correlation matching method This method uses multiplication operation; the larger the value, the better the matching.
        TM_CCOEFF correlation coefficient matching method 1 represents a perfect match; -1 represents the worst match.
        TM_SQDIFF_NORMED Normalized squared difference matching method   
        TM_CCORR_NORMED Normalized correlation matching method   
        TM_CCOEFF_NORMED Normalized correlation coefficient matching method
    """
    res = cv2.matchTemplate(bg_image,slider_img,cv2.TM_CCOEFF_NORMED)
    threshold=0.9
    while (len(np.where(res >= threshold)[1])==0 and threshold!=0):
        threshold-=0.1
    if (threshold):
        return np.where(res >= threshold)[1] #Select the 0th value of the x coordinate
    else:
        return 0
#Get the sliding distance and return the distance
def get_distance():

    slider_img =cv2.imread('.\bg_image.png',0) #0Get the grayscale value
    bg_image=cv2.imread('.\ft_image.png',0)

    # Identify image edges
    bg_edge = cv2.Canny(bg_image, 100, 200)
    tp_edge = cv2.Canny(slider_img, 100, 200)

    cv2.imwrite('sd_image1.png',tp_edge)
    cv2.imwrite('bg_image1.png',bg_edge)

    return slider_location(tp_edge,bg_edge)[0]

3. Send the package to obtain the final validate value

3.1 Trajectory generation

Based on the slider movement distance and the cookie value returned in the first step, a packet is sent for verification to obtain the validate value.
The trajectory coordinates need to be constructed according to the movement distance of the slider. My trajectory coordinate method is quite bad, so I won’t post it here. It looks like the picture below.

3.2 check website outsourcing

The following ts_str is the string conversion form of json of the trajectory.
Note that token must be the same as get? Returns the same.

 get_web = 'https://xxxxx/api/v3/check'
    payload ={<!-- -->
        "referer":"https://xxxxx/trial/jigsaw",
        "zoneId":"CN31",
        "dt":"yyyyyy",
        "id":"yyyyyyyyyyy",
        "acToken":"undefined",
        "token":token,
        "data":Get_data(token,ts_str),
        "width":320,
        "type":2,
        "version":"2.25.0",
        "cb":Get_cb(),
        'extraData':"",
        'bf':0,
        "runEnv":10,
        "sdkVersion":"undefined",
        "iv":3,
        "callback":"__JSONP_mbi1bll_30"} #Randomly generate callback
        

    res = requests.get(get_web, params=payload, headers=headers)
    if len(res.text)> 150:
        print(res.text)
        return 1
    #print(token)
    return 0

3.3 Get data value

data is a dictionary converted to a string and contains many encrypted variables.


4. Conclusion

The current success rate is not high. It should be because the slider trajectory is not done well and is easily discovered. We can study it in detail in the future.
Did 20 experiments,
6 times more than 20 times
The average number of successes in 14 times is less than 5 times