mcpField
P
profile-website-bot-detection

profile-website-bot-detection

github.com/kernel安全13384 次安装2 周前更新
代码仓库

关于 profile-website-bot-detection

用于检查目标网站的反机器人检测情况,识别供应商、产品和挑战类型。它通过隐身与普通浏览器模式的对照分析,帮助评估网站防护表现。

主要功能

  1. 01识别反机器人供应商与产品
  2. 02检测挑战类型和拦截情况
  3. 03分析首页及登录页
  4. 04对比隐身与普通浏览器
  5. 05生成 JSON 报告和截图

适用场景

  1. 01调查网站采用的反机器人服务
  2. 02比较不同浏览器模式的检测结果

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/kernel/skills --skill profile-website-bot-detection

安装后在 Claude Code 中输入/profile-website-bot-detection确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

scripts/
.gitignore
package.json
test-kernel-bot-detection.ts

详细介绍

Bot 检测供应商网站分析

分析目标网站,识别 Bot 检测供应商、其具体产品和挑战类型。支持比较隐身与非隐身浏览器模式。

前提条件

  • 已安装并完成身份验证的 Kernel CLI
  • 已安装 Bash、Node.js 22+ 和 jq
  • 已为分析脚本导出 KERNEL_API_KEY;切勿打印该密钥,也不要要求用户将其粘贴到聊天中

对比工作流(推荐)

在控制网络路径的同时,比较隐身与非隐身浏览器的 Bot 检测行为。在同一个 Bash 进程中运行步骤 1-7,以确保清理 trap 始终生效。不要将步骤 2 作为独立的非交互式 shell 运行:该 shell 返回时,其 EXIT trap 会删除会话。

步骤 1:准备分析器

在创建计费的浏览器会话之前安装依赖项:

cd scripts
npm install  # first run only
export TARGET_URL='https://example.com'
test -n "${KERNEL_API_KEY:-}" || { echo "KERNEL_API_KEY is not set" >&2; exit 1; }
步骤 2:创建两种浏览器会话并启用清理

使用 JSON 输出获取准确的会话 ID。如果第二个会话创建失败或后续分析失败,EXIT trap 会清理第一个会话。

set -euo pipefail
STEALTH_ID=
NORMAL_ID=

