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 | ⚠️ | ✅ | ✅ |