防 CC 攻击项目

让 CC 攻击
在门口就被拦下

一套零依赖的 PHP 防火墙 + 一款离线的桌面日志分析器。 别人只需要在入口文件加一行,就能立刻获得 10 层防护; 而你,只需把日志丢进分析器,攻击全貌一目了然。

产品一 · 服务侧

CC Shield 防火墙

框架无关、即插即用的 PHP 防火墙,专门对抗 HTTP 洪水 / 爬虫刷接口 / 恶意扫描。

⚡

一行引入

在入口文件顶部 require_once 一行即可启用,无需 Composer、无需数据库、不改动业务代码。

🧱

10 层纵深

白名单优先、黑名单硬拦,再到静态放行 / 放行路径 / UA 规则 / 限频,最后用 JS 人机验证拦下脚本流量。

🤖

人机验证

真人浏览器几十毫秒算完令牌自动跳转;curl / python-requests 不执行 JS 被挡门外。

🗄️

多后端存储

自动探测 Redis > Memcache / Memcached > 文件,没有也能跑(虚拟主机友好)。多站点共用一台缓存时键前缀自动隔离。

🛡️

Fail-Open

任意异常都放行,绝不白屏宿主站点;先 observe 观察,确认无副作用再开 on。

🌐

IPv6 支持

黑名单支持单 IP / CIDR / 起止段 / 通配 / IPv6,覆盖现代网络环境。

入口文件最顶部,加这一行:
<?php
// 放在入口文件(index.php / app.php / public/index.php)的最顶部
require_once __DIR__ . '/cc-shield/bootstrap.php';
产品二 · 运营侧

CC 防火墙日志分析器

一款离线运行的 Windows 桌面程序(exe),把防火墙日志变成可读的攻击情报。

📊

归属地统计

内置离线 IP 库(ip2region),自动解析每条攻击的省 / 市 / 运营商,无需联网。

🗺️

网段 / 地域分类

按 /16 网段与归属地两种维度聚类,一眼看出攻击来自哪些机房与地区。

🕒

攻击时段

按小时维度统计攻击密度,识别攻击高峰与持续时长。

🚦

拦截类型

区分黑名单 / UA 规则 / 限频 / 挑战洪水,定位主要拦截手段。

🔍

误判识别

标注疑似误拦记录,帮助你在上线前把真实用户排除在防护之外。

💽

双击即用

PyQt5 打包的单目录 exe,配套离线库,解压后双击即可运行,不写注册表。

💡 分析器的数据来自 cc-shield.log(Tab 分隔 7 列:时间 / 动作 / 阶段 / IP / 原因 / URL / UA)。 防火墙开启后产生的日志,直接拖进分析器即可。
前提条件

运行环境与 PHP 版本要求

CC Shield 是纯 PHP 实现,零扩展依赖。以下为经过实测与推荐的组合。

🖥️ 操作系统

  • Linux:CentOS / Rocky / Ubuntu / Debian 等
  • Windows:Server 2012+ / 10 / 11(IIS 或 Apache)
  • macOS:本地开发 / 测试

🌐 Web 服务器

  • Apache(mod_php 或 php-fpm)
  • Nginx + PHP-FPM
  • IIS + PHP(Windows)
  • 任意 FastCGI / FPM 环境
  • CLI 默认不启用(可用 CC_SHIELD_ALLOW_CLI 强制)

🐘 PHP 版本

  • 最低:PHP 7.0(用到 random_bytes()、\Throwable)
  • 推荐:7.4 / 8.0 / 8.1 / 8.2
  • 已实测:PHP 8.2.33(10 场景全通过)
  • 不支持:PHP 5.x

⚠️ CPU 架构(重要)

  • 强烈建议 64 位(x86_64 / arm64)PHP。
  • 32 位 PHP 的 ip2long() 返回有符号整数,会导致 ≥128.0.0.0 的高位 IP 段匹配偏差。
  • 64 位下整数可完整容纳 32 位地址,判断准确。

🧩 PHP 扩展

  • 无强制依赖:仅用内置函数
  • 可选:redis(推荐)
  • 可选:memcached / apcu
  • 都没有 → 自动退回文件存储

📁 目录权限

  • cc-shield/data/ 需可写
  • 用于日志 / 盐值 / 黑名单缓存 / 限频计数
  • 无写权限时自动 fail-open 放行
