├── README.md ├── enc.js └── slide.py /README.md: -------------------------------------------------------------------------------- 1 | # -abogus-a_bogus-ttwid-req_sign-bd_ticket_guard_client_data-sig3- 2 | 抖音网页版2024最新算法,abogus、a_bogus,抖音滑块,文字点选,ttwid,req_sign,bd_ticket_guard_client_data,私钥生成,评论上传图片signature加密,抖音扫码登录算法,抖音直播间弹幕采集,抖音爬虫; 3 | 快手sig3算法,快手滑块; 4 | 小红书xs加密; 5 | 腾讯滑块,腾讯文字点选,腾讯六图,tx_msg加密; 6 | 数美滑块,devideid; 7 | 极验4代全家桶,极验滑块,极验文字点选,无感,图标,五子棋,消消乐; 8 | 瑞数6,瑞数信息安全,中国海关; 9 | 网易易盾滑块; 10 | 阿里227(非x82y); 11 | reese84; 12 | akamai 阿卡迈; 13 | px3; 14 | datadome; 15 | 专注航空航司:reese84,akamai,hcaptcha; 16 | 17 | 各类加密算法,在线接单!!! 18 | 交流学习vx(备注来意):ProfessorLuoMing 19 | -------------------------------------------------------------------------------- /enc.js: -------------------------------------------------------------------------------- 1 | //bd_ticket_guard_client_data生成方法 2 | //在登录过程中会出现两个bd_ticket_guard_client_data,可以抓包base64解码查看两个bd_ticket_guard_client_data组成, 3 | //第一个'{"bd-ticket-guard-version":2,"bd-ticket-guard-iteration-version":1,"bd-ticket-guard-ree-public-key":"BN5YmS3JDO+9bge5r1NgWzg6k6TeHcNIagDxeD77Q9rabrX+kibN38mziGVe6Jj88U2d4Zuz46Z61GjFM4NCCAc=","bd-ticket-guard-web-version":1}' 4 | //第二个'{"ts_sign":"ts.1.3d16f1bea8bee4c5281219d3eb8dab3b56382db58c615529d1d05db8319e2b88c4fbe87d2319cf05318624ceda14911ca406dedbebeddb2e30fce8d4fa02575d","req_content":"ticket,path,timestamp","req_sign":"MEUCIBF5BF/25saHMGOOeB0I7qDRhck9ARwsFWzmMpkBzT8qAiEAoySCd7X7Sf93wRrGrLa0hCskVoF7hdBUf9WTCrd0p1s=","timestamp":1715141907}' 5 | //我们最终需要第二个 6 | //第一个需要解决的参数是bd-ticket-guard-ree-public-key 7 | // 第一次是调用_private_key函数生成私钥跟公钥,调用xt函数加密私钥得到bd_ticket_guard_ree_public_key 8 | //之后base64编码即可得到最初的bd_ticket_guard_client_data 9 | //第二个需要解决的参数是ts_sign,req_sign 10 | //经过一系列流程请求最终请求到一个关键请求https://www.douyin.com/passport/sso/login/callback/?ticket=你的&next=https%3A%2F%2Fwww.douyin.com 11 | //cookie里携带第一个bd_ticket_guard_client_data请求这个关键请求响应头里即可返回bd_ticket_guard_server_data这个关键参数还有其他cookie相关的参数,base64解码后得到 12 | //'{"ticket":"8fce9fb22205b0c2e7e43114b3523b60","ts_sign":"ts.1.3d16f1bea8bee4c5281219d3eb8dab3b56382db58c615529d1d05db8319e2b88c4fbe87d2319cf05318624ceda14911ca406dedbebeddb2e30fce8d4fa02575d","client_cert":"pub.BN5YmS3JDO+9bge5r1NgWzg6k6TeHcNIagDxeD77Q9rabrX+kibN38mziGVe6Jj88U2d4Zuz46Z61GjFM4NCCAc="}' 13 | //这里可以得到生成最终bd_ticket_guard_client_data需要的ts_sign 14 | //剩下req_sign待解决 15 | //req_sign =调用js里的函数req_sign函数传入这段'ticket=' + ticket + '&path=/passport/token/beat/web/×tamp=1715141907'和私钥privatekey 16 | //最终加密生成出req_sign,到此bd_ticket_guard_client_data需要解决的ts_sign,req_sign都已解决 17 | //'{"ts_sign":"","req_content":"ticket,path,timestamp","req_sign":"","timestamp":1715141907}' 18 | //最后base64编码即可得到最终的bd_ticket_guard_client_data 19 | -------------------------------------------------------------------------------- /slide.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | import re 3 | 4 | from PIL import Image 5 | import uvicorn 6 | from fastapi import FastAPI, Response 7 | from pydantic import BaseModel 8 | import uuid 9 | import httpx 10 | import base64 11 | import random 12 | from PIL import Image 13 | import json 14 | import time 15 | from pathlib import Path 16 | import PIL 17 | import cv2 18 | import numpy as np 19 | import requests 20 | from Crypto.Cipher import AES 21 | from Crypto.Hash import SHA512 22 | import base64 23 | import ctypes 24 | import functools 25 | import json 26 | import random 27 | import string 28 | import time 29 | from urllib.parse import urlencode 30 | import ctypes 31 | import math 32 | import random 33 | import time 34 | 35 | class Dy: 36 | def __init__(self, ip): 37 | self.comment_fp_url = "https://www.douyin.com/aweme/v1/web/comment/list/" 38 | self.captcha_url = "https://verify.snssdk.com/captcha/get" 39 | self.verify_captcha_url = 'https://verify.zijieapi.com/captcha/verify' 40 | self.video_fp_url = "https://www.douyin.com/aweme/v1/web/aweme/post/" 41 | if ip != '': 42 | self.proxies = { 43 | 'http://': 'http://' + ip, 44 | 'https://': 'http://' + ip 45 | } 46 | else: 47 | self.proxies = None 48 | self.uuid = uuid.uuid4() 49 | 50 | self.main_filename = f"img/puzzle/{self.uuid}.jpeg" 51 | self.small_filename = f"img/piece/{self.uuid}.jpeg" 52 | self.http2 = httpx.Client(http2=True, proxies=self.proxies) 53 | 54 | 55 | def get_img(self, verify_data): 56 | headers = { 57 | 'authority': 'p3-catpcha.byteimg.com', 58 | 'accept': 'image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8', 59 | 'accept-language': 'zh-CN,zh;q=0.9,en;q=0.8', 60 | 'cache-control': 'no-cache', 61 | 'origin': 'https://rmc.bytedance.com', 62 | 'pragma': 'no-cache', 63 | 'referer': 'https://rmc.bytedance.com/', 64 | 'sec-ch-ua': '"Not A(Brand";v="99", "Google Chrome";v="121", "Chromium";v="121"', 65 | 'sec-ch-ua-mobile': '?0', 66 | 'sec-ch-ua-platform': '"Windows"', 67 | 'sec-fetch-dest': 'image', 68 | 'sec-fetch-mode': 'cors', 69 | 'sec-fetch-site': 'cross-site', 70 | 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36', 71 | } 72 | # params = { 73 | # "lang": "zh", 74 | # "app_name": "", 75 | # "h5_sdk_version": "3.5.56", 76 | # "sdk_version": "3.5.2", 77 | # "iid": "0", 78 | # "did": "0", 79 | # "device_id": "0", 80 | # "ch": "web_text", 81 | # "aid": "6383", 82 | # "os_type": "2", 83 | # "mode": "", 84 | # "tmp": str(int(time.time() * 1000)), 85 | # "platform": "pc", 86 | # "webdriver": "false", 87 | # "fp": verify_data['fp'], 88 | # "type": "verify", 89 | # "detail": verify_data['detail'], 90 | # "server_sdk_env": '{"idc":"hl","region":"CN","server_type":"whale"}', 91 | # "subtype": verify_data['subtype'], 92 | # "challenge_code": "99999", 93 | # "os_name": "windows", 94 | # "h5_check_version": "3.5.2" 95 | # } 96 | params = ( 97 | ('aid', '6383'), 98 | ('lang', 'zh'), 99 | ('subtype', 'slide'), 100 | ('detail', 101 | verify_data['detail']), 102 | ('server_sdk_env', '/{"idc":"lq","region":"CN","server_type":"whale"/}'), 103 | ('mode', 'slide'), 104 | ('fp', verify_data['fp']), 105 | ('h5_check_version', '3.5.2'), 106 | ('os_name', 'windows'), 107 | ('platform', 'pc'), 108 | ('os_type', '2'), 109 | ('h5_sdk_version', '3.5.56'), 110 | ('webdriver', 'false'), 111 | ('tmp', str(int(time.time() * 1000))), 112 | ) 113 | 114 | response = self.http2.get(self.captcha_url, headers=headers, params=params).json() 115 | if response['code'] == 200: 116 | return response['data'] 117 | 118 | def fp(self): 119 | e = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" 120 | t = len(e) 121 | milliseconds = int(round(time.time() * 1000)) 122 | base36 = '' 123 | while milliseconds > 0: 124 | remainder = milliseconds % 36 125 | if remainder < 10: 126 | base36 = str(remainder) + base36 127 | else: 128 | base36 = chr(ord('a') + remainder - 10) + base36 129 | milliseconds = int(milliseconds / 36) 130 | r = base36 131 | o = [''] * 36 132 | o[8] = o[13] = o[18] = o[23] = '_' 133 | o[14] = '4' 134 | for i in range(36): 135 | if not o[i]: 136 | n = 0 or int(random.random() * t) 137 | if i == 19: 138 | n = 3 & n | 8 139 | o[i] = e[n] 140 | ret = "verify_" + r + "_" + ''.join(o) 141 | return ret 142 | 143 | # def origin(self, img): 144 | # # 打开原始图片 145 | # image = Image.open(io.BytesIO(img)) 146 | # # 定义切割参数 147 | # width = 92 148 | # height = 344 149 | # num_slices = 6 150 | # slice_order = [5, 1, 4, 6, 3, 2] 151 | # # 创建一个空白的拼接图片 152 | # result_image = Image.new('RGB', (width * num_slices, height)) 153 | # # 切割并拼接图片 154 | # for i, slice_index in enumerate(slice_order): 155 | # # 计算切割的起始和结束位置 156 | # start_x = (slice_index - 1) * width 157 | # end_x = slice_index * width 158 | # 159 | # # 切割图片 160 | # slice_image = image.crop((start_x, 0, end_x, height)) 161 | # 162 | # # 将切割后的图片拼接到结果图片上 163 | # result_image.paste(slice_image, (i * width, 0)) 164 | # # 保存拼接后的图片 165 | # buffer = io.BytesIO() 166 | # result_image.save(buffer, format='JPEG') 167 | # binary_data = buffer.getvalue() 168 | # # 返回二进制数据 169 | # return binary_data 170 | # return result_image 171 | 172 | 173 | 174 | 175 | def verify(self, captcha_body, verify_data, data): 176 | headers = { 177 | 'authority': 'verify.snssdk.com', 178 | 'accept': '*/*', 179 | 'accept-language': 'zh-CN,zh;q=0.9,en;q=0.8', 180 | 'cache-control': 'no-cache', 181 | 'content-type': 'text/plain;charset=UTF-8', 182 | 'origin': 'https://rmc.bytedance.com', 183 | 'pragma': 'no-cache', 184 | 'referer': 'https://rmc.bytedance.com/', 185 | 'sec-ch-ua': '"Not A(Brand";v="99", "Google Chrome";v="121", "Chromium";v="121"', 186 | 'sec-ch-ua-mobile': '?0', 187 | 'sec-ch-ua-platform': '"Windows"', 188 | 'sec-fetch-dest': 'empty', 189 | 'sec-fetch-mode': 'cors', 190 | 'sec-fetch-site': 'cross-site', 191 | 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36', 192 | } 193 | # params = { 194 | # "lang": "zh", 195 | # # "app_name": "", 196 | # "h5_sdk_version": "3.5.56", 197 | # # "sdk_version": "3.8.6", 198 | # # "iid": "0", 199 | # # "did": "0", 200 | # # "device_id": "0", 201 | # "ch": "web_text", 202 | # "aid": "6383", 203 | # "os_type": "2", 204 | # "mode": data['mode'], 205 | # "tmp": str(int(time.time() * 1000)), 206 | # "platform": "pc", 207 | # "webdriver": "false", 208 | # "type": "verify", 209 | # "detail": verify_data['detail'], 210 | # "server_sdk_env": '{"idc":"lq","region":"CN","server_type":"whale"}', 211 | # "subtype": verify_data['subtype'], 212 | # # "challenge_code": '99999', 213 | # 'fp':verify_data['fp'], 214 | # "os_name": "windows", 215 | # "h5_check_version": "3.8.6", 216 | # "xx-tt-dd": "qJI7ttpVdGKKbSBvYqmaf0aPo" 217 | # } 218 | url=f"aid=6383&lang=zh&subtype={verify_data['subtype']}&detail={verify_data['detail']}&server_sdk_env=%7B%22idc%22%3A%22lq%22%2C%22region%22%3A%22CN%22%2C%22server_type%22%3A%22whale%22%7D&mode=slide&fp={verify_data['fp']}&h5_check_version=3.5.2&os_name=windows&platform=pc&os_type=2&h5_sdk_version=3.5.56&webdriver=false&tmp={str(int(time.time() * 1000))}&xx-tt-dd=qJI7ttpVdGKKbSBvYqmaf0aPo&msToken=Nw0F5oHRzu1F0BxQ48AtLQSNQuqGmn6qxREhWNZwIHXPt1biYVTB2xnOEm_WVjQ4U2bPFjRvo7NnLg5gy7RtDiF92g2nIj8igiXODlA_o6P4Nar8HMKi-ZLn9zDNVOjk" 219 | # ab = ABogus().getABogus( 220 | # user_agent=headers['user-agent'], param=url 221 | # , data=None) 222 | ab = getABogus(url, '', headers['user-agent']) 223 | 224 | params = ( 225 | ('aid', '6383'), 226 | ('lang', 'zh'), 227 | ('subtype', verify_data['subtype']), 228 | ('detail', 229 | verify_data['detail']), 230 | ('server_sdk_env', '{"idc":"lq","region":"CN","server_type":"whale"}'), 231 | ('mode', 'slide'), 232 | ('fp', verify_data['fp']), 233 | ('h5_check_version', '3.5.2'), 234 | ('os_name', 'windows'), 235 | ('platform', 'pc'), 236 | ('os_type', '2'), 237 | ('h5_sdk_version', '3.5.56'), 238 | ('webdriver', 'false'), 239 | ('tmp', str(int(time.time() * 1000))), 240 | ('xx-tt-dd', 'qJI7ttpVdGKKbSBvYqmaf0aPo'), 241 | ('msToken', 242 | 'Nw0F5oHRzu1F0BxQ48AtLQSNQuqGmn6qxREhWNZwIHXPt1biYVTB2xnOEm_WVjQ4U2bPFjRvo7NnLg5gy7RtDiF92g2nIj8igiXODlA_o6P4Nar8HMKi-ZLn9zDNVOjk'), 243 | ('a_bogus', ab), 244 | ) 245 | # params = ( 246 | # ('aid', '6383'), 247 | # ('lang', 'zh'), 248 | # # ('repoId', '579047'), 249 | # ('subtype', 'slide'), 250 | # ('detail', 251 | # verify_data['detail']), 252 | # ('server_sdk_env', '{"idc":"lq","region":"CN","server_type":"whale"}'), 253 | # ('mode', 'slide'), 254 | # ("fp", verify_data['fp']), 255 | # ('h5_check_version', '3.8.6'), 256 | # ('os_name', 'windows'), 257 | # ('platform', 'pc'), 258 | # ('os_type', '2'), 259 | # ('h5_sdk_version', '3.5.56'), 260 | # ('webdriver', 'false'), 261 | # ('tmp', str(int(time.time()*1000))), 262 | # ('xx-tt-dd', 'qJI7ttpVdGKKbSBvYqmaf0aPo'), 263 | # # ('msToken', 264 | # # 'jwnLUS-q2c1lvCnVlNjP4SwWQhydOtEiAoIZNLMaM1cuFaz_A1XoUz950pX6mQvvnt24AboHAe67YwVvflzSArs_pyHUEtxElW9xC_zUKyeFpFp5s8BsKOJJgnuJNKk='), 265 | # # ('a_bogus', 'D7BEfO26Msm16MVlm7kz9CK/h8y0YWR7gZEPJiPRf0oQ'), 266 | # ) 267 | data = { 268 | "captchaBody": captcha_body 269 | } 270 | response = self.http2.post(self.verify_captcha_url, headers=headers, json=data, params=params) 271 | print(response.text) 272 | if response.json()['code']==200 and response.json()['message']=='验证通过': 273 | return True 274 | 275 | def run(self, detail, fp, subtype): 276 | 277 | verify_data = {'detail': detail, 'fp': fp, 'subtype': subtype} 278 | fp = verify_data['fp'] 279 | data = self.get_img(verify_data) 280 | if subtype == "slide": 281 | time.sleep(3) 282 | value = get_distance( 283 | bg=requests.get(data['question']['url1']).content, 284 | tp=requests.get(data['question']['url2']).content, 285 | im_show=False, 286 | save_path=None 287 | ) 288 | y = data['question']['tip_y'] 289 | 290 | tt = get_track(int(value / 552 * 340), data['id'], y) 291 | captcha_body = captcha_encrypt(tt) 292 | 293 | result = self.verify(captcha_body, verify_data, data) 294 | if result: 295 | return fp 296 | 297 | 298 | 299 | # app = FastAPI() 300 | # 301 | # 302 | # class Item(BaseModel): 303 | # ip: str = None 304 | # detail: str = None 305 | # fp: str = None 306 | # 307 | # 308 | # @app.post("/douyin") 309 | # async def index20(item: Item): 310 | # item_dict = item.dict() 311 | # ip = item_dict['ip'] 312 | # detail = item_dict['detail'] 313 | # fp = item_dict['fp'] 314 | # result = Dy(ip).run(detail, fp, 'slide') 315 | # return result 316 | # 317 | # if __name__ == '__main__': 318 | # config = uvicorn.config.Config(app, host="0.0.0.0", port=8866, loop="asyncio", workers=64) 319 | # server = uvicorn.Server(config) 320 | # server.run() 321 | # result = Dy('').run( 322 | # 323 | # 'y80mbaoQH4zupIiI14CrOkvgVTXEvnJZkgfSLmFaQZtP8PIB2pqZixTAwibpRFVMzudgJW1uJK3F7Hl-UKX1bfwqwx6LZnsvcsTDdNi-pr*hYFNQTE*Mj4Cal9*Y8N3SZiX5HsJ5-NpWuF0ac4rh2W57Gafn3NP7JTcQJjjta2P*IwacDEfW2XsL1hGvuRBGmlJpb58vpeT26OwGqL1AMNbMD-o4oIhEeabzK5GD3fUBYe1riLk61F-9ZY4eTjTPAA5KceCAxoO4YKLqEI2E6RBQYfW-P4n0LZ2kN*2xGw*dpRjjPLK4nk9sDc6thNRSvqPds-ry-bqZfGQgnN*SOnjkWpVwWA1HZBVXmIEKtmXa7lvS3ylx7T0IjOXIYxSJBw4Hc0jdOJSzLpBGE4Bzk9kRYkwzlN2CAiY.' 324 | # ,'3620033887498343', 'slide') 325 | 326 | while 1: 327 | import requests 328 | headers = { 329 | 'authority': 'www.douyin.com', 330 | 'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7', 331 | 'accept-language': 'zh-CN,zh;q=0.9,en;q=0.8', 332 | 'cache-control': 'no-cache', 333 | 'cookie': ' __ac_referer=https://www.douyin.com/video/7379445613236079884; __ac_nonce=06669a9f400ce1f28e533; ttwid=1%7C9Nz_KEuk-HKcdjb9PLTwePqzYubKPZXb_GfFU3HJ81U%7C1718200820%7C731492e777335f70a2978690c9a94a5094483538894c6d260748c00bc767bc04; s_v_web_id=; dy_swidth=1536;', 334 | 'pragma': 'no-cache', 335 | 'referer': 'https://www.douyin.com/video/7379445613236079884', 336 | 'sec-ch-ua': '"Not A(Brand";v="99", "Google Chrome";v="121", "Chromium";v="121"', 337 | 'sec-ch-ua-mobile': '?0', 338 | 'sec-ch-ua-platform': '"Windows"', 339 | 'sec-fetch-dest': 'document', 340 | 'sec-fetch-mode': 'navigate', 341 | 'sec-fetch-site': 'same-origin', 342 | 'sec-fetch-user': '?1', 343 | 'upgrade-insecure-requests': '1', 344 | 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36', 345 | } 346 | 347 | response = requests.get('https://www.douyin.com/video/7379445613236079884', headers=headers).text 348 | 349 | # print(response.text) 350 | # print(response.headers) 351 | # exit() 352 | # base64_data = response.headers.get('x-vc-bdturing-parameters') 353 | # dd=json.loads(base64.b64decode(base64_data).decode()) 354 | # detail=dd['detail'] 355 | # fp=dd['fp'] 356 | detail = re.findall('"detail":"(.*?)"', response)[0] 357 | fp = re.findall('"fp":"(.*?)"', response)[0] 358 | result = Dy('').run( 359 | detail,fp, 'slide') 360 | print(result) 361 | 362 | 363 | 364 | --------------------------------------------------------------------------------