综合php项目,防守漏洞怎么识别定位?

wen PHP项目 2

PHP 项目防守漏洞识别与定位指南

防守方(甲方/蓝队/安全左移)识别 PHP 项目漏洞,需要从代码审计、运行时监控、依赖管理、配置检查几个维度系统化进行,下面给出一套可落地的方法论。

综合php项目,防守漏洞怎么识别定位?


先建立"漏洞定位思维模型"

定位漏洞本质是回答三个问题:

  1. 入口在哪?(用户可控数据从哪进来)
  2. 数据怎么流?(污点传播路径)
  3. 危险函数在哪?(sink 点是否被触发)

即经典的 Source → Propagator → Sink 污点分析模型。


静态代码审计(SAST)—— 主力手段

按高危 Sink 反向搜索

用 IDE / grep / ripgrep 全局搜索危险函数,这是最快定位方式:

命令执行类

rg -n "system|exec|shell_exec|passthru|popen|proc_open|pcntl_exec|`" --type php

代码执行类

rg -n "eval|assert|create_function|preg_replace.*/e|call_user_func|call_user_func_array|array_map|usort" --type php

文件操作类

rg -n "include|require|include_once|require_once|file_get_contents|file_put_contents|fopen|unlink|copy|rename|move_uploaded_file" --type php

SQL 注入类

rg -n "mysql_query|mysqli_query|->query\(|->exec\(|->prepare\(" --type php

反序列化类

rg -n "unserialize|__wakeup|__destruct|__toString|__call" --type php

SSRF/请求类

rg -n "curl_exec|file_get_contents\(.*http|fsockopen|stream_context_create" --type php

追踪污点传播

找到 Sink 后往回追,看参数是否来自:

  • $_GET / $_POST / $_REQUEST / $_COOKIE / $_FILES / $_SERVER
  • php://input
  • 数据库读出的内容(二次注入)
  • 上传文件名、HTTP Header

定位要点:只要从入口到 Sink 之间没有白名单校验,基本可以判定为漏洞。

静态分析工具

工具 特点
PHPStan / Psalm 类型流分析,配合 taint 扩展
psalm --taint-analysis 官方支持污点分析,强烈推荐
RIPS 商业 PHP 静态审计,误报低
SonarQube 通用,支持 PHP
Semgrep 自定义规则灵活
Fortify / Checkmarx 企业级

Psalm 污点分析示例

psalm --taint-analysis --output-format=json ./src

它会直接给出 $_GET['id']mysqli_query() 的完整路径。

通读路由入口

PHP 项目定位漏洞的第一站

  • 框架项目:看 routes/controller/middleware/
  • 原生项目:看 index.php 入口、.htaccess/nginx.conf 的 rewrite 规则
  • 找出所有对外暴露的 URL,逐个反查代码

动态检测(DAST)—— 运行时验证

黑白盒扫描工具

  • Burp Suite / AWVS / Xray / 杀器(Goby):主动扫描 URL
  • sqlmap:SQL 注入定位
  • nuclei:模板化 POC 扫描

运行时 Hook(关键手段)

在 PHP 层挂钩危险函数,直接捕获调用栈:

// 通过 auto_prepend_file 注入
$danger = ['system','exec','eval','unserialize','mysqli_query'];
foreach ($danger as $fn) {
    // 需要 uopz / runkit 扩展实现函数替换
}

更实用的方式是 RASP(运行时应用自我保护):

  • 开源:openrasp(支持 PHP)
  • 商业:长亭、青藤、默安等 HIDS/RASP

RASP 会直接输出:

漏洞类型: 命令执行
调用栈: index.php:10 → UserController.php:55 → system()
输入源: $_GET['cmd'] = "whoami"

日志与埋点

  • error_log + PHP-FPM access log
  • 在 PDO/mysqli 层包装记录完整 SQL
  • Nginx $request_body 全量记录(注意脱敏)

依赖与配置层防护

Composer 依赖扫描

composer audit
# 或
local-php-security-checker composer.lock

对接 https://packagist.org 漏洞库,定位 symfony/*laravel/*guzzle 等组件的已知 CVE。

配置检查清单

配置项 安全值
display_errors Off
allow_url_include Off
allow_url_fopen 按需
disable_functions system,exec,passthru...
open_basedir 限定目录
session.cookie_httponly On
session.cookie_secure On
expose_php Off
php -i | grep -E "disable_functions|open_basedir|allow_url"

常见 PHP 漏洞的定位套路

漏洞类型 快速定位方法
SQL 注入 $_GET/\$_POST 直接影响 query;检查是否用 prepare + 参数绑定
XSS echo/print 输出未 htmlspecialchars 的变量
文件包含 include/require 的变量参数,检查是否含 / php://
文件上传 检查 move_uploaded_file 前的 MIME、后缀、内容校验
命令执行 system/exec/shell_exec,看参数是否拼接
反序列化 unserialize,追踪 __destruct/__wakeup 可达性(POP 链)
SSRF curl_exec/file_get_contents,参数是否用户可控
越权 看 controller 是否有统一的鉴权中间件
CSRF 检查表单是否有 token 校验

落地流程(推荐)

梳理资产    →  路由入口清单 + 对外接口
2. 静态扫描    →  Semgrep/Psalm + grep 危险函数
3. 人工审计    →  按 Source→Sink 追踪每个入口
4. 动态验证    →  Burp + Xray + RASP 复现
5. 依赖审计    →  composer audit
6. 配置加固    →  php.ini + Nginx + disable_functions
7. 建立基线    →  把审计规则沉淀到 CI(GitLab CI / GitHub Actions)

CI 集成示例

stages: [scan]
semgrep:
  script: semgrep --config=p/php --error .
psalm:
  script: psalm --taint-analysis
composer-audit:
  script: composer audit

关键建议

  1. 不要只依赖工具:SAST 误报率高,最终靠人工确认数据流。
  2. 优先看入口:80% 的洞来自用户可控的 $_GET/$_POST 直接进危险函数。
  3. 关注框架特性:Laravel/ThinkPHP 的 Request 封装、DB::rawwhereRaw 都是高危点。
  4. RASP 是防守方利器:能在运行时直接告诉你漏洞在哪一行。
  5. 建立函数禁用清单:即使代码有洞,disable_functions 也能兜底。

如果你想针对具体某个漏洞类型(如反序列化链、SQL 注入)或者某个框架(Laravel/ThinkPHP)展开,我可以给更细的定位步骤。

抱歉,评论功能暂时关闭!