本文目录导读:

- 第一步:判断攻击的“属性特征”(打底分)
- 第二步:利用PHP日志和中间件日志做“异常检测”(加分项)
- 第三步:明确“攻击链”走到了哪一步(关键项)
- 第四步:业务影响程度(权重项)
- 最终评分公式(实操建议)
- 附:给PHP项目的“轻量化”实时监控建议
在PHP项目(尤其是Web应用)中,判断“这波进攻的威胁程度”不能靠感觉,必须依靠可量化的数据、攻击特征和业务影响来综合评估。
我们可以从以下四个维度来建立威胁评估模型,你可以根据实际情况给每个维度打分(1-5分),最后得出综合威胁指数:
第一步:判断攻击的“属性特征”(打底分)
这部分不需要看日志,仅凭攻击流量本身的特点就能初步判断。
- 自动化 vs 人工(+1到+3分):
- 如果请求头非常标准、速率恒定、没有Referer、没有Cookie —— 很可能是扫描器或僵尸网络(威胁较低,属于噪音)。
- 如果请求时间随机、带有正常浏览器指纹、且单次尝试后会改变策略 —— 很可能是真人或高级半自动工具(威胁极高)。
- 定向性 vs 广撒网(+1到+4分):
- 通用路径(如
/index.php?page=../../etc/passwd、/wp-admin)—— 大概率是全网扫描,威胁低。 - 业务特定路径(如
/api/v1/payment/callback、/admin/export.php?file=)—— 说明攻击者了解你的业务结构,威胁极高。
- 通用路径(如
- 请求分布:
- 只有单个IP攻击(+1分)。
- 大量IP同时段攻击(分布式,+4分,防范难度大)。
第二步:利用PHP日志和中间件日志做“异常检测”(加分项)
你需要像侦探一样去翻日志(access.log 和 PHP error.log),并寻找以下“危险信号”:
- 报错频率激增(+2分):
PHP Warning: mysqli_connect()或PDOException大量出现,说明攻击者正在尝试 SQL注入 或 数据库爆破。 - 超时和资源耗尽(+3分):日志中出现大量
Maximum execution time exceeded,可能正在遭受 慢速DDOS 或 表达式注入(导致正则回溯爆炸)。 - 文件上传迹象(+4分):上传目录(
/uploads/)频繁出现.php、.phtml、.phar后缀的文件,且日志发现/uploads/xxx.php?cmd=的请求,这是 命令执行/Webshell 的强信号,属于致命威胁。 - 参数值异常(+3分):
$_GET['id']、$_POST['data']中出现union select、base64_decode(、eval(、system(等关键字。
第三步:明确“攻击链”走到了哪一步(关键项)
这是判断威胁程度最核心的部分,这波进攻是刚摸门把手,还是已经进屋了?
- Level 0:试探扫描(威胁系数:1)—— 只请求不存在的路径,测试有无WAF。
- Level 1:漏洞探测(威胁系数:2)—— 尝试常见的注入点,但未成功执行。
- Level 2:漏洞利用中(威胁系数:4)—— 探测到了报错或者明显的时间延迟(
sleep(3)),说明可能触发了代码执行或SQL执行。 - Level 3:已获取权限/已上传文件(威胁系数:10,最高级)—— 一旦代码执行成功或写入文件成功,这已经不是“威胁程度”问题,而是“正在失陷”状态,必须立即断网隔离。
第四步:业务影响程度(权重项)
同样是SQL注入,打“新闻列表页”和打“支付/订单表”的威胁天壤之别。
- 攻击目标是公开信息(如文章详情、搜索缓存)—— 威胁程度降级。
- 攻击目标是敏感数据(用户密码、身份证、余额、后台管理入口)—— 威胁程度直接拉满。
最终评分公式(实操建议)
综合威胁值 = 攻击频率系数 × 攻击深度系数 × 业务敏感系数
| 严重级别 | 综合威胁值 | 响应动作 |
|---|---|---|
| 低危 | 1-3 | 普通扫描、404轰炸。动作:加入IP黑名单,无需人工介入。 |
| 中危 | 4-6 | 正在尝试注入但未成功,或带有业务定向性。动作:开启WAF拦截规则,重点监控同IP段。 |
| 高危 | 7-9 | 已出现SQL注入报错、反序列化尝试、或命令注入尝试。动作:停止该业务的异常请求,抓取当前MySQL的 processlist 和PHP日志完整快照,审计代码逻辑。 |
| 致命 | 10+ | 已发现Webshell上传成功,或核心数据库出现异常读写。动作:立即断开外网,保留现场,进入应急响应流程(备份当前进程、内存、访问日志)。 |
附:给PHP项目的“轻量化”实时监控建议
如果你无法立刻上复杂SIEM,可以用PHP内置机制做一个快速自检脚本(放在入口文件最顶部,配合Redis/MySQL计数器):
<?php
// 简单的威胁感知探针(在框架入口文件最顶部)
$key = 'threat:' . md5($_SERVER['REQUEST_URI'] . $_SERVER['REMOTE_ADDR']);
$flag = 0;
// 1. 检测参数中是否包含危险关键字(正则)
foreach ($_GET as $param) {
if (preg_match('/[\'\"\;\*\<\>\=\$\^\`\|\\]/i', $param)) {
$flag += 2; // 疑似注入
}
}
// 2. 检测并发频率(用Redis计数器)
$count = $redis->incr($key);
if ($count > 50) { $flag += 3; } // 高频访问
// 3. 如果威胁值高,直接记录并阻断
if ($flag >= 3) {
// 记录到安全日志表
log_security_event($_SERVER['REMOTE_ADDR'], $_SERVER['REQUEST_URI'], $flag);
// 如果是致命级别,直接 http_response_code(403); die(); // 或者交给WAF处理
}
最核心的建议:面对攻击,PHP项目最怕的不是被扫描,而是代码里存在可被利用的漏洞,防御的关键在于:开启display_errors=Off(防止报错泄露路径),禁用危险函数(disable_functions=system, exec, shell_exec),并绝对禁止将用户输入直接拼入SQL和文件路径,只要这三板斧到位,大部分“威胁”会迅速降级为“噪音流量”。