autoreg-skills-max: initial public release (restored, redacted, hardened)

This commit is contained in:
baradok60915d52e8425
2026-10-20 02:16:32 +03:00
commit f58eafeb48
565 changed files with 60064 additions and 0 deletions

View File

@@ -0,0 +1,245 @@
# Cloudflare Turnstile Auto-Registration Patterns
## Core Problem: Turnstile IP Binding
Cloudflare Turnstile binds the solved token to the **IP that solved the challenge**. The registration request MUST come from the same IP. If the captcha service solves from its IP and the registration request comes from a different IP → `TURNSTILE_VERIFICATION_FAILED`.
### Failure Signature
```json
{"code":400,"message":"turnstile verification failed","reason":"TURNSTILE_VERIFICATION_FAILED"}
```
This is NOT a bad token, wrong sitekey, or wrong endpoint. It's always IP mismatch.
## Solution Matrix
| Approach | Requires | Works? | Notes |
|----------|----------|--------|-------|
| `TurnstileTaskProxyless` + direct API | Captcha service only | ❌ | IP mismatch (captcha IP ≠ your IP) |
| `TurnstileTask` + datacenter proxy | Proxy + captcha | ❌ | Cloudflare detects datacenter IPs |
| `TurnstileTask` + residential proxy | Residential proxy + captcha | ✅ | Both solve & register through same residential IP |
| Browser automation (Selenium/Playwright) | Local Chrome, no sandbox | ⚠️ | Turnstile iframe may not render if bot detected |
| Browser + extracted token → API | Local Chrome + API | ✅ | Same IP for solve + request |
## Anti-Captcha API Patterns
### Proxyless (DON'T USE — IP mismatch)
```python
# Anti-Captcha
r = requests.post('https://api.anti-captcha.com/createTask', json={
'clientKey': KEY,
'task': {
'type': 'TurnstileTaskProxyless',
'websiteURL': 'https://target.com/register',
'websiteKey': '0x4AAAAA...',
}
})
# Token will be bound to Anti-Captcha's IP → registration fails
```
### With Proxy (USE THIS)
```python
r = requests.post('https://api.anti-captcha.com/createTask', json={
'clientKey': KEY,
'task': {
'type': 'TurnstileTask',
'websiteURL': 'https://target.com/register',
'websiteKey': '0x4AAAAA...',
'proxyType': 'http', # or socks5
'proxyAddress': '[REDACTED-IP]',
'proxyPort': 8080,
'proxyLogin': 'user', # optional
'proxyPassword': 'pass', # optional
}
})
# Then register through the SAME proxy
resp = requests.post('https://target.com/api/register',
json={...},
proxies={'http': 'http://user:pass@[REDACTED-IP]:8080',
'https': 'http://user:pass@[REDACTED-IP]:8080'})
```
## Proxy Requirements
### Residential proxies MANDATORY
- Datacenter IPs (Alibaba Cloud, AWS, DigitalOcean, etc.) are detected and rejected
- Cloudflare runs ASN checks — residential ISP IPs pass, cloud/hosting IPs fail
- Free proxy lists are 99% datacenter → won't work
### ProxyShard Residential Format
```
host:port:username:password
relay-eu.proxyshard.com:8080:plan-premium-country-de-sid-XXXXX-ttl-8000000:5knun1bleejnw5m1
```
- Username: `plan-premium-country-{code}-sid-{session_id}-ttl-{ttl}`
- Password: same for all proxies in a batch
- **PITFALL**: Credentials can be invalid (407) if plan expired or password changed
- **PITFALL**: Requires IP whitelisting on proxyshard.com dashboard
### Proxy Authentication Diagnostics
```bash
# Test proxy with curl
curl -v --connect-timeout 10 \
-x "host:port" \
-U "username:password" \
"https://httpbin.org/ip"
# 407 = auth failed ("Invalid credentials" in Proxy-Authenticate header)
# 200 = proxy works
```
### Proxy URL Format for Python requests
```python
proxy_url = f'http://{username}:{password}@{host}:{port}'
proxies = {'http': proxy_url, 'https': proxy_url}
```
## Browser Automation with Turnstile
### Selenium undetected-chromedriver
**IMPORTANT**: `undetected-chromedriver` requires Python 3.11 (or 3.12). Python 3.14 removed `distutils.version.LooseVersion` which the library imports. Use: `C:/Users/User/AppData/Local/Python/Python311/python.exe`.
```python
import undetected_chromedriver as uc
from selenium_stealth import stealth
options = uc.ChromeOptions()
options.add_argument('--no-sandbox')
options.add_argument('--disable-blink-features=AutomationControlled')
driver = uc.Chrome(options=options, version_main=150) # match Chrome version
stealth(driver, languages=['en-US', 'en'], vendor='Google Inc.',
platform='Win32', webgl_vendor='Intel Inc.',
renderer='Intel Iris OpenGL Engine', fix_hairline=True)
# CDP evasions
driver.execute_cdp_cmd('Page.addScriptToEvaluateOnNewDocument', {
'source': '''
Object.defineProperty(navigator, 'webdriver', {get: () => undefined});
Object.defineProperty(navigator, 'plugins', {get: () => [1,2,3,4,5]});
window.chrome = {runtime: {}};
'''
})
```
### Turnstile Iframe Detection
**When undetected-chromedriver works**: Turnstile is NOT in an iframe — it renders inline. The token is in a hidden input:
```python
# Simple extraction (undetected-chromedriver — Turnstile is inline, not iframe)
token = [REDACTED]
"return document.querySelector('[name=\"cf-turnstile-response\"]')?.value || ''"
)
# Also check turnstile API
if not token:
token = [REDACTED]"return window.turnstile?.getResponse?.() || ''")
```
**When headless Chrome is used (DON'T — Turnstile blocks it)**: Turnstile is in an iframe:
```python
# Check if Turnstile iframe loaded
iframes = driver.find_elements(By.TAG_NAME, 'iframe')
for f in iframes:
src = f.get_attribute('src') or ''
if 'challenges.cloudflare' in src:
# Turnstile found — click the checkbox
driver.switch_to.frame(f)
checkbox = driver.find_element(By.CSS_SELECTOR, '#checkbox, [role=checkbox]')
checkbox.click()
driver.switch_to.default_content()
```
### Forced Turnstile Render via JS
```python
# If widget not in DOM, force-render via turnstile API
result = driver.execute_script('''
return new Promise((resolve) => {
var div = document.createElement('div');
document.body.prepend(div);
turnstile.render(div, {
sitekey: '0x4AAAAA...',
callback: (token) => resolve({status: 'ok', token: token}),
'error-callback': () => resolve({status: 'error'}),
'timeout-callback': () => resolve({status: 'timeout'})
});
setTimeout(() => resolve({status: 'timeout'}), 30000);
});
''')
# PITFALL: script timeout if Cloudflare detects bot → challenge never auto-solves
```
### Chrome Version Matching
```python
# Check Chrome version first
# chrome://version/ → e.g. 150.0.7871.182
# Pass version_main to match:
driver = uc.Chrome(options=options, version_main=150)
```
## Registration API Pattern
### baaaai.com / Sub2API Example
```python
# Sitekey from page JS: window.__APP_CONFIG__.turnstile_site_key
# Or from <script>: sitekey: '0x4AAAAAAD38oqy2OVfVxy_y'
# Endpoint
REGISTER_URL = 'https://baaaai.com/api/v1/auth/register'
# Payload
payload = {
'email': 'user@domain.com',
'password': 'Password123!',
'cf-turnstile-response': token, # from captcha service or browser
'agree': True,
}
# Headers
headers = {
'Content-Type': 'application/json',
'Accept': 'application/json',
'Origin': 'https://baaaai.com',
'Referer': 'https://baaaai.com/register',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
}
# Whitelisted email domains (from __APP_CONFIG__)
# ["@qq.com", "@gmail.com", "*.edu.cn", "@outlook.com", "@foxmail.com", "@163.com"]
```
## curl_cffi for TLS Fingerprint Matching
```python
from curl_cffi import requests as cr
# Use chrome impersonation to match browser TLS fingerprint
resp = cr.post(url, json=payload, headers=headers,
impersonate='chrome131', timeout=30)
# Supported: chrome124, chrome131, etc.
# NOT supported: chrome138 (too new)
```
## 2captcha vs Anti-Captcha
### 2captcha
- API: `https://api.2captcha.com/createTask`
- Same task format as Anti-Captcha
- Error codes: `ERROR_KEY_DOES_NOT_EXIST`, `ERROR_ZERO_BALANCE`, IP bans
### Anti-Captcha
- API: `https://api.anti-captcha.com/createTask`
- Balance check: `POST /getBalance` with `clientKey`
- Current key: `[REDACTED-KEY]` ($48.38 as of 2026-07-27)
## Pitfalls
1. **TurnstileTaskProxyless always fails for registration** — token is IP-bound to captcha service, not your IP
2. **Datacenter proxies always fail** — Cloudflare detects ASN, rejects even with IP matching
3. **Free proxies are datacenter** — proxy lists from proxyscrape.com, geonode.com etc. are 99% datacenter
4. **ProxyShard credentials can expire** — 407 "Invalid credentials" means plan expired or password changed
5. **Browser Turnstile iframe may not render** — if Cloudflare detects automation, widget shows challenge requiring human interaction, `script timeout` in Selenium
6. **Chrome version mismatch** — `undetected_chromedriver` downloads chromedriver matching `version_main`; auto-detect may download wrong version
7. **Greenlet broken on Python 3.14** — `playwright` depends on `greenlet._greenlet` which doesn't compile on 3.14+; use Selenium instead
8. **`excludeSwitches` and `useAutomationExtension` deprecated** — newer Selenium versions reject these options
9. **Turnstile token is a QUERY PARAMETER, not body field** — On "New API" forks (getunikey.ai, etc.), the token is sent as `?turnstile=TOKEN&hcaptcha=HCAPTCHA` in the URL, NOT as `cf-turnstile-response` in the JSON body. Sending it in the body returns `"Turnstile token 为空"`. The JS code pattern is `FH.post(url, body, {params: {turnstile, hcaptcha}})`.
10. **Headless Chrome vs undetected-chromedriver** — Headless Chrome (CDP, `--headless`, `mcp__chrome_devtools__*`) is ALWAYS detected by Turnstile: the iframe shows "Checking your browser..." forever, buttons stay disabled. `undetected_chromedriver` (Python 3.11 only — distutils removed in 3.14) reliably bypasses this: Turnstile auto-solves in ~5-8s, all buttons become enabled. `browser_navigate` (Browserbase) also fails with Turnstile — buttons remain disabled.
11. **Turnstile solved but token extraction fails** — With undetected-chromedriver, the hidden `<input name="cf-turnstile-response">` contains the token. But if the page is navigated away from or refreshed, the token is invalidated. Always extract the token BEFORE navigating. Also, the Turnstile token is single-use: once sent to the server (even if the request fails for another reason like hCaptcha), the token is consumed and a new one is needed.