File size: 13,637 Bytes
89419ea | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 | # HTTP-Only 注册链路反检测 — 最终完整修复建议
> **版本**:v3 全量版(合并 3 轮分析)
> **方法论**:逐行代码审计 + 真实 Chrome 行为对照 + codex-suite-win 参考实现对比 + 防御者视角 10 维度 threat model
> **范围**:覆盖外壳层(HTTP/TLS)、行为层(时序/流量形状)、内核层(Sentinel PoW 载荷)
---
## 检测维度总览
```
┌─ 外壳层(HTTP 请求长什么样)──────────────────────────────┐
│ TLS/H2 指纹 · HTTP headers · Client Hints · sec-fetch-* │
│ traceparent/datadog · 首请求导航特征 │
├─ 行为层(请求的节奏和模式)──────────────────────────────┤
│ 步骤间延迟 · 流量入口形状 · 跨账号统计关联 │
│ 密码/名字/生日的统计指纹 │
├─ 内核层(PoW token 里嵌的环境数据)──────────────────────┤
│ 时区 vs IP 地理 · 语言签名 vs Accept-Language │
│ 屏幕分辨率 · navigator/window 属性池 · 哈希算法版本 │
└──────────────────────────────────────────────────────────┘
```
---
## 注册链路完整请求地图
| # | 端点 | 代码位置 | headers 来源 |
|---|---|---|---|
| ① | `GET auth.openai.com/oauth/authorize?...` | `register.py:248` | **无自定义 headers** |
| ② | `POST sentinel.openai.com/backend-api/sentinel/req` | `http_client.py:374` | origin + referer + content-type |
| ③ | `POST auth.openai.com/api/accounts/authorize/continue` | `register.py:372` | referer + accept + content-type + sentinel |
| ④ | `POST auth.openai.com/api/accounts/password/verify` | `register.py:457` | **裸 headers** |
| ⑤ | `POST auth.openai.com/api/accounts/email-otp/validate` | `register.py:2193` | **裸 headers** |
| ⑥ | `POST auth.openai.com/api/accounts/create_account` | `register.py:2281` | **裸 headers** |
| ⑦ | `POST auth.openai.com/oauth/token` | `oauth.py:160` | **独立一次性会话** |
---
## 全部问题清单与优先级
### 🔴 P0 — 立即修复(每项都是可被直接检测的暴露点)
---
#### P0-1. Sentinel PoW 语言签名 vs Accept-Language 矛盾
**代码位置**:`sentinel.py:18` vs `http_client.py:261`
```python
# sentinel.py — PoW 内部声称浏览器语言
_LANGUAGE_SIGNATURE = "en-US,es-US,en,es" # ← 包含西班牙语
# http_client.py — HTTP 请求头
"Accept-Language": "en-US,en;q=0.9" # ← 只有英语
```
**问题**:同一个浏览器的语言配置在 PoW 载荷和 HTTP 请求中对不上。服务端解码 PoW 后可直接比对。
**修复**:统一为 `"en-US,en"` 或从 BrowserProfile 中读取。
**工时**:5 分钟
---
#### P0-2. Sentinel PoW 时区硬编码 EST,与代理 IP 地理位置冲突
**代码位置**:`sentinel.py:29`
```python
browser_now = datetime.now(timezone(timedelta(hours=-5)))
# → "GMT-0500 (Eastern Standard Time)"
```
**问题**:PoW 永远声称浏览器在美东时区。如果代理 IP 在欧洲/亚洲,IP 地理位置 vs PoW 时区 = 矛盾。
**修复**:改用 UTC(`time.gmtime()` + `"GMT+0000 (Coordinated Universal Time)"`),和 codex-suite-win 保持一致。UTC 不暴露地理位置。
**工时**:5 分钟
---
#### P0-3. Sentinel PoW 屏幕分辨率不是真实值
**代码位置**:`sentinel.py:17`
```python
_SCREEN_SIGNATURES = (3000, 3120, 4000, 4160)
# 没有任何真实显示器是这些分辨率
```
**修复**:替换为真实常见值,如 `"1920x1080"`、`"2560x1440"`、`"1366x768"`。codex-suite-win 使用 `"1920x1080"`。
**工时**:5 分钟
---
#### P0-4. impersonate 版本与 User-Agent 版本分裂
**代码位置**:`http_client.py:29` + `http_client.py:258`
```python
impersonate: str = "chrome" # → TLS 层 = 最新 Chrome (131+)
"User-Agent": "...Chrome/120.0.0.0..." # → 应用层 = Chrome 120
```
**问题**:TLS ClientHello 的指纹对应 Chrome 131+,但 UA 声称 Chrome 120。
**修复**:建立 BrowserProfile 工厂,绑定 `impersonate` 版本与 UA/sec-ch-ua:
```python
_CHROME_PROFILES = [
{"impersonate": "chrome120", "major": 120, "build": 6099,
"sec_ch_ua": '"Not_A Brand";v="8", "Chromium";v="120", "Google Chrome";v="120"'},
{"impersonate": "chrome131", "major": 131, "build": 6778,
"sec_ch_ua": '"Google Chrome";v="131", "Chromium";v="131", "Not_A Brand";v="24"'},
# 按需扩展
]
```
**工时**:1 小时
---
#### P0-5. 所有请求缺少 sec-ch-ua 三件套
**代码位置**:整个 `src/` 目录 — 零个 `sec-ch-ua`
Chrome 从 2021 年起**每个 HTTPS 请求默认发送**:
```
sec-ch-ua: "Chromium";v="120", "Google Chrome";v="120", "Not_A Brand";v="8"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
```
你的 7 个请求阶段全部缺失。声称是 Chrome 但不发 Chrome 默认 headers = 最基本的检测信号。
**修复**:包含在 P0-4 的 BrowserProfile 中。
**工时**:含在 P0-4 中
---
#### P0-6. 注册流程零延迟,全链路 < 2 秒完成
**代码位置**:`register.py` 全流程
7 个 HTTP 请求之间没有任何 `time.sleep()`,请求背靠背发出。真实用户从打开注册页到完成至少 30-120 秒。
**修复**:在关键步骤间加入正态分布延迟:
```python
import random, time
def _human_delay(mean=3.0, std=1.0, minimum=1.0):
delay = max(random.gauss(mean, std), minimum)
time.sleep(delay)
```
- `_get_device_id` → `_check_sentinel`:延迟 1-3秒
- `_submit_auth_start` → `_submit_login_password`:延迟 2-5秒("用户在输密码")
- `_validate_verification_code`:延迟 5-15秒("用户在等验证码邮件")
- `_create_user_account`:延迟 2-4秒("用户在填姓名和生日")
**工时**:30 分钟
---
#### P0-7. 阶段 ④⑤⑥ 的 headers 风格与 ③ 不一致
**代码位置**:`register.py:459`、`register.py:2195`、`register.py:2283`
`password_verify`、`validate_otp`、`create_account` 只有 3 行最小 headers(referer + accept + content-type),缺少:
- `origin`
- `oai-device-id`
- `sec-ch-ua` 三件套
- `sec-fetch-*` 三件套
同一会话中 ③ 带了 sentinel 和更多 headers,④⑤⑥ 突然"简化" = header 风格突变。
**修复**:统一使用 `profile.json_request_headers(referer)` 构建,至少加 `origin` 和 `sec-fetch-*`。
**工时**:30 分钟
---
### 🟡 P1 — 建议修复(降低检测风险、提高耐久性)
---
#### P1-1. traceparent 与 x-datadog-trace-id 值不一致
**代码位置**:`register.py:279-288`
`traceparent` 用 `uuid4().hex` 做 trace-id,`x-datadog-trace-id` 用另一个随机十进制数。两者必须对应同一个 trace。当前实现比不发更糟糕。
**修复**:**推荐直接移除**这些 headers。如需保留,从同一 trace-id 派生:
```python
trace_id_hex = uuid.uuid4().hex
dd_trace_id = int(trace_id_hex[16:], 16) # 低64位转十进制
```
**工时**:15 分钟
---
#### P1-2. 密码无特殊字符,批量可指纹
**代码位置**:`constants.py:179`
```python
PASSWORD_CHARSET = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
# → 所有账号密码 = [a-zA-Z0-9]{12},无特殊字符
```
同一 IP 注册的所有账号密码都是相同字符集和长度,统计可识别。
**修复**:
```python
PASSWORD_CHARSET = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%&*"
DEFAULT_PASSWORD_LENGTH = random.randint(12, 16)
# 确保至少包含 1 特殊字符
```
**工时**:10 分钟
---
#### P1-3. Name 只有名没有姓
**代码位置**:`constants.py:201`
```python
name = random.choice(FIRST_NAMES) # → "James"(无姓)
```
OpenAI about-you 页面要的是 Full Name,只有一个词极罕见。
**修复**:加 LAST_NAMES 列表,生成 `"James Smith"` 格式。
**工时**:10 分钟
---
#### P1-4. 首请求(_get_device_id)无浏览器导航 headers
**代码位置**:`register.py:248`
```python
response = self.session.get(self.oauth_start.auth_url, timeout=20)
# ← 没有 Accept, 没有 Upgrade-Insecure-Requests, 没有 sec-fetch-*
```
真实浏览器导航到页面时的 headers:
```
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Upgrade-Insecure-Requests: 1
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: none
Sec-Fetch-User: ?1
```
**修复**:补上导航请求标准 headers。
**工时**:10 分钟
---
#### P1-5. Sentinel navigator/window 属性池太小
**代码位置**:`sentinel.py:19-20`
```python
_NAVIGATOR_KEYS = ("location", "ontransitionend", "onprogress") # 3 个
_WINDOW_KEYS = ("window", "document", "navigator") # 3 个
```
codex-suite-win 有 21 个 navigator 属性、6 个 window 属性。你的 3 个会导致多次注册中频繁重复。
**修复**:扩展到至少 15+ 个真实 Chrome navigator 属性。
**工时**:15 分钟
---
#### P1-6. Sentinel 请求缺 sec-ch-ua 和 sec-fetch-*
**代码位置**:`http_client.py:376-380`
Sentinel 请求只有 origin/referer/content-type,缺少浏览器标准 headers。
**修复**:补 `sec-ch-ua` 三件套 + `sec-fetch-dest: empty` + `sec-fetch-mode: cors` + `sec-fetch-site: cross-site`。
**工时**:10 分钟
---
#### P1-7. Sentinel PoW 哈希算法可能不匹配当前版本
**代码位置**:`sentinel.py:82`
你用 SHA3-512,codex-suite-win 用 FNV-1a。这是两种不同的 challenge 协议。需要验证当前 OpenAI 注册链路使用的是哪个版本。
**修复**:抓包确认 sentinel/req 响应中的 challenge 格式。如果 OpenAI 已升级,需要更新哈希算法。
**工时**:1-2 小时(含调研)
---
#### P1-8. 注册入口跳过 chatgpt.com 前端
你的流程直接 GET `auth.openai.com/oauth/authorize`,跳过了真实用户的路径:`chatgpt.com → CSRF → signin/openai → 跳转到 auth`。
**修复**:模拟 chatgpt.com 入口流,注入 `ext-oai-did` + `auth_session_logging_id`。
**工时**:2-3 小时
---
### ⚪ P2 — 灰度验证(长期增强)
---
#### P2-1. 跨账号统计关联
同一 IP 批量注册时,所有账号共享:单一 Chrome 版本、相同密码字符集/长度、相同名字池、相同 TLS 指纹、相同注册耗时。
**修复**:通过 P0-4(多版本 Profile 池)+ P1-2(密码多样化)+ P1-3(名字多样化)+ P0-6(延迟随机化)综合缓解。
---
#### P2-2. OAuth token exchange 使用独立会话
`oauth.py:160` 使用 `cffi_requests.post` 而非 `self.session.post`,不携带前面的 cookies。
**修复**:改为使用主会话发送 token exchange 请求。
**工时**:30 分钟
---
#### P2-3. 出生年份均匀分布
```python
birth_year = random.randint(current_year - 45, current_year - 18)
# → 均匀分布,但真人年龄是正态分布
```
**修复**:改为正态分布 `int(random.gauss(28, 6))`,限制在 18-45 岁。
**工时**:10 分钟
---
#### P2-4. ext-oai-did / auth_session_logging_id
codex-suite-win 在 signin 时注入这两个参数,你的项目没有。
**修复**:在 OAuth 入口流中补充。
**工时**:含在 P1-8 中
---
## 修复依赖图与落地顺序
```mermaid
graph TD
A["P0-4 BrowserProfile 工厂"] --> B["P0-5 sec-ch-ua 全覆盖"]
A --> C["P0-7 统一 header 构建"]
A --> D["P1-6 Sentinel 补 headers"]
A --> G["P1-4 首请求导航 headers"]
E["P0-1 PoW 语言签名"] --> |独立| E
F["P0-2 PoW 时区"] --> |独立| F
H["P0-3 PoW 屏幕分辨率"] --> |独立| H
I["P0-6 步骤间延迟"] --> |独立| I
C --> J["P1-1 移除 traceparent"]
K["P1-2 密码特殊字符"] --> |独立| K
L["P1-3 Name 加姓"] --> |独立| L
```
### 推荐执行顺序
| 批次 | 内容 | 总工时 | 效果 |
|---|---|---|---|
| **第 1 批** | P0-1 + P0-2 + P0-3(PoW 内部 3 个矛盾) | 15 分钟 | 消除 PoW 载荷的内部自相矛盾 |
| **第 2 批** | P0-6(加延迟) + P1-2(密码)+ P1-3(姓名) | 50 分钟 | 消除行为层最明显的批量特征 |
| **第 3 批** | P0-4 + P0-5(BrowserProfile + sec-ch-ua) | 1 小时 | 消除 TLS/UA 分裂和 Client Hints 缺失 |
| **第 4 批** | P0-7 + P1-4 + P1-6(统一 headers) | 50 分钟 | 消除 header 风格突变 |
| **第 5 批** | P1-1 + P1-5 + P1-7 | 2.5 小时 | 清理 traceparent / 扩展 PoW 属性池 / 确认哈希算法 |
| **第 6 批** | P1-8 + P2-*(入口流 + 灰度项) | 3-4 小时 | 流量形状对齐 |
---
## 修复后的覆盖率预估
| 侦察维度 | 修复前 | 第 1-2 批后 | 第 3-4 批后 | 全部完成后 |
|---|---|---|---|---|
| TLS/HTTP2 指纹 | ⚠️ 版本不匹配 | ⚠️ | ✅ | ✅ |
| HTTP headers 一致性 | ❌ 3 个裸端点 | ❌ | ✅ | ✅ |
| Client Hints | ❌ 零个 | ❌ | ✅ | ✅ |
| Datadog 追踪头 | ❌ 值矛盾 | ❌ | ❌ | ✅ |
| 请求时序/节奏 | ❌ 零延迟 | ✅ | ✅ | ✅ |
| 流量入口形状 | ❌ 跳过前端 | ❌ | ❌ | ✅ |
| 账号数据统计模式 | ❌ 批量可指纹 | ✅ | ✅ | ✅ |
| 首请求导航特征 | ❌ 无 headers | ❌ | ✅ | ✅ |
| PoW 内部环境一致性 | ❌ 3 处矛盾 | ✅ | ✅ | ✅ |
| 跨账号统计关联 | ❌ 单一 profile | ⚠️ | ✅ | ✅ |
|