📌 日志分析器(exe)为 Windows 桌面程序,需要 Windows 7 SP1 及以上(含 .NET/VC 运行库随包附带),无需安装 PHP。
纵深防御

链接注入防护 · 已防护的历史漏洞

除了 10 层 CC 防护,CC Shield 还内置一层链接/查询串注入防护(第 2 层,默认开启), 专门拦截通过 URL 发动的历史漏洞攻击特征。

✅ 已防护(特征拦截)

CVE-2024-4577

PHP-CGI 参数注入 · 未授权 RCE · Critical

拦截 %ad / %2d 等注入特征——攻击者借此向 php-cgi.exe 注入 -d 指令实现远程代码执行。

✅ 已防护(特征拦截)

CVE-2012-1823

旧版 PHP-CGI 参数注入

CVE-2024-4577 正是它的绕过;同样依靠 URL 特征拦截。

✅ 已防护(特征拦截)

空字节注入等

经典 URL 绕过

拦截 %00 等空字节注入,防御路径 / 包含类绕过尝试。

🎯 精确判定,不误伤中文:软连字符 0xAD 同时也是 UTF-8 的续字节—— 「中」的编码 %E4%B8%AD 里就含 %AD。所以本层不是简单匹配 %ad(那会误拦约 3.1% 的常用汉字,让用户搜索「中 / 字 / 六」时直接 403 「该页无法显示」),而是要求 0xAD 前一字节为非高位字节(即它不属于任何 多字节字符),仅在「参数边界 + 后跟开关字符 + 典型载荷关键词」时才判定为注入。
判定对 UTF-8 / GBK 一视同仁,不依赖 mbstring,也不会误伤 base64 值里的 -d; 已通过 422,340 组多字节字符穷举回归(CJK 基本区 / 扩展 A·B / 谚文 / 假名 / emoji),零误拦。
⚠️ 边界说明(务必知悉):链接注入防护是 Web 服务器层请求过滤(IIS Request Filtering / Apache mod_rewrite)的兜底,不能替代根本修复。 在「经典 CGI + auto_prepend_file」变体下,注入发生在 PHP 脚本运行之前,本层可能来不及拦截; 该漏洞的彻底解决仍是升级 PHP 或改用 FastCGI。 此外,CC Shield 仅防护「URL 类」攻击特征,对 PHP 引擎自身漏洞(gd / imap 的 RCE)、 操作系统漏洞、32 位 PHP 的 IP 计算偏差等无能为力——这些必须靠升级 / 换架构。
🔧 想确认自己的服务器是否处于 CVE-2024-4577 高危环境?项目仓库根目录提供 cc_shield_env_check_用完即删.php:上传到网站根目录访问即可一键检测 (PHP 版本 / SAPI / 架构 / 扩展 / 历史漏洞逐步判定),查看完请立即删除。 下载检测工具(重命名为 .php 后使用)
配置

配置文件说明(shield.ini)

CC Shield 零配置即可运行(默认 mode = on),并不强制要求改配置才能启动。 但上线前,建议通过 config/shield.ini 微调几项,避免误拦真实用户。

📁 文件位置:cc-shield/config/shield.ini · 格式:扁平 key=value(无 section) · 保存即生效,无需重启 PHP / Web 服务器
config/shield.ini 示例(取消注释即启用)
; 运行模式:先 observe 观察 1~2 天,确认无副作用再改 on
mode = observe

; 走 CDN / Nginx 反代必须开 1;直连服务器保持 0(防 XFF 伪造绕过)
trust_xff = 0

; 后台 / API / 健康检查,命中即绕过防火墙
allow_paths = "/admin,/api/,/wp-admin,/wp-login.php"

; 自己的办公 / 运维 IP,强烈建议填写,防误锁自己
ip_whitelist = "1.2.3.4, 10.0.0.0/8"

📌 上线前建议确认的项

  • mode:先用 observe 观察,再开 on
  • trust_xff:CDN / 反代开 1,直连保持 0
  • allow_paths:把后台、API 加进去
  • ip_whitelist:填你的办公 / 运维 IP

