应先执行php think route:list确认已注册路由,重点检查GET/POST中含变量参数的路径;未出现在列表中的控制器方法不可达,无需审计。

怎么快速确认入口是否可控
ThinkPHP 5.1.41 的路由机制决定了绝大多数请求最终会落到控制器方法上,所以审计第一件事不是翻代码,而是确认哪些 URL 路径能真正触发你关心的类和方法。用 php think route:list 查看已注册路由,重点看 GET 和 POST 类型中带变量参数的(如 /admin/user/edit?id=1),这些才是可能传入用户输入的地方。如果某个控制器方法没出现在列表里,它基本不可达——别花时间审计它。
哪些函数调用要立刻标记高危
在 TP5.1.41 中,以下函数一旦参数部分或全部来自用户输入(input()、request()->get()、request()->post() 等),必须立刻停下来分析:
-
unserialize():全局搜,但注意它是否在可访问路径下被调用;很多地方调用了,但没路由入口等于白搭 -
file_exists()、is_dir()、is_file():TP5.1.41 多处用于文件操作逻辑(如scanFilesForTree、upload),且常直接拼接$_GET['dir'],极易触发phar://反序列化 -
extract():出现在模板渲染链路(View->fetch->read),若$vars来自assign(request()->get()),就可能覆盖$cacheFile导致任意文件包含 -
call_user_func()、call_user_func_array():如 DolphinPHP 的action_log中,第一个参数若由数据库字段或用户输入控制,就是 RCE 高危点
Linux 下大小写和路径敏感是硬伤
TP5.1.41 默认启用自动加载与命名规范校验,但很多开发者忽略这点,导致审计时漏掉真实漏洞:
- 控制器类名必须 PascalCase(
UserController),方法名必须小写(index),否则 404 不进框架——但攻击者若知道真实类名(如通过报错、目录遍历),仍可能绕过路由直访index.php?s=/user/index -
public/是 Web 入口根目录,application/不应被 Web 直接访问;检查.htaccess或 Nginxlocation /是否禁掉了application/目录,否则配置文件、路由定义等可能被下载 - Linux 文件系统区分大小写,
app/controller/Index.php和app/controller/index.php是两个文件;有些 CMS 把控制器放错位置,结果框架加载失败,但 Web 服务器直接返回源码——这是信息泄露温床
缓存和配置文件别当成“死数据”
TP5.1.41 的 runtime/ 目录默认可写,里面缓存的路由、模板编译结果、日志都可能被污染或反向利用:
立即学习“PHP免费学习笔记(深入)”;
-
runtime/cache/下的 PHP 缓存文件若未严格校验后缀,上传恶意文件并重命名为xxx.php后,可能被include执行 -
config.php或数据库配置若被写入攻击者可控路径(如上传路径配置成phar://xxx),后续调用is_dir($config['upload_path'])就会触发反序列化 - 某些插件或模块会把用户输入持久化进
runtime/下的 JSON 或 PHP 文件,下次加载时若不做反序列化过滤,unserialize(file_get_contents(...))就成了固定入口
真正卡住审计进度的,往往不是找不到 unserialize,而是没意识到 $dir = input('get.dir') 传给 is_dir() 这种“看起来无害”的组合,在 Linux + Phar 环境下就是一把打开 RCE 的钥匙。别只盯函数名,盯参数流向。



















