Cloudflare 的“我受到攻击模式”(IUAM) 是一种 DDoS 防御,强制每个访问者在访问网站之前接受 5 秒的 JavaScript 挑战。这是最激进的 Cloudflare 保护模式,由站点操作员在攻击期间手动触发或在高风险站点上永久启用。对于自动访问,IUAM 创建了传统 HTTP 客户端无法通过的强制性 JavaScript 挑战。
IUAM 的作用
当站点操作员在 Cloudflare 仪表板中启用“我处于攻击模式”时:
Every request → Cloudflare edge
↓
JavaScript challenge page served (HTTP 503)
↓
Browser executes JavaScript challenge (~5 seconds)
↓
Challenge answer submitted automatically
↓
qa_session_cookie cookie set
↓
Original page loaded with qa_session_cookie cookie
IIUAM 挑战页面
挑战页面返回 HTTP 503 并包含:
| 元素 | 目的 |
|---|---|
jschl_vc |
挑战验证码 |
pass |
计时令牌(强制 5 秒等待) |
jschl_answer |
JavaScript 计算的答案 |
cf_chl_opt |
挑战选项 |
ray |
请求的 Cloudflare Ray ID |
| “访问之前请检查您的浏览器...” | 对用户可见的消息 |
主要特点
- HTTP 503 状态代码(不是 403)
- 提交挑战前强制等待 5 秒
- 需要执行 JavaScript — 普通 HTTP 客户端失败
- qa_session_cookie cookie — 有效期约为 30 分钟,允许后续请求
- 全域 — 域中的每个页面都显示了挑战
识别 IUAM 与其他 Cloudflare 保护
import requests
def identify_cloudflare_protection(url):
"""Distinguish IUAM from other Cloudflare protections."""
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
"AppleWebKit/537.36 Chrome/120.0.0.0",
}
response = requests.get(url, headers=headers, timeout=15, allow_redirects=False)
html = response.text
status = response.status_code
if status == 503 and "jschl" in html:
return "IUAM (I'm Under Attack Mode)"
if status == 503 and "challenge-platform" in html:
return "Managed Challenge"
if status == 403 and "cf-ray" in str(response.headers):
return "Blocked by WAF/Bot Management"
if "cf-turnstile" in html:
return "Turnstile widget"
if "challenges.cloudflare.com" in html:
return "Cloudflare 验证流程 (generic)"
if status == 200:
return "No challenge (passed)"
return f"Unknown (status: {status})"
检测表
| 信号 | 国际原子能机构联合会 | 管理挑战 | 旋转门 | WAF区块 |
|---|---|---|---|---|
| HTTP 状态 | 503 | 503 | 200 | 403 |
正文中为jschl |
✅ | ❌ | ❌ | ❌ |
| 5秒等待 | ✅ | 有时 | ❌ | ❌ |
qa_session_cookie 设置 |
解决后 | 解决后 | ❌ | ❌ |
| 挑战页面 | 整页 | 整页 | 仅小部件 | 错误页面 |
| 需要JS | ✅ | ✅ | ✅ | ❌ |
JavaScript 挑战赛如何进行
IAUAM 的 JavaScript 挑战旨在验证访问者是否拥有真实的浏览器:
挑战流程
- Cloudflare 使用模糊的 JavaScript 提供挑战页面
- JavaScript 执行计算: - 对页面中的字符串进行数学运算 - DOM 测量 - 计时执行(至少 4-5 秒)
- 计算的答案 — 基于挑战的数值
- 使用
jschl_vc、pass和jschl_answer表单自动提交到 Cloudflare - Cloudflare 验证答案和时间安排
- 返回
qa_session_cookiecookie — 允许访问约 30 分钟
为什么 HTTP 客户端会失败
# This will ALWAYS get the challenge page:
import requests
response = requests.get("https://iuam-protected-site.com")
# response.status_code == 503
# response.text contains "Checking your browser..."
# Plain HTTP clients cannot:
# - Execute JavaScript
# - Compute the challenge answer
# - Meet the timing requirement
# - Generate the required cookies
使用CaptchaAI解决IUAM
方法一:Cloudflare 验证流程求解器(推荐)
CaptchaAI的cloudflare_challenge方法直接处理IUAM挑战:
import requests
import time
API_KEY = "YOUR_API_KEY"
TARGET_URL = "https://iuam-protected-site.com/data"
# Step 1: Submit challenge to CaptchaAI
submit = requests.post("https://ocr.captchaai.com/in.php", data={
"key": API_KEY,
"method": "cloudflare_challenge",
"sitekey": "managed",
"pageurl": TARGET_URL,
"json": 1,
})
task_id = submit.json()["request"]
print(f"Task submitted: {task_id}")
# Step 2: Poll for result
for attempt in range(60):
time.sleep(5)
result = requests.get("https://ocr.captchaai.com/res.php", params={
"key": API_KEY,
"action": "get",
"id": task_id,
"json": 1,
}).json()
if result.get("status") == 1:
token = result["request"]
print(f"Challenge solved! Token: {token[:50]}...")
break
elif result.get("request") == "ERROR_CAPTCHA_UNSOLVABLE":
print("Challenge could not be solved")
break
else:
print("Timed out waiting for solution")
# Step 3: Use qa_session_cookie cookie or token
# The response contains the clearance data needed to access the site
方法 2:使用 CaptchaAI 进行浏览器自动化
对于持久会话,请将无头浏览器与 CaptchaAI 结合起来:
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import requests
import time
API_KEY = "YOUR_API_KEY"
# Launch browser
options = webdriver.ChromeOptions()
options.add_argument("--no-sandbox")
driver = webdriver.Chrome(options=options)
# Navigate to IUAM page
driver.get("https://iuam-protected-site.com")
# Wait for challenge page to load
time.sleep(3)
# Check if IUAM challenge is present
if "Checking your browser" in driver.page_source or driver.title == "Just a moment...":
print("IUAM challenge detected")
# Option A: Wait for browser to solve natively (if not headless)
try:
WebDriverWait(driver, 15).until(
lambda d: "Checking your browser" not in d.page_source
)
print("Challenge passed natively")
except:
print("Native solve failed — using CaptchaAI")
# Submit to CaptchaAI for solving
# Token submission via JavaScript injection
# After challenge is passed, extract cookies for API use
cookies = driver.get_cookies()
qa_session_cookie = next(
(c["value"] for c in cookies if c["name"] == "qa_session_cookie"), None
)
if qa_session_cookie:
print(f"qa_session_cookie obtained: {qa_session_cookie[:30]}...")
# Use cookie with requests library
session = requests.Session()
for cookie in cookies:
session.cookies.set(cookie["name"], cookie["value"])
session.headers.update({
"User-Agent": driver.execute_script("return navigator.userAgent"),
})
# Now make requests with the clearance cookie
response = session.get("https://iuam-protected-site.com/api/data")
print(f"Status: {response.status_code}")
driver.quit()
Node.js
const axios = require("axios");
const API_KEY = "YOUR_API_KEY";
const TARGET_URL = "https://iuam-protected-site.com/data";
async function solveIUAM() {
// Submit challenge
const submit = await axios.post("https://ocr.captchaai.com/in.php", null, {
params: {
key: API_KEY,
method: "cloudflare_challenge",
sitekey: "managed",
pageurl: TARGET_URL,
json: 1,
},
});
const taskId = submit.data.request;
console.log(`Task submitted: ${taskId}`);
// Poll for result
for (let i = 0; i < 60; i++) {
await new Promise((r) => setTimeout(r, 5000));
const result = await axios.get("https://ocr.captchaai.com/res.php", {
params: { key: API_KEY, action: "get", id: taskId, json: 1 },
});
if (result.data.status === 1) {
console.log("IUAM challenge solved!");
return result.data.request;
}
}
throw new Error("Timed out");
}
solveIUAM().then((token) => console.log("Token:", token.substring(0, 50)));
管理 qa_session_cookie cookie
qa_session_cookie cookie是解决IUAM挑战的关键输出:
| 财产 | 价值 |
|---|---|
| Cookie 名称 | qa_session_cookie |
| 寿命 | 约 30 分钟(可现场配置) |
| 范围 | 域范围内 |
| 绑定到 | IP地址+用户代理 |
| 可重复使用的 | 是的,一生一世 |
| 可转让 | 仅具有相同的IP + UA |
Cookie 管理策略
import requests
import time
class IUAMSessionManager:
"""Manage qa_session_cookie cookies for IUAM-protected sites."""
def __init__(self, api_key, target_url, user_agent=None):
self.api_key = api_key
self.target_url = target_url
self.user_agent = user_agent or (
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
"AppleWebKit/537.36 Chrome/120.0.0.0"
)
self.session = requests.Session()
self.session.headers["User-Agent"] = self.user_agent
self.clearance_time = 0
self.clearance_lifetime = 1800 # 30 minutes default
def needs_refresh(self):
"""Check if clearance cookie needs refreshing."""
return time.time() - self.clearance_time > self.clearance_lifetime - 60
def solve_challenge(self):
"""Solve IUAM challenge and update session cookies."""
submit = requests.post("https://ocr.captchaai.com/in.php", data={
"key": self.api_key,
"method": "cloudflare_challenge",
"sitekey": "managed",
"pageurl": self.target_url,
"json": 1,
})
task_id = submit.json()["request"]
for _ in range(60):
time.sleep(5)
result = requests.get("https://ocr.captchaai.com/res.php", params={
"key": self.api_key,
"action": "get",
"id": task_id,
"json": 1,
}).json()
if result.get("status") == 1:
# Apply clearance to session
self.clearance_time = time.time()
return result["request"]
raise TimeoutError("IUAM solve timed out")
def get(self, url, **kwargs):
"""Make a GET request, solving IUAM if needed."""
if self.needs_refresh():
self.solve_challenge()
return self.session.get(url, **kwargs)
故障排除
| 症状 | 原因 | 处理方式 |
|---|---|---|
| 挑战无限循环 | 获得许可后IP发生变化 | 使用一致IP解决+访问 |
| qa_session_cookie 被拒绝 | 用户代理不匹配 | 使用相同的用户代理来解决和请求 |
| 解决后依然503 | Cookie 已过期(>30 分钟) | 到期前刷新清关 |
| 挑战页面与预期不同 | 网站使用 Managed Challenge,而不是 IUAM | 切换到 Turnstile 求解器方法 |
| 多个挑战页面 | 第一个挑战是IUAM,第二个挑战是Turnstile | 依次解决两者 |
常见问题
qa_session_cookie 持续多久?
默认值为 30 分钟,但站点操作员可以将其配置为 15 分钟到 24 小时。大多数网站都使用 30 分钟的默认值。计划在到期前刷新。
我可以在请求之间共享 qa_session_cookie 吗?
是的,但只能来自相同的 IP 地址并具有相同的用户代理字符串。更改其中任何一个都会使 cookie 失效。
受到攻击模式是否始终处于启用状态?
不会。站点操作员在攻击期间手动切换它。有些网站将其永久启用作为额外的安全层。无法预测某个网站是否会启用 IUAM。
IUAM 和管理挑战有什么区别?
IAUAM无条件地挑战每一位参观者。托管挑战使用 Cloudflare 的机器人评估来选择性地挑战可疑流量。 IUAM 总是返回 503 并带有 JS 挑战。托管挑战可能会返回 503,并带有 Turnstile 小部件。
IUAM 会影响 API 端点吗?
是的。 IUAM 适用于域上的每个请求,包括 API 端点。这就是来自非浏览器客户端的 API 请求失败的原因——它们无法执行 JavaScript 挑战。
概括
Cloudflare 的“受到攻击”模式为所有访问者创建了强制性的 JavaScript 挑战,返回 HTTP 503 并要求 5 秒的计算。解决 IUAM 挑战CaptchaAI 的 Cloudflare 验证流程 求解器,然后在 30 分钟窗口内使用 qa_session_cookie cookie 进行后续请求。在解决和使用之间始终匹配 IP 地址和用户代理。
相关文章
- Cloudflare 验证流程 与旋转门检测对比
- Cloudflare 验证流程 的工作原理
- Cloudflare 验证流程 会话流程演练