🧩 其它常用项

  • block_empty_ua / min_ua_len:过短 UA 直接拦
  • ua_blacklist / ua_allow:恶意工具 / 搜索引擎
  • crawler_ips:爬虫来源 IP(默认已内置官方段)
  • crawler_dns_verify:反向 DNS 校验爬虫来源
  • challenge_max / challenge_hard_max:人机验证的软上限(超了只记日志、不封禁,默认 300)与硬上限(超了才 403,默认 3000)
  • challenge_paths:只对敏感入口挑战,大幅降低挑战总量
  • token_bind_ip / token_bind_prefix_v4:令牌绑定粒度;移动网络 / CGNAT 出口 IP 漂移时设 24 按网段绑定(比直接设 0 安全)
  • store_type:auto / redis / memcache / memcached / file(APCu 需显式指定,见下)
  • store_prefix:缓存键前缀。留空即自动隔离——多项目共用一台 Memcache / Redis 时互不干扰;仅多站共用同一份包且文档根也相同时才需手工指定
  • log_level:all / action / block / off
💡 除 ini 外,你也可以在入口文件用 define() 覆盖(优先级更高),或用 CC_SHIELD_CONFIG 数组配置限频分组等数组型参数。完整参数说明见压缩包内的 README.md。
🛡️ 黑名单是硬拦截:把 IP / 网段写进 data/ip-blacklist.txt,命中即拦,不受放行路径、静态后缀、爬虫 UA 影响;改完保存即生效。唯一能覆盖黑名单的是 ip_whitelist——把自己办公 / 运维 IP 加白,避免误锁。
🩺 站点「偶尔打不开 / 刷新几次又好了」怎么查(重要):这类症状基本都出自 有状态层(限频、临时封禁、人机验证)或请求被挂住,不是规则写错。四个最常见根因:
① 共享出口 IP(公司 / 校园 / 运营商 NAT)——计数按 IP 统计,几十个真人共用一个出口时容易互相误伤。本版已改为分级封禁:软上限(默认 300)只记日志、不封禁,只有超过硬上限(默认 3000)才 403,此类误伤基本消除;
② CDN / 反代 / 移动网络导致 IP 不稳定——令牌(默认绑定 IP)对不上就会反复验证。处理顺序:先开 trust_xff,再设 token_bind_prefix_v4 = 24 按网段绑定,最后才考虑 token_bind_ip = 0;
③ 存储状态不共享——auto 已不再选 APCu(其缓存按 PHP 进程隔离,会造成间歇性拦截),需要更快的共享存储请用 Redis / Memcached;
④ 同一站点跑在多台服务器——令牌用 data/.salt 签名,各机各一份盐 → 令牌只在签发它的那台有效。请共用同一 data/ 或统一 CC_SALT;
⑤ 同机多站点共用一台 Memcache / Redis——键名若相同会跨站连坐(A 站封的 IP 在 B 站也 403、限频阈值被叠加打满)。本版已按站点自动隔离键前缀,例外情况见下方 FAQ。
最快定位办法:把 cc_shield_env_check_用完即删.php 放到网站根目录访问,它的「挑战令牌往返自测」会读取你浏览器真实携带的令牌并当场判定 没有携带 / ✅ 通过 / ❌ 未通过,原因 xxx——刷新几次再看不携带/未通过,就是问题所在。
🤖 爬虫白名单默认必须校验来源(重要):UA 是客户端随手就能伪造的字符串,所以 「UA 命中 ua_allow」不再等于放行——还必须通过来源校验,否则一律按普通访客处理 (照样受限频与人机验证约束):
① crawler_ips:来源 IP 必须落在官方网段内,默认已内置 Googlebot / Bingbot / Baiduspider 官方段,无需填写即可用;
② crawler_dns_verify = 1:改用反向 DNS 双向确认(官方推荐、名单永不过期,代价是少量 DNS 查询,已带缓存与每分钟限流);
③ trust_crawler_ua = 1:仅凭 UA 放行,不安全,仅为兼容旧行为,默认关闭。
自测:curl -A "Googlebot/2.1" http://你的站/ 应收到 403 或人机验证页,而不是正常页面。
上手

快速开始

1

部署防火墙

把 cc-shield/ 目录整体拷到你的项目根目录,在入口文件最顶部加一行:

require_once __DIR__ . '/cc-shield/bootstrap.php';
2

先观察再启用

在引入前加 define('CC_SHIELD_MODE','observe'); 跑 1~2 天, 看 data/cc-shield.log 里的 WOULD_BLOCK,确认无真实用户被误判。

