前面几篇里我们练的是”用眼睛和脑子审”:背危险函数、追参数来源、通读鉴权。但真到了几万行的项目,纯手工翻会又慢又漏。这时候就该请工具出场了——工具负责把”体力活”(扫遍所有危险调用点、列出依赖组件、标出可疑写法)做掉,你负责做工具做不了的”判断题”(这到底是不是漏洞、危害多大、怎么修)。这一篇就把 PHP 审计常用的工具链讲透,帮你搭一条自己的流水线。
本文所有工具仅用于你对自有或已授权的 PHP 代码做安全评估,切勿用于未授权目标。
先分清:工具分几类
上手前先建立分类认知,你才知道每个工具解决什么问题、什么时候用哪个:
- 静态分析工具:不运行代码,直接读源码找危险模式。这是审计主力,比如 Seay、RIPS、Fortify、Semgrep、Progpilot。
- 类型/质量分析工具:本职是查代码质量和类型错误,但能顺带暴露危险写法,比如 PHPStan、Psalm。
- 动态调试工具:让代码跑起来、下断点看变量,用于验证静态阶段的可疑点,代表是 Xdebug。
- 后门/木马检测工具:专门找已经被种进去的 WebShell,比如 D 盾、河马 Shellcheck。
- 辅助工具:IDE 的全局搜索、正则、
grep,虽然朴素但极其高频。
记住一条原则:没有一个工具能包打天下。真正的审计是几类工具搭配着用,静态扫出可疑点,动态去验证,辅助工具补漏。
Seay:国产 PHP 审计的顺手兵器
Seay 源代码审计系统是国内 PHP 审计几乎人手一个的工具,图形界面、对中文友好、上手快。它的核心能力是:
- 自动审计:导入项目后一键扫描,把
eval、system、include、unserialize等危险函数的调用点全部列出来,双击即可跳到源码位置。 - 代码定位与上下文:点开某个可疑点,能直接看到它所在的函数、上下文,方便你判断参数来不来自用户。
- 自定义规则:Seay 支持用正则写自己的审计规则。比如你想找所有”拼接了
$_GET的 SQL 语句”,可以自定义正则批量匹配,比死记函数名灵活得多。 - MySQL 监控:它能挂到数据库上,把应用真正执行的 SQL 抓下来,帮你确认某个注入点是不是真的把恶意参数带进了查询。
Seay 的定位是”帮你快速把可疑点捞出来”,它不会告诉你”这一定是漏洞”,误报很多,需要你逐个人工确认。但对新手来说,它把”全局搜危险函数”这一步自动化了,省了大量体力。
RIPS 与 Fortify:老牌与商业选手
RIPS 是较早专注 PHP 的静态分析工具,它能做污点分析(taint analysis)——追踪一个用户输入从进入到危险函数的完整路径,而不只是简单匹配函数名。这比纯正则匹配聪明,能减少一部分误报。老版本 RIPS 开源,新版本转向商业。
Fortify SCA 是惠普/微焦系的商业静态分析工具,支持多语言(含 PHP),规则库非常全,报告规范,适合企业做合规扫描。它的优点是”开箱即用、覆盖广”,缺点是”贵、误报也不少、需要人工过滤”。同类的商业选手还有 Checkmarx。这类工具通常出现在有预算的甲方安全团队或第三方测评机构手里。
对个人和小团队,商业工具往往用不起,这时开源方案更实际。
Semgrep 与 Progpilot:轻量开源方案
Semgrep 是近几年很流行的开源静态分析工具,跨语言、规则用 YAML 写、上手极快。它的最大优势是规则可读可自定义:官方和社区维护了一大批 PHP 安全规则(命令执行、SQL 注入、XSS 等),你也能几行 YAML 写出自己的规则。比如”匹配所有把 $_GET 直接拼进 mysqli_query 的地方”,写成规则后可以在整个项目乃至持续集成里反复跑。因为轻量、易接 CI,Semgrep 特别适合团队把审计规则沉淀下来、自动化执行。
Progpilot 是一个专门针对 PHP 的开源污点分析器,能追踪从输入源(source)到危险汇聚点(sink)的数据流,输出可能的漏洞路径。它比简单的关键字匹配更接近”真正的数据流分析”,适合想要免费又想要污点追踪能力的场景。
顺便说一句:很多人会问 CodeQL 能不能审 PHP。CodeQL 官方主要支持 Java、JavaScript、Python、C/C++、Go、C# 等,并不原生支持 PHP,所以 PHP 审计里 CodeQL 不是主力——想要语义化查询能力,PHP 这边更多靠 Semgrep 和 Progpilot。
PHPStan / Psalm:本职查错,顺带查危险
PHPStan 和 Psalm 是 PHP 的静态类型分析工具,本职工作是找类型错误、未定义变量、死代码这些质量问题。它们不是安全工具,但对审计有两点价值:
其一,它们能帮你快速理解陌生代码——把类型标注、调用关系梳理清楚,你追调用链会更快。其二,很多安全问题本质上是”类型没约束好”,比如一个本该是整数的参数被当字符串拼进 SQL,类型分析能顺带把这类隐患暴露出来。Psalm 甚至有 taint 分析的实验特性,可以做一定程度的污点追踪。
把它们理解成”审计的辅助雷达”:主雷达(Seay/Semgrep)扫危险函数,辅助雷达帮你看清代码结构和类型漏洞。
Xdebug:让可疑点”跑给你看”
静态工具再强,也只能告诉你”这里可能有问题”。要坐实一个漏洞,最靠谱的是让它跑起来。Xdebug 是 PHP 最主流的调试扩展,配合 VS Code 或 PhpStorm,可以:
- 在可疑代码行下断点,发一个构造好的请求,单步执行看参数一步步怎么变。
- 观察变量的真实值:那个你以为可控的
$id,到了 SQL 拼接处到底长什么样、有没有被中途过滤。 - 验证弱类型绕过:亲眼看到
'0e123' == '0e456'判断为真、$$k覆盖了权限变量,比脑补可信得多。
审计的黄金节奏是”静态找、动态证”:静态工具给你一张可疑清单,Xdebug 帮你把清单里最像漏洞的几个一个个坐实。能在本地复现的,就别只在脑子里推演。
D 盾与河马:查已被种下的后门
有一类特殊场景:你审计的项目已经”出过事”,需要确认里面有没有被人种了 WebShell(网站木马)。这时静态审计工具不够用,要请专门的后门检测工具:
- D 盾:Windows 下常用的 WebShell 查杀工具,对各种变形、加密、混淆的 PHP 木马识别率高,扫一遍能把可疑文件标出来。
- 河马 Shellcheck:跨平台的 WebShell 检测工具,支持命令行,适合服务器上批量扫。
它们和审计工具的区别是:审计工具找”代码里的漏洞”,后门检测找”已经被利用后留下的马”。应急响应或接手一个来历不明的项目时,先用它们扫一遍很有必要。
别忘了最朴素也最高频的工具
聊了这么多专业工具,其实审计里用得最多的,反而是 IDE 的全局搜索和正则。PhpStorm、VS Code 的全局搜索支持正则,你可以:
- 搜
(\$_GET|\$_POST|\$_REQUEST|\$_COOKIE)\[快速列出所有外部输入点。 - 搜
eval\s*\(|system\s*\(|exec\s*\(一次性捞出危险函数调用。 - 搜
unserialize\s*\(定位所有反序列化入口。
命令行的 grep -rn(或更快的 ripgrep)在服务器上没有 IDE 时同样管用。别小看这些朴素手段,它们不需要安装配置、随手就用,很多资深审计员的主力就是”正则 + 人脑”,专业工具只是补充。
一条能落地的 PHP 审计工具流水线
把上面的工具串起来,给你一条可直接照做的流程:
- 摸底:拿到项目先看版本、依赖、
php.ini与框架配置,用 IDE 全局搜索认清目录结构和入口。 - 粗筛:用 Seay 或 Semgrep 全量扫一遍,导出危险函数与可疑模式清单。想要污点分析就加 Progpilot。
- 辅助理解:跑一遍 PHPStan/Psalm,把类型问题和代码结构摸清,帮助后续追链。
- 人工确认:对清单里的每个可疑点,用 IDE 跳转逆推参数来源,判断是否用户可控、有无过滤。
- 动态验证:给最像漏洞的几个点用 Xdebug 断点复现,坐实危害。
- 应急补充:若项目疑似被入侵,用 D 盾/河马扫一遍 WebShell。
- 沉淀规则:把这次发现的高频问题写成 Semgrep 规则,接进 CI,下次自动拦。
用工具的三条心法
工具用得好不好,差距往往不在工具本身,而在用法。三条心法送给你。
第一,工具是放大镜,不是大脑。 所有静态工具都有误报,它标红的地方不等于漏洞。它的价值是”帮你把值得看的地方圈出来”,最终”是不是洞、多严重、怎么修”永远要你自己判断。见到工具报一堆就慌、或者工具没报就放心,都是新手才犯的错。
第二,误报比漏报好,但都要治。 宁可工具多报你去过滤,也别调得太松漏掉真洞。但长期看,要通过自定义规则不断降低误报,否则每次几千条结果,你会累到直接不看。这就是为什么要善用 Semgrep 这种可自定义规则的工具,把团队的判断沉淀进规则里。
第三,静态与动态一定要配合。 只静态不动态,你永远在”猜”;只动态不静态,你会漏掉大量没被触发到的路径。两者交替,才既有覆盖面又有确定性。把 Xdebug 这个”动态验证器”用熟,是从”会扫”到”会审”的分水岭。
这一篇你该记住的
- PHP 审计工具分五类:静态分析(Seay/RIPS/Fortify/Semgrep/Progpilot)、类型分析(PHPStan/Psalm)、动态调试(Xdebug)、后门检测(D 盾/河马)、辅助(IDE 搜索/正则)。
- Seay 上手快、适合国产项目粗筛;Semgrep 规则可自定义、易接 CI;Progpilot 提供开源污点分析;CodeQL 不原生支持 PHP。
- Xdebug 是坐实漏洞的关键:静态找可疑点,动态断点复现,“静态找、动态证”是黄金节奏。
- 最高频的其实是 IDE 全局搜索 + 正则,
(\$_GET|\$_POST)\[、eval\s*\(、unserialize\s*\(随手就能捞洞。 - 工具只标可疑点,判断永远靠人;用自定义规则降误报,把审计沉淀进 CI。
下一篇我们切换到 Java 战场,先把 Java Web 的请求生命周期、危险 API 和调用链摸清,这是 Java 代码审计的地基。