207 lines
7.6 KiB
Markdown
207 lines
7.6 KiB
Markdown
# Steam Account Registration — Platform-Specific Techniques
|
|
|
|
Extends the `bulk-account-registration` pipeline with Steam-specific flows.
|
|
Covers the full lifecycle: form submission → reCAPTCHA v2 → email verification → Steam Guard activation.
|
|
|
|
## Key Differences from Generic Registration
|
|
|
|
Steam is NOT a typical REST API registration. It's a multi-step web form with:
|
|
- reCAPTCHA v2 (not Turnstile — use `RecaptchaV2TaskProxyless` on 2captcha)
|
|
- AJAX email availability check before form submission (`/join/ajaxverifyemail`)
|
|
- RSA-encrypted password submission for login (not for registration itself)
|
|
- Email verification code (5-char alphanumeric, NOT numeric)
|
|
- Optional Steam Guard mobile authenticator activation via `ITwoFactorService`
|
|
|
|
## Flow Overview
|
|
|
|
```
|
|
GET /join/ → extract sessionid cookie
|
|
↓
|
|
2captcha: solve reCAPTCHA v2 (sitekey: 6LdIFr0Z...)
|
|
↓
|
|
POST /join/ajaxverifyemail → check email availability
|
|
↓
|
|
POST /join/createaccount → submit form with g-recaptcha-response
|
|
↓
|
|
Poll email (IMAP/GuerrillaMail) → extract 5-char Steam Guard code
|
|
↓
|
|
(Optional) POST /steamguard/add_ajax → activate mobile authenticator
|
|
↓
|
|
(Optional) ITwoFactorService/AddAuthenticator → extract shared_secret
|
|
```
|
|
|
|
## reCAPTCHA v2 on Steam
|
|
|
|
Steam uses reCAPTCHA v2 (checkbox), NOT Turnstile and NOT invisible reCAPTCHA.
|
|
|
|
**Sitekey**: `6LdIFr0ZAAAAAO3vz0O0OQOyjusTBucR2cwXTO4n`
|
|
**Page URL**: `https://store.steampowered.com/join/`
|
|
|
|
**2captcha solve** (via `createTask` API, not legacy `in.php`):
|
|
```python
|
|
payload = {
|
|
"clientKey": "YOUR_2CAPTCHA_KEY",
|
|
"task": {
|
|
"type": "RecaptchaV2TaskProxyless",
|
|
"websiteURL": "https://store.steampowered.com/join/",
|
|
"websiteKey": "6LdIFr0ZAAAAAO3vz0O0OQOyjusTBucR2cwXTO4n",
|
|
"isInvisible": False,
|
|
}
|
|
}
|
|
# POST https://api.2captcha.com/createTask → poll /getTaskResult
|
|
# Solution field: solution.gRecaptchaResponse
|
|
```
|
|
|
|
**Difference from Turnstile**: Turnstile uses `method=turnstile` on legacy API with `sitekey` and `pageurl` params. reCAPTCHA v2 uses `RecaptchaV2TaskProxyless` on the `createTask` JSON API. Do NOT use Turnstile method for Steam — it's reCAPTCHA.
|
|
|
|
## Form Submission Details
|
|
|
|
### Email Availability Check
|
|
```
|
|
POST https://store.steampowered.com/join/ajaxverifyemail
|
|
Data: email=user@domain.com&sessionid=<sessionid>
|
|
Headers: X-Requested-With: XMLHttpRequest, Referer: .../join/
|
|
Response: {"bEmailAvailable": true} or false
|
|
```
|
|
|
|
### Account Creation
|
|
```
|
|
POST https://store.steampowered.com/join/createaccount
|
|
Data:
|
|
accountname=<username>
|
|
password=<password>
|
|
email=<email>
|
|
email_confirm=<email>
|
|
captchagid=-1
|
|
captcha_text=
|
|
iAgree=1
|
|
ticket=
|
|
g-recaptcha-response=<2captcha_token>
|
|
count=7 # country code (7=US)
|
|
l=english
|
|
creation_sessionid=<sessionid>
|
|
```
|
|
|
|
No RSA encryption needed for registration — that's only for login.
|
|
|
|
## RSA Password Encryption (Login Only)
|
|
|
|
When logging into an existing account, Steam requires RSA-encrypted passwords:
|
|
|
|
```python
|
|
# 1. Get RSA key
|
|
POST https://store.steampowered.com/login/getrsakey/
|
|
Data: username=<username>&donotcache=<timestamp_ms>
|
|
Response: {"success": true, "publickey_mod": "<hex>", "publickey_exp": "<hex>", "timestamp": "<ts>"}
|
|
|
|
# 2. Encrypt password (PKCS1 v1.5)
|
|
mod = int(publickey_mod, 16)
|
|
exp = int(publickey_exp, 16)
|
|
pw_int = int.from_bytes(password.encode("utf-8"), "big")
|
|
encrypted_int = pow(pw_int, exp, mod)
|
|
encrypted_b64 = base64.b64encode(encrypted_int.to_bytes(...))
|
|
|
|
# 3. Submit login
|
|
POST https://store.steampowered.com/login/dologin/
|
|
Data: username=...&password=<encrypted_b64>&rsatimestamp=<ts>&emailauth=<code>...
|
|
```
|
|
|
|
## Email Verification Code Extraction
|
|
|
|
Steam sends a 5-character alphanumeric code (uppercase letters + digits). Pattern:
|
|
```
|
|
re.search(r'\b([A-Z0-9]{5})\b', email_body)
|
|
```
|
|
|
|
The email comes from `noreply@steampowered.com` with subject containing "Steam Guard".
|
|
|
|
**IMAP search**:
|
|
```python
|
|
client.search(["FROM", "noreply@steampowered.com"])
|
|
client.search(["SUBJECT", "Steam Guard"])
|
|
```
|
|
|
|
**GuerrillaMail**: Subject line and body both contain the code. The `_extract_steam_code()` function handles HTML and plain text.
|
|
|
|
## Steam Guard Mobile Authenticator (TOTP)
|
|
|
|
Steam uses a custom TOTP implementation:
|
|
- **Algorithm**: HMAC-SHA1
|
|
- **Period**: 30 seconds
|
|
- **Digits**: 5
|
|
- **Alphabet**: `23456789BCDFGHJKMNPQRTVWXY` (no 0, 1, A, E, I, O, L, S, U, Z — avoids ambiguous characters)
|
|
|
|
### TOTP Generation
|
|
```python
|
|
import hmac, hashlib, base64, struct, time
|
|
|
|
def generate_steam_totp(shared_secret_b64: str, timestamp: int = None) -> str:
|
|
if timestamp is None:
|
|
timestamp = int(time.time())
|
|
secret = [REDACTED])
|
|
time_bytes = struct.pack(">Q", timestamp // 30)
|
|
hmac_result = hmac.new(secret, time_bytes, hashlib.sha1).digest()
|
|
offset = hmac_result[-1] & 0x0F
|
|
code_int = struct.unpack(">I", hmac_result[offset:offset + 4])[0] & 0x7FFFFFFF
|
|
steam_alphabet = "23456789BCDFGHJKMNPQRTVWXY"
|
|
code = ""
|
|
for _ in range(5):
|
|
code += steam_alphabet[code_int % len(steam_alphabet)]
|
|
code_int //= len(steam_alphabet)
|
|
return code
|
|
```
|
|
|
|
### Activating Steam Guard (extracting shared_secret)
|
|
|
|
**Endpoint 1** (community page):
|
|
```
|
|
POST https://steamcommunity.com/steamguard/add_ajax
|
|
Data: sessionid=...&op=add_authenticator&device_identifier=android:<uuid>&sms_phone_id=1&access_token=
|
|
[REDACTED] {"success": true, "shared_secret": "<base64>", "identity_secret": "<base64>", ...}
|
|
```
|
|
|
|
**Endpoint 2** (API — more reliable):
|
|
```
|
|
POST https://api.steampowered.com/ITwoFactorService/AddAuthenticator/v0001
|
|
Data: steamid=<steamid64>&authenticator_time=<server_time>&authenticator_type=1&device_identifier=<device_id>&sms_phone_id=1
|
|
|
|
# Then finalize:
|
|
POST https://api.steampowered.com/ITwoFactorService/FinalizeAddAuthenticator/v0001
|
|
Data: steamid=<steamid64>&authenticator_code=<generated_totp>&authenticator_time=<server_time>&activation_code=
|
|
```
|
|
|
|
**Device ID format**: `android:XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX` (lowercase hex UUID).
|
|
|
|
**Getting server time**:
|
|
```
|
|
POST https://api.steampowered.com/ITwoFactorService/QueryTime/v0001
|
|
Response: {"response": {"server_time": "1719600000"}}
|
|
```
|
|
|
|
## SteamID64 Retrieval
|
|
|
|
After login, SteamID64 appears in the URL: `https://steamcommunity.com/profiles/7656119XXXXXXXXXX/`
|
|
|
|
Or resolve custom URL:
|
|
```
|
|
GET https://api.steampowered.com/ISteamUser/ResolveVanityURL/v0001/?key=&vanityurl=<custom>
|
|
Response: {"response": {"steamid": "7656119XXXXXXXXXX", "success": 1}}
|
|
```
|
|
|
|
## Pitfalls
|
|
|
|
1. **Don't use Turnstile method for Steam** — it's reCAPTCHA v2. Wrong method = wasted 2captcha balance.
|
|
2. **Steam Guard code is 5 chars, NOT 6** — unlike most OTP systems. Regex `\d{6}` will miss it.
|
|
3. **RSA encryption is for LOGIN, not registration** — registration submits plaintext password.
|
|
4. **`sms_phone_id=1` skips SMS** — use this to avoid phone verification requirement.
|
|
5. **GuerrillaMail domains are blocked by some platforms but NOT Steam** — Steam accepts `@guerrillamail.com` addresses.
|
|
6. **Session cookies expire quickly** — complete the full flow (register → verify → guard) within 10 minutes or the session dies.
|
|
7. **Steam rate-limits registrations per IP** — use rotating proxies for batch creation. Minimum 30-90s between accounts from same IP.
|
|
8. **Email availability check is mandatory** — Steam won't accept the create form without a prior successful ajaxverifyemail call in the same session.
|
|
|
|
## See Also
|
|
|
|
- `bulk-account-registration` — general IMAP, proxy rotation, browser automation patterns
|
|
- `references/multi-provider-imap-servers.md` — IMAP server routing for reading Steam Guard emails
|
|
- `C:\Users\User\steam_registrar\steam_register.py` — complete working implementation
|