3

微调并上线

把后台路径、API 前缀、办公 IP 填进 config/shield.ini,再把模式改成 on。

4

分析日志

双击打开日志分析器,把 cc-shield.log 拖入,按归属地 / 网段 / 时段 / 拦截类型查看攻击全貌。

获取

下载

两个独立压缩包 + 一个单文件检测工具,按需取用。下载后解压 / 上传即可,无需安装。

🛡️

CC Shield 防火墙

PHP 源码包 · 一行引入 · 零依赖

  • 格式:ZIP
  • 环境:PHP 7.0+(推荐 8.2)
  • 含 README、示例、配置文件
下载 cc-shield.zip
📊

CC 防火墙日志分析器

Windows 桌面 exe · 离线 IP 库

  • 格式:ZIP
  • 环境:Windows 7 SP1 及以上
  • 双击即用,无需 PHP
下载 cc-analyzer.zip
🩺

环境检测 / 拦截自查工具

单文件 PHP · 用完即删

  • 格式:PHP(下载的是 .txt,请改名去掉 .txt 后缀)
  • 检测运行环境 + 历史漏洞(CVE-2024-4577 等)
  • 定位「偶尔打不开」是哪一层拦的
下载检测工具(.php.txt)
答疑

常见问题

放在 Laravel / ThinkPHP / WordPress 入口会不会冲突?

不会。它只读取 $_SERVER / $_COOKIE,不依赖任何框架,且在业务启动前运行;被拦的请求根本不会进到框架,通过的请求原样交还。务必放在入口最顶部。

走了 CDN(腾讯云 / Cloudflare / 阿里云),限频把全站访客当一个人?

开启 trust_xff(或 CC_TRUST_XFF),让它从 X-Forwarded-For / X-Real-IP 取真实访客 IP。直连服务器切勿开启,否则攻击者可用 XFF 伪造绕过。

挑战页会不会影响 SEO / 正常用户?

不会。搜索引擎爬虫从官方 IP 段来访时直接放行——默认已内置 Googlebot / Bingbot / Baiduspider 官方网段,也可开 crawler_dns_verify 改用反向 DNS 校验(官方推荐、名单不会过期)。真实浏览器首次访问做几十毫秒验证后自动跳转,几乎无感。挑战只对 GET 请求,POST 表单不受影响。

攻击者把 UA 改成 Googlebot,能绕过防火墙吗?

不能(前提是别开 trust_crawler_ua)。因为 UA 可以随意伪造,爬虫白名单默认必须校验来源:只有「UA 命中 ua_allow」且「来源 IP 在官方网段内(或反向 DNS 双向确认通过)」才放行。伪造 UA 的请求会退回普通队列,照样受限频与人机验证约束。
自测:curl -A "Googlebot/2.1" http://你的站/ 应收到 403 或验证页。

虚拟主机没有 Redis / Memcached 能用吗?

能。store_type=auto 会自动退回文件存储:非阻塞加锁(拿不到锁就直接放行,绝不卡住请求)、rename 原子写、并按概率自动回收过期缓存文件。并发量大的站点建议上 Redis。

一台服务器上多个项目都装了它、都连同一个 Memcache,缓存键会撞车吗?

默认不会,已自动隔离,无需配置。但要理解原理,否则出问题时很难查:
Memcache / Redis 的键空间是整台服务器共享的,而各站用到的键名都一样(ban:IP 临时封禁、r:组:IP:槽 限频计数、c:IP:槽 挑战次数、botdns:IP 爬虫 DNS 缓存)。不隔离就会跨站连坐:A 站封的 IP 在 B 站也被封、几个站的访问量叠加到同一个计数器上把限频阈值提前打满、误封真人、爬虫 DNS 配额被别站吃光。
本版为每个安装派生唯一的键前缀(形如 cshr:9f3a1c7e02:ban:1.2.3.4),依据是「站点文档根 + 本包目录」,所以这两种常见形态自动隔离:「各项目各拷一份 cc-shield」→ 包目录不同;「多站点共用一份 cc-shield」→ 文档根不同。用文件存储时本来就各用各的 data/cache/,天然隔离。
唯一例外:多个站点共用同一份包、且文档根也相同(同一站点下 /a/、/b/ 两个子项目各引一份),此时需手工区分——各站写不同的 store_prefix = "cshr:siteA" / "cshr:siteB",或在入口 define('CC_STORE_PREFIX', ...)。核对办法:跑 cc_shield_env_check_用完即删.php 看「缓存键前缀」一行,各站点必须不同。

