SoFunction
Updated on 2024-11-18

Python slider captcha hack implementation

There are 2 main ideas to break the slider captcha:

  • Get a complete background image and a nicked image, and the two images are compared pixel by pixel to find the coordinates that are not the same.
  • A notched image and a small image to be verified are obtained, and the two images are polarized as well as normalized to determine the coordinates of the small image in the middle of the image.
  • After that it's time to use middle school physics knowledge, using linear acceleration to mimic a person operating manually

This time on the use of the second, the first is relatively simple. Not much to say, directly on the code:

The following are obtained using the headless browser

Get a small image of the slider validation

def get_image1(self,driver):
  """
  Get the slider validation notch small image
  :param driver:chrome object
  :return:Notched small image
  """
  canvas = driver.find_element_by_xpath("//div[@id='xy_img']").get_attribute("style")
  image_data=("data:image/jpg;base64,(.*?)\"\)",canvas)[0]
  # print(image_data)
  binary_image_data=base64.b64decode(image_data,'-_')
  file_like=BytesIO(binary_image_data)
  image=(file_like)
  return image

Generally, this small image is independent and better to obtain, the image is as follows:

Get the background image for slider validation

! This background image web page will generally return disorganized pictures, and then reorder the pictures through js, to crack the time needed is more, and each js sorting algorithm is not the same, does not have reusability. Here took a trick, directly on the current browser screenshot, and then in the interception of the specified range of pictures.

def get_image2(self,driver):
  """
  Get slider captcha background image
  :param driver:chrome object
  :return:background image
   """
  driver.save_screenshot('')
  # Get coordinate values from image element nodes
  # element = driver.find_element_by_id("bgImg")
  # left = ['x']
  # top = ['y']
  # right = ['x'] + ['width']
  # bottom = ['y'] + ['height']
  # Obtain the coordinate values of the corresponding images directly through the drawing software
  left=359
  top=238
  right=658
  bottom=437
  # print((left, top, right, bottom))
  im = ('')
  im = ((left, top, right, bottom))
  return im

Pictures are below:

Trajectory calculation method

def get_track(self, distance):
  """
  Get the movement trajectory based on the offset
  :param distance:offset
  :return:Move trajectory
  """
  # Moving trajectories
  track = []
  # Current displacement
  current = 0
  # Deceleration threshold
  mid = distance * 4 / 5
  # Calculation interval
  t = 0.2
  # Initial velocity
  v = 0

  while current < distance:
    if current < mid:
      # Acceleration is positive 2
      a = 2
    else:
      # Acceleration is negative 3
      a = -3
    # Initial velocity v0
    v0 = v
    # Current velocity v = v0 + at
    v = v0 + a * t
    # Move distance x = v0t + 1/2 * a * t^2
    move = v0 * t + 1 / 2 * a * t * t
    # Current displacement
    current += move
    # Join the track
    (round(move))
  return track

Verify the main program

 def slider_verification_code(self,driver,cnt):
  """
  Cracking the slider validation main program
  :param driver:chrome object; cnt:validated counts
  :return:number of times verified
  """
  print("Slider validation appears. Validation in progress.")
  # 1, slider validation appears, get the validation small image
  picture1 = self.get_image1(driver)
  ("./")
  # 2. Get the notched validation image
  picture2 = self.get_image2(driver)
  ("./")
  # Binarize the images, compare them, and output the matching coordinate system.
  target_rgb=("./")
  target_gray=(target_rgb,cv2.COLOR_BGR2GRAY)
  template_rgb=("./",0)
  res=(target_gray,template_rgb,cv2.TM_CCOEFF_NORMED)
  value=(res)
  value = value[3][0]
  cnt += 1
  print("The distance to be displaced is:"+str(value)+", verified."+str(cnt)+"Second.")
  # Get the trajectory route of the displacement based on the distance
  track=self.get_track(value)
  (1)
  ActionChains(driver).click_and_hold(driver.find_element_by_class_name("handler.handler_bg")).perform()
  for x in track:
    ActionChains(driver).move_by_offset(xoffset=x, yoffset=0).perform()
  (0.5)
  ActionChains(driver).release().perform()
  return cnt

Look! There are airplanes:

This is the whole content of this article.