cleanup() {
  local ids=()
  [[ -n "${STEALTH_ID:-}" ]] && ids+=("$STEALTH_ID")
  [[ -n "${NORMAL_ID:-}" ]] && ids+=("$NORMAL_ID")
  if ((${#ids[@]})); then
    kernel browsers delete "${ids[@]}" || true
  fi
}
trap cleanup EXIT
trap 'exit 130' INT
trap 'exit 143' TERM

STEALTH_ID=$(kernel browsers create --stealth --viewport 1920x1080@25 --timeout 300 --output json | jq -er '.session_id')
NORMAL_ID=$(kernel browsers create --viewport 1920x1080@25 --timeout 300 --output json | jq -er '.session_id')

# Isolate browser stealth behavior: route the stealth session directly, like the normal session.
kernel browsers update "$STEALTH_ID" --disable-default-proxy >/dev/null

否则,隐身会话将使用 Kernel 的默认隐身代理,而普通会话将直接连接。若不执行更新,测量结果反映的是隐身 + 代理与普通 + 直连的差异,而非单纯的隐身效果。仅对隐身会话应用 --disable-default-proxy;API 不允许对非隐身会话使用该选项。

导航前,选择一种网络设计:

  • 浏览器模式对比(推荐): 保留上述更新,让两个会话都直接连接。
  • 平台默认设置对比: 省略更新,并将隐身结果报告为 stealth + default proxy;不要将差异归因于隐身本身。
  • 显式代理对比: 可选择使用 kernel proxies check "$PROXY_ID" --url https://example.com --output json 验证已配置的代理,在两个创建命令中都添加 --proxy-id "$PROXY_ID",并省略更新。这样可以控制代理配置,但代理提供商轮换仍可能导致出口 IP 不同。
步骤 3:在两种浏览器上运行分析
KERNEL_BROWSER_ID="$STEALTH_ID" TARGET_URL="$TARGET_URL" BROWSER_MODE=stealth npm run analyze
KERNEL_BROWSER_ID="$NORMAL_ID" TARGET_URL="$TARGET_URL" BROWSER_MODE=normal npm run analyze

每次分析器运行都会在写入报告后断开本地 CDP 客户端;Kernel 会话仍保持活动状态,以便进行对比和清理。

步骤 4:对比结果

对比每种模式下最新的报告,不要将多个 JSON 文档拼接在一起:

# Derive the same hostname folder used by the analyzer (e.g., chase.com -> chase-com).
HOST=$(node -e 'const host = new URL(process.env.TARGET_URL).hostname; console.log(host.replace(/^www\./, "").replace(/\./g, "-"))')
latest_report() {
  local reports=("$1"/report-*.json)
  [[ -e "${reports[0]}" ]] || return 1
  printf '%s\n' "${reports[@]}" | sort | tail -n 1
}
STEALTH_REPORT=$(latest_report "output/$HOST/stealth")
NORMAL_REPORT=$(latest_report "output/$HOST/normal")

echo "=== STEALTH VERDICT ===" && jq '.summary.verdict' "$STEALTH_REPORT"
echo "=== NORMAL VERDICT ===" && jq '.summary.verdict' "$NORMAL_REPORT"

echo "=== STEALTH BLOCKED ===" && jq '.summary | {isBlocked, blockedPages, blockedVendors}' "$STEALTH_REPORT"
echo "=== NORMAL BLOCKED ===" && jq '.summary | {isBlocked, blockedPages, blockedVendors}' "$NORMAL_REPORT"

echo "=== STEALTH VENDORS ===" && jq '.summary.vendorNames' "$STEALTH_REPORT"
echo "=== NORMAL VENDORS ===" && jq '.summary.vendorNames' "$NORMAL_REPORT"
步骤 5:解读对比结果
场景隐身普通含义
未检测到供应商00未观察到信号;不要据此认为网站没有 Bot 检测
检测到相同供应商,未拦截NN存在 Bot 检测,两个会话均通过
普通浏览器被拦截,隐身通过0 次拦截已拦截在网络受控的情况下,隐身模式有效
两者均被拦截已拦截已拦截两种受测配置均被拦截
挑战类型不同较轻较难在网络受控的情况下,隐身模式可能降低了可疑程度
步骤 6:提供摘要

完成对比分析后,明确说明网络设计。只有当两个会话使用相同网络类别时,才能声称隐身模式有效。

摘要报告模板:

## Bot Detection Comparative Analysis: [TARGET_URL]

### Verdict
- **Network Design**: [both direct / same explicit proxy config / platform defaults]
- **Stealth Browser**: [verdict from summary.verdict]
- **Normal Browser**: [verdict from summary.verdict]
- **Stealth Effectiveness**: [Effective/Ineffective/Inconclusive; use Inconclusive for mixed network paths]

### Block Status
| Browser | Blocked | Block Type | Evidence |
|---------|---------|------------|----------|
| Stealth | [Yes/No] | [blockType or N/A] | [first evidence item] |
| Normal  | [Yes/No] | [blockType or N/A] | [first evidence item] |

### Detected Vendors
| Vendor | Stealth | Normal | Products |
|--------|---------|--------|----------|
| [vendor] | ✓/✗ | ✓/✗ | [product list] |

### Analysis
- [Explain what the results mean]
- [Note any differences between stealth and normal]
- [Recommend next steps if blocked]

### Key Findings
1. [Finding 1]
2. [Finding 2]
3. [Finding 3]

使用 JSON 报告填写此模板:

  • summary.verdict - 最终判定字符串
  • summary.isBlocked - 浏览器是否被拦截
  • summary.blockedPages - 被拦截页面的详细信息
  • summary.vendorNames - 检测到的供应商列表
  • vendorDetections - 供应商/产品详细信息
步骤 7:清理

收集报告后立即删除两个会话。browsers delete 是非交互式命令,支持多个 ID;它没有 -y 标志。

cleanup
trap - EXIT INT TERM

如果 shell 被中断或变量丢失,请使用 kernel browsers list 查找创建的会话,并使用 kernel browsers delete <session-id> 分别删除。


结果解读

分析会检测供应商及其特定产品:

供应商检测到的产品
AkamaiBot Manager、Bot Manager Premier、mPulse RUM、Sensor Script、Edge DNS
CloudflareBot Management、Turnstile、Challenge Platform、JS Challenge、Managed Challenge
DataDomeInterstitial Challenge、Slider Challenge、Device Check、Picasso Fingerprint
HUMAN/PerimeterXBot Defender、Sensor SDK、Press & Hold Challenge
Imperva/IncapsulaAdvanced Bot Protection (utmvc)、Advanced Bot Protection (reese84)、WAF
KasadaIPS (Initial Page Security)、FP (Fingerprint Endpoint)、Telemetry、POW Challenge
GooglereCAPTCHA v2、reCAPTCHA v3、reCAPTCHA Enterprise
hCaptchaWidget、Enterprise
FingerprintJSFingerprint Pro、BotD
Arkose LabsFunCaptcha

检测方法:

  • 根据供应商脚本和端点的 URL 模式进行匹配
  • 分析 Cookie(例如,_abck、__cf_bm、datadome、_px*)
  • 检测标头(例如,cf-ray、x-kpsdk-*、x-d-token)
  • 根据响应状态码检测质询

供应商专属检查:

  • DataDome:检测硬性 IP 封锁(dd.t === 'bv')
  • Akamai:检查 Cookie 是否有效(~0~ 指示符)
  • Kasada:检测流程类型(IPS 或 FP)
分析的页面

脚本会自动分析:

  1. 主页 - 初始页面加载和机器人检测脚本
  2. 登录页 - 通过链接检测或常见路径(/login、/signin 等)自动发现

登录页通常会采用更严格的机器人检测,以防止凭据填充攻击。

输出文件

结果按目标主机名整理,存放在 scripts/output/<hostname>/<mode>/ 中:

  • report-<timestamp>.json - 包含供应商检测结果的完整 JSON 报告
  • screenshot-homepage-<timestamp>.png - 主页截图
  • screenshot-login-<timestamp>.png - 登录页截图(如果找到)

以 chase.com 的对比测试为例:

output/chase-com/
├── stealth/
│   ├── report-*.json
│   ├── screenshot-homepage-*.png
│   └── screenshot-login-*.png
└── normal/
    ├── report-*.json
    ├── screenshot-homepage-*.png
    └── screenshot-login-*.png

JSON 报告包含:

  • summary:快速查看判定结果、封锁状态和供应商名称
    • verdict:易于理解的结果(例如,“已封锁 - 主页(错误页面)”)
    • isBlocked:布尔值 - 如果任一页面被封锁,则为 true
    • vendorNames:检测到的供应商名称数组
    • blockedPages:包含证据的已封锁页面详情
  • vendorDetections:已检测供应商的映射,包含产品、URL、Cookie 和标头
  • blockDetections:每个页面的详细封锁分析
  • vendorScriptsDetected:检测到的供应商脚本 URL(未保存到磁盘)
  • networkRequests/networkResponses:所有经过供应商匹配的请求
  • cookies:所有 Cookie 及其对应的供应商

供应商专属检测说明

Akamai
  • Cookie:_abck(核心验证)、bm_sz、bm_sv
  • _abck 值中的 Cookie ~0~ = 会话有效
Cloudflare
  • Cookie:__cf_bm、cf_clearance
  • 质询:/cdn-cgi/challenge-platform/
  • Turnstile:challenges.cloudflare.com/turnstile
DataDome
  • Cookie:datadome
  • dd.t === 'bv' = 硬性 IP 封锁(需要更换 IP,解决验证码也无济于事)
HUMAN/PerimeterX
  • Cookie:_px2、_px3、_pxhd
  • Press & Hold 质询需要进行行为模拟
Imperva/Incapsula
  • utmvc:通过 /_Incapsula_Resource 提供的脚本
  • reese84:Cookie 或 x-d-token 标头
Kasada
  • 标头:x-kpsdk-ct、x-kpsdk-cd
  • 流程 1(IPS):初始页面加载时返回 429,必须先解决 ips.js
  • 流程 2(FP):后台 /fp 指纹请求

评论

支持 Markdown