页面偶尔打不开、刷新几次又能打开,是什么原因?

这类症状几乎都出自有状态层(限频、临时封禁、人机验证)或请求被挂住,按下面三步定位:
① 先分清是「403 页面」还是「浏览器提示无法访问」。看到 403 说明是防火墙拦的,去 data/cc-shield.log 看第 3 列阶段(iplist 黑名单 / ua UA 规则 / rate 限频 / challenge 人机验证 / url-injection URL 特征);如果是浏览器自身提示「该页无法显示」,那是请求被挂住/超时,不是拦截——请确认已用最新版 src/Store.php(早期版本 flock 会无限等锁)。
② 人机验证反复出现时,直接看日志里的 why=——它就是结论:no_cookie(cookie 没被带回)、ip_mismatch:IP(IP 漂移,令牌有效但换了个 IP)、bad_hex(盐变了,或令牌不是本机/本 IP 签发的)、iter_low(没真正执行 JS,属正常拦截)。count 持续增长才说明令牌确实没生效。
③ 用检测工具一次看全:把 cc_shield_env_check_用完即删.php 放到网站根目录访问,「挑战令牌往返自测」会读取你浏览器真实携带的 cc_vt 并用同一套规则验一遍,直接给出没有携带 / ✅ 通过 / ❌ 未通过,原因 xxx;同一页还有防火墙看到的 IP、存储后端是否跨进程共享、data/ 是否可写、日志分层统计与 why 分布。

为什么 auto 不再自动选 APCu 了?

因为 APCu 的缓存是按 PHP 进程隔离的(PHP-FPM / IIS 多 worker 下每个进程各一份)。限频计数、临时封禁这类状态必须跨请求、跨进程一致,否则会出现「这个进程说封了、那个进程说没封」,表现为间歇性拦截、刷新几次又好了——极难排查。要更快的共享存储请用 Redis / Memcached;确实需要 APCu 才显式写 store_type = apcu。

32 位 PHP 能用吗?

不推荐。防火墙内部用 PHP 整数运算处理 32 位 IPv4 地址,32 位 PHP 的 ip2long() 返回有符号整数,会导致 ≥128.0.0.0 的高位 IP 段匹配偏差。请使用 64 位 PHP。

日志分析器需要联网吗?

不需要。IP 归属地解析使用随包内置的离线库(ip2region),全程离线,适合在内网 / 隔离环境使用。

我把自己的 IP 加进黑名单,为什么还是不拦截?

按以下顺序排查:
① 运行模式:若配置成 observe,只会写日志(WOULD_BLOCK)而不真正拦截,改回 on 即可;
② IP 对不对:服务器实际看到的 IP 必须和黑名单里的一致。走 CDN / 反向代理时要在入口开 CC_TRUST_XFF,并确认取到的是真实访客 IP 而不是节点 IP;
③ 入口是否覆盖:确认你测试的这个 URL 所经过的入口文件确实 require 了 bootstrap.php(老系统常有多入口 / 静态文件直出,不经过 PHP);
④ 黑名单是硬拦截:现在命中即拦,不受放行路径、静态后缀、爬虫 UA 影响;唯一能覆盖它的是 ip_whitelist(这是为了不把你锁在门外)。

用户搜索中文关键词时出现 403 /「该页无法显示」?

先看 data/cc-shield.log 里有没有 url-injection 记录:
① 有:是链接注入防护误判。只有早期版本会出现——它直接匹配 %ad, 而 0xAD 是 UTF-8 续字节,「中」的编码 %E4%B8%AD 里就含它, 因此会误拦约 3.1% 的常用汉字(中 / 字 / 六…)。升级到当前版本即可(已改为按 「是否为孤立软连字符」精确判定,42 万组穷举零误拦);紧急时可先在入口加 define('CC_URL_INJECTION_GUARD', false) 临时关闭本层。
② 没有:不是这一层,按上一条「黑名单不拦截」的思路逐项排查(模式是否为 observe、trust_xff、入口是否覆盖、限频阈值)。

↑