import hashlib import json import math import random import time import httpx from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes from cryptography.hazmat.primitives import padding, serialization from cryptography.hazmat.primitives.asymmetric.padding import PKCS1v15 class Crack: def __init__(self, gt=None, challenge=None): self.pic_path = None self.s = None self.c = None self.session = httpx.Client(http2=True) self.session.headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36" } # self.session.verify = False self.gt = gt self.challenge = challenge self.aeskey = "".join( f"{int((1 + random.random()) * 65536):04x}"[1:] for _ in range(4) ) public_key = """-----BEGIN PUBLIC KEY----- MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDB45NNFhRGWzMFPn9I7k7IexS5 XviJR3E9Je7L/350x5d9AtwdlFH3ndXRwQwprLaptNb7fQoCebZxnhdyVl8Jr2J3 FZGSIa75GJnK4IwNaG10iyCjYDviMYymvCtZcGWSqSGdC/Bcn2UCOiHSMwgHJSrg Bm1Zzu+l8nSOqAurgQIDAQAB -----END PUBLIC KEY-----""" self.public_key = serialization.load_pem_public_key(public_key.encode()) self.enc_key = self.public_key.encrypt(self.aeskey.encode(), PKCS1v15()).hex() with open("mousepath.json", "r") as f: self.mouse_path = json.loads(f.read()) def get_type(self) -> dict: url = f"https://api.geetest.com/gettype.php?gt={self.gt}" res = self.session.get(url) return json.loads(res.text[1:-1])["data"] @staticmethod def encode(input_bytes: list): def get_char_from_index(index): char_table = ( "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789()" ) return char_table[index] if 0 <= index < len(char_table) else "." def transform_value(value, bit_mask): result = 0 for r in range(23, -1, -1): if (bit_mask >> r) & 1: result = (result << 1) + ((value >> r) & 1) return result encoded_string = "" padding = "" input_length = len(input_bytes) for i in range(0, input_length, 3): chunk_length = min(3, input_length - i) chunk = input_bytes[i : i + chunk_length] if chunk_length == 3: value = (chunk[0] << 16) + (chunk[1] << 8) + chunk[2] encoded_string += ( get_char_from_index(transform_value(value, 7274496)) + get_char_from_index(transform_value(value, 9483264)) + get_char_from_index(transform_value(value, 19220)) + get_char_from_index(transform_value(value, 235)) ) elif chunk_length == 2: value = (chunk[0] << 16) + (chunk[1] << 8) encoded_string += ( get_char_from_index(transform_value(value, 7274496)) + get_char_from_index(transform_value(value, 9483264)) + get_char_from_index(transform_value(value, 19220)) ) padding = "." elif chunk_length == 1: value = chunk[0] << 16 encoded_string += get_char_from_index( transform_value(value, 7274496) ) + get_char_from_index(transform_value(value, 9483264)) padding = ".." return encoded_string + padding @staticmethod def MD5(text: str): return hashlib.md5(text.encode()).hexdigest() @staticmethod def encode_mouse_path(path: list, c: list, s: str): def preprocess(path: list): def BFIQ(e): t = 32767 if not isinstance(e, int): return e else: if t < e: e = t elif e < -t: e = -t return round(e) def BGAB(e): t = "" n = 0 len(e or []) while n < len(e) and not t: if e[n]: t = e[n][4] n += 1 if not t: return e r = "" i = ["mouse", "touch", "pointer", "MSPointer"] for s in range(len(i)): if t.startswith(i[s]): r = i[s] _ = list(e) for a in range(len(_) - 1, -1, -1): c = _[a] l = c[0] if l in ["move", "down", "up"]: value = c[4] or "" if not value.startswith(r): _.pop(a) return _ t = 0 n = 0 r = [] s = 0 if len(path) <= 0: return [] o = None _ = None a = BGAB(path) c = len(a) for l in range(0 if c < 300 else c - 300, c): u = a[l] h = u[0] if h in ["down", "move", "up", "scroll"]: if not o: o = u _ = u r.append([h, [u[1] - t, u[2] - n], BFIQ(u[3] - s if s else s)]) t = u[1] n = u[2] s = u[3] elif h in ["blur", "focus", "unload"]: r.append([h, BFIQ(u[1] - s if s else s)]) s = u[1] return r def process(prepared_path: list): h = { "move": 0, "down": 1, "up": 2, "scroll": 3, "focus": 4, "blur": 5, "unload": 6, "unknown": 7, } def p(e, t): n = bin(e)[2:] r = "" i = len(n) + 1 while i <= t: i += 1 r += "0" return r + n def d(e): t = [] n = len(e) r = 0 while r < n: i = e[r] s = 0 while True: if s >= 16: break o = r + s + 1 if o >= n: break if e[o] != i: break s += 1 r += 1 + s _ = h[i] if s != 0: t.append(_ | 8) t.append(s - 1) else: t.append(_) a = p(n | 32768, 16) c = "" for l in range(len(t)): c += p(t[l], 4) return a + c def g(e, tt): def temp1(e1): n = len(e) r = 0 i = [] while r < n: s = 1 o = e[r] _ = abs(o) while True: if n <= r + s: break if e[r + s] != o: break if (_ >= 127) or (s >= 127): break s += 1 if s > 1: i.append((49152 if o < 0 else 32768) | s << 7 | _) else: i.append(o) r += s return i e = temp1(e) r = [] i = [] def n(e, t): return 0 if e == 0 else math.log(e) / math.log(t) for temp in e: t = math.ceil(n(abs(temp) + 1, 16)) if t == 0: t = 1 r.append(p(t - 1, 2)) i.append(p(abs(temp), t * 4)) s = "".join(r) o = "".join(i) def temp2(t): return t != 0 and t >> 15 != 1 def temp3(e1): n = [] def temp(e2): if temp2(e2): n.append(e2) for r in range(len(e1)): temp(e1[r]) return n def temp4(t): if t < 0: return "1" else: return "0" if tt: n = [] e1 = temp3(e) for r in range(len(e1)): n.append(temp4(e1[r])) n = "".join(n) else: n = "" return p(len(e) | 32768, 16) + s + o + n def u(e): t = "" n = len(e) // 6 for r in range(n): t += "()*,-./0123456789:?@ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz~"[ int(e[6 * r : 6 * (r + 1)], 2) ] return t t = [] n = [] r = [] i = [] for a in range(len(prepared_path)): _ = prepared_path[a] a = len(_) t.append(_[0]) n.append(_[1] if a == 2 else _[2]) if a == 3: r.append(_[1][0]) i.append(_[1][1]) c = d(t) + g(n, False) + g(r, True) + g(i, True) l = len(c) if l % 6 != 0: c += p(0, 6 - l % 6) return u(c) def postprocess(e, t, n): i = 0 s = e o = t[0] _ = t[2] a = t[4] while True: r = n[i : i + 2] if not r: break i += 2 c = int(r, 16) l = chr(c) u = (o * c * c + _ * c + a) % len(e) s = s[:u] + l + s[u:] return s return postprocess(process(preprocess(path)), c, s) def aes_encrypt(self, content: str): cipher = Cipher( algorithms.AES(self.aeskey.encode()), modes.CBC(b"0000000000000000") ) encryptor = cipher.encryptor() padder = padding.PKCS7(128).padder() padded_data = padder.update(content.encode()) padded_data += padder.finalize() ct = encryptor.update(padded_data) + encryptor.finalize() return ct def get_c_s(self): o = { "gt": self.gt, "challenge": self.challenge, "offline": False, "new_captcha": True, "product": "embed", "width": "300px", "https": True, "protocol": "https://", } o.update(self.get_type()) o.update( { "cc": 16, "ww": True, "i": "-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1", } ) o = json.dumps(o, separators=(",", ":")) # print(o) ct = self.aes_encrypt(o) s = [] for byte in ct: s.append(byte) i = self.encode(s) r = self.enc_key w = i + r params = { "gt": self.gt, "challenge": self.challenge, "lang": "zh-cn", "pt": 0, "client_type": "web", "callback": "geetest_" + str(int(round(time.time() * 1000))), "w": w, } resp = self.session.get("https://api.geetest.com/get.php", params=params).text # print(resp) data = json.loads(resp[22:-1])["data"] self.c = data["c"] self.s = data["s"] return data["c"], data["s"] def gettype(self): url = f"https://api.geetest.com/gettype.php?gt={self.gt}&callback=geetest_{str(int(round(time.time() * 1000)))}" return self.session.get(url).text def ajax(self): def transform(e, t, n): if not t or not n: return e o = 0 i = list(e) s = t[0] a = t[2] b = t[4] while o < len(n): r = n[o : o + 2] o += 2 c = int(r, 16) l = chr(c) u = (s * c * c + a * c + b) % len(i) i.insert(u, l) return "".join(i) mouse_path = [ ["move", 385, 313, 1724572150164, "pointermove"], ["move", 385, 315, 1724572150166, "pointermove"], ["move", 386, 315, 1724572150174, "pointermove"], ["move", 387, 315, 1724572150182, "pointermove"], ["move", 387, 316, 1724572150188, "pointermove"], ["move", 388, 316, 1724572150204, "pointermove"], ["move", 388, 317, 1724572150218, "pointermove"], ["down", 388, 317, 1724572150586, "pointerdown"], ["focus", 1724572150587], ["up", 388, 317, 1724572150632, "pointerup"], ] tt = transform( self.encode_mouse_path(mouse_path, self.c, self.s), self.c, self.s ) rp = self.MD5(self.gt + self.challenge + self.s) temp1 = ( """"lang":"zh-cn","type":"fullpage","tt":"%s","light":"DIV_0","s":"c7c3e21112fe4f741921cb3e4ff9f7cb","h":"321f9af1e098233dbd03f250fd2b5e21","hh":"39bd9cad9e425c3a8f51610fd506e3b3","hi":"09eb21b3ae9542a9bc1e8b63b3d9a467","vip_order":-1,"ct":-1,"ep":{"v":"9.1.9-dbjg5z","te":false,"me":true,"ven":"Google Inc. (Intel)","ren":"ANGLE (Intel, Intel(R) Iris(R) Xe Graphics (0x0000A7A0) Direct3D11 vs_5_0 ps_5_0, D3D11)","fp":["scroll",0,1602,1724571628498,null],"lp":["up",386,217,1724571629854,"pointerup"],"em":{"ph":0,"cp":0,"ek":"11","wd":1,"nt":0,"si":0,"sc":0},"tm":{"a":1724571567311,"b":1724571567549,"c":1724571567562,"d":0,"e":0,"f":1724571567312,"g":1724571567312,"h":1724571567312,"i":1724571567317,"j":1724571567423,"k":1724571567330,"l":1724571567423,"m":1724571567545,"n":1724571567547,"o":1724571567569,"p":1724571568259,"q":1724571568259,"r":1724571568261,"s":1724571570378,"t":1724571570378,"u":1724571570380},"dnf":"dnf","by":0},"passtime":1600,"rp":"%s",""" % (tt, rp) ) r = "{" + temp1 + '"captcha_token":"1198034057","du6o":"eyjf7nne"}' # print(r) ct = self.aes_encrypt(r) s = [byte for byte in ct] w = self.encode(s) params = { "gt": self.gt, "challenge": self.challenge, "lang": "zh-cn", "pt": 0, "client_type": "web", "callback": "geetest_" + str(int(round(time.time() * 1000))), "w": w, } resp = self.session.get("https://api.geetest.com/ajax.php", params=params).text return json.loads(resp[22:-1])["data"] def get_pic(self, retry): params = { "type": "click", "gt": self.gt, "challenge": self.challenge, "lang": "zh-cn", "callback": "geetest_" + str(int(round(time.time() * 1000))), } if retry == 0: url = "https://api.geevisit.com/get.php" params.update( { "is_next": "true", "https": "true", "protocol": "https://", "offline": "false", "product": "float", "api_server": "api.geevisit.com", "isPC": True, "autoReset": True, "width": "100%", } ) else: url = "https://api.geetest.com/refresh.php" resp = self.session.get(url, params=params).text data = json.loads(resp[22:-1])["data"] self.pic_path = data["pic"] pic_url = "https://" + data["image_servers"][0][:-1] + data["pic"] return data["pic_type"], self.session.get(pic_url).content def verify(self, points: list): u = self.enc_key o = { "lang": "zh-cn", "passtime": 1600, "a": ",".join(points), "pic": self.pic_path, "tt": self.encode_mouse_path(self.mouse_path, self.c, self.s), "ep": { "ca": [ {"x": 524, "y": 209, "t": 0, "dt": 1819}, {"x": 558, "y": 299, "t": 0, "dt": 428}, {"x": 563, "y": 95, "t": 0, "dt": 952}, {"x": 670, "y": 407, "t": 3, "dt": 892}, ], "v": "3.1.0", "$_FB": False, "me": True, "tm": { "a": 1724585496403, "b": 1724585496605, "c": 1724585496613, "d": 0, "e": 0, "f": 1724585496404, "g": 1724585496404, "h": 1724585496404, "i": 1724585496404, "j": 1724585496404, "k": 0, "l": 1724585496413, "m": 1724585496601, "n": 1724585496603, "o": 1724585496618, "p": 1724585496749, "q": 1724585496749, "r": 1724585496751, "s": 1724585498068, "t": 1724585498068, "u": 1724585498069, }, }, "h9s9": "1816378497", } o["rp"] = self.MD5(self.gt + self.challenge + str(o["passtime"])) o = json.dumps(o, separators=(",", ":")) # print(o) ct = self.aes_encrypt(o) s = [] for byte in ct: s.append(byte) p = self.encode(s) w = p + u params = { "gt": self.gt, "challenge": self.challenge, "lang": "zh-cn", "pt": 0, "client_type": "web", "w": w, } resp = self.session.get("https://api.geevisit.com/ajax.php", params=params).text return resp[1:-1]