feat: Implement Telegram bot with Claude authentication, mail service, and identity spoofing, refactoring core logic into new modules.

This commit is contained in:
2026-02-12 22:16:17 +08:00
parent 02d70ac3cd
commit ad7b6196dc
14 changed files with 1577 additions and 470 deletions

172
claude_auth.py Normal file
View File

@@ -0,0 +1,172 @@
import uuid
import base64
from curl_cffi import requests # 用于模拟指纹
from config import CLAUDE_URL
from models import ClaudeAccount
from identity import random_ua
def attack_claude(target_email):
"""伪装成浏览器发起攻击"""
device_id = str(uuid.uuid4())
ua = random_ua()
headers = {
"Host": "claude.ai",
"Anthropic-Anonymous-Id": f"claudeai.v1.{uuid.uuid4()}",
"Sec-Ch-Ua-Full-Version-List": '"Google Chrome";v="143.0.7499.105", "Chromium";v="143.0.7499.105", "Not A(Brand";v="24.0.0.0"',
"Sec-Ch-Ua-Platform": '"Linux"',
"Sec-Ch-Ua": '"Google Chrome";v="143", "Chromium";v="143", "Not A(Brand";v="24"',
"Baggage": "sentry-environment=production,sentry-release=ce5600af514463a166f4cd356a6afbc46ee5cd3d,sentry-public_key=58e9b9d0fc244061a1b54fe288b0e483,sentry-trace_id=7bdc872994f347d6b5a610a520f40401,sentry-org_id=1158394",
"Anthropic-Client-Sha": "ce5600af514463a166f4cd356a6afbc46ee5cd3d",
"Content-Type": "application/json",
"Anthropic-Client-Platform": "web_claude_ai",
"Anthropic-Device-Id": device_id,
"Anthropic-Client-Version": "1.0.0",
"User-Agent": ua,
"Origin": "https://claude.ai",
"Referer": "https://claude.ai/login?returnTo=%2Fonboarding",
"Accept-Encoding": "gzip, deflate, br",
"Accept-Language": "zh-CN,zh;q=0.9",
"Priority": "u=1, i"
}
payload = {
"utc_offset": -480,
"email_address": target_email,
"login_intent": None,
"locale": "en-US",
"oauth_client_id": None,
"source": "claude"
}
try:
print(f"[*] 正在向 Claude 发送 Magic Link 请求: {target_email}")
session = requests.Session()
response = session.post(
CLAUDE_URL,
json=payload,
headers=headers,
impersonate="chrome124"
)
if response.status_code == 200:
print("[+] 请求成功Claude 已发信。")
return True
elif response.status_code == 429:
print("[-] 被限流了 (Rate Limited)。")
else:
print(f"[-] 请求失败 Code: {response.status_code}, Body: {response.text}")
except Exception as e:
print(f"[-] 发生异常: {e}")
return False
def finalize_login(magic_link_fragment):
"""
完成最后一步:无需浏览器,直接交换 sessionKey。
magic_link_fragment 格式: https://claude.ai/magic-link#token:base64_email
返回 ClaudeAccount 对象
"""
# 1. 外科手术式拆解 Hash
if '#' in magic_link_fragment:
fragment = magic_link_fragment.split('#')[1]
else:
fragment = magic_link_fragment
if ':' not in fragment:
print("[-] 链接格式错误: 找不到 token 和 email 的分隔符")
return None
# 分割 nonce 和 base64_email
nonce, encoded_email = fragment.split(':', 1)
try:
decoded_email = base64.b64decode(encoded_email).decode('utf-8')
print(f"[*] 解析成功 -> Email: {decoded_email} | Nonce: {nonce[:8]}...")
except:
print(f"[*] 解析成功 -> Nonce: {nonce[:8]}...")
# 2. 构造最终 payload
verify_url = "https://claude.ai/api/auth/verify_magic_link"
payload = {
"credentials": {
"method": "nonce",
"nonce": nonce,
"encoded_email_address": encoded_email
},
"locale": "en-US",
"oauth_client_id": None,
"source": "claude"
}
# 3. 伪造指纹头
device_id = str(uuid.uuid4())
ua = random_ua()
headers = {
"Host": "claude.ai",
"Content-Type": "application/json",
"Origin": "https://claude.ai",
"Referer": "https://claude.ai/magic-link",
"User-Agent": ua,
"Accept": "*/*",
"Accept-Language": "zh-CN,zh;q=0.9",
"Anthropic-Client-Version": "1.0.0",
"Anthropic-Client-Platform": "web_claude_ai",
"Anthropic-Device-Id": device_id,
"Sec-Fetch-Dest": "empty",
"Sec-Fetch-Mode": "cors",
"Sec-Fetch-Site": "same-origin",
"Priority": "u=1, i"
}
try:
print(f"[*] 正在交换 SessionKey...")
session = requests.Session()
response = session.post(
verify_url,
json=payload,
headers=headers,
impersonate="chrome124"
)
if response.status_code == 200:
data = response.json()
# 1. 提取 SessionKey
session_key = response.cookies.get("sessionKey")
if not session_key:
for name, value in response.cookies.items():
if name == "sessionKey":
session_key = value
break
if not session_key:
print("[-] 请求成功 (200),但未在 Cookie 中找到 sessionKey。")
print(f"Response: {str(data)[:200]}...")
return None
# 2. 提取 Org UUID
try:
org_uuid = data['account']['memberships'][0]['organization']['uuid']
email = data['account']['email_address']
print(f"[+] 登录成功。OrgID: {org_uuid}")
return ClaudeAccount(email, session_key, org_uuid, ua)
except KeyError as e:
print(f"[-] 无法提取 Organization UUID结构可能变了: {e}")
print(f"Response keys: {data.keys() if isinstance(data, dict) else type(data)}")
return None
else:
print(f"[-] 交换失败 Code: {response.status_code}")
print(f"Body: {response.text}")
return None
except Exception as e:
print(f"[-] 发生异常: {e}")
return None