深度解析

如何处理攻击模式下的 Cloudflare

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 挑战旨在验证访问者是否拥有真实的浏览器:

挑战流程

  1. Cloudflare 使用模糊的 JavaScript 提供挑战页面
  2. JavaScript 执行计算: - 对页面中的字符串进行数学运算 - DOM 测量 - 计时执行(至少 4-5 秒)
  3. 计算的答案 — 基于挑战的数值
  4. 使用 jschl_vcpassjschl_answer 表单自动提交到 Cloudflare
  5. Cloudflare 验证答案和时间安排
  6. 返回 qa_session_cookie cookie — 允许访问约 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是解决IUAM挑战的关键输出:

财产 价值
Cookie 名称 qa_session_cookie
寿命 约 30 分钟(可现场配置)
范围 域范围内
绑定到 IP地址+用户代理
可重复使用的 是的,一生一世
可转让 仅具有相同的IP + UA
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 依次解决两者

常见问题

默认值为 30 分钟,但站点操作员可以将其配置为 15 分钟到 24 小时。大多数网站都使用 30 分钟的默认值。计划在到期前刷新。

是的,但只能来自相同的 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 地址和用户代理。

相关文章

该文章已禁用评论。