仅靠disable_functions不够,因其仅软性禁用函数调用,无法阻止proc_open调用cmd.exe、扩展触发反序列化链、上传文件二次执行等绕过方式;真正有效的是结合open_basedir限制路径、windows权限隔离目录并关闭allow_url_include等组合策略。

Windows 7 下 PHP 环境默认不设防,eval、system、exec 等函数一旦被 Web 应用误用,配合用户可控输入,极易触发 RCE(远程代码执行)。仅靠禁用函数不够——攻击者常绕过 disable_functions,真正有效的防线是「从执行源头掐断」:限制 PHP 进程对危险目录的访问权限。
为什么不能只靠 disable_functions?
disable_functions 是 PHP 层面的软性拦截,它只禁用函数调用,但不阻止以下行为:
- 通过
proc_open+cmd.exe或bash绕过(尤其在 Windows 下,cmd未被禁用时) - 利用已加载的扩展(如
imap、exif)触发反序列化链执行任意代码 - 写入临时文件后通过 Web 可访问路径(如
/uploads/shell.php)二次触发 - PHP-FPM 模式下,若配置了
security.limit_extensions = .php但未限制脚本实际存放位置,仍可能被上传并执行
用 Windows 权限系统隔离危险目录
核心思路:让 PHP 进程(通常是 IIS_IUSRS 或 Users 组下的服务账户)对特定目录「不可读、不可执行、不可遍历」。不是删文件,而是砍权限。
- 找到你的 Web 根目录(如
C:\ESSamp\wwwroot)和所有允许上传的目录(如C:\ESSamp\wwwroot\uploads) - 右键 → 「属性」→ 「安全」→ 「编辑」→ 「添加」,输入
IIS_IUSRS(IIS)或Users(Apache/Nginx + php-cgi) - 为该用户组取消勾选「读取和执行」、「列出文件夹内容」、「读取」——只保留「写入」(仅对上传目录)
- 特别注意:上传目录绝对不要给「执行」权限;若用的是 Apache,还需确认
httpd.conf中有Options -ExecCGI或RemoveHandler .php针对该目录
php.ini 关键加固项(非可选)
这些配置必须显式设置,不能依赖默认值:
-
disable_functions = exec,passthru,shell_exec,system,proc_open,popen,pcntl_exec(注意逗号后无空格) -
open_basedir = C:\ESSamp\wwwroot;C:\ESSamp\tmp(严格限定 PHP 只能访问指定路径,多个路径用分号隔开) -
allow_url_include = Off(关闭远程文件包含,防止include($_GET['f'])加载恶意 URL) -
expose_php = Off(隐藏 HTTP 响应头中的X-Powered-By: PHP/5.6.25,减少指纹暴露)
验证是否生效的实操检查点
改完配置后别急着重启,先人工验证几个关键点:
- 在浏览器访问
http://localhost/uploads/test.php(假设你刚上传了一个含phpinfo()的文件)——应返回 403 或 404,而非执行结果 - 在命令行运行
php -r "echo file_get_contents('C:/Windows/win.ini');"—— 若open_basedir生效,会报Warning: file_get_contents(): open_basedir restriction in effect - 检查 Windows 事件查看器 → 「Windows 日志 → 安全」,筛选「审核对象访问失败」事件,确认 PHP 进程确实在尝试访问被拒路径时留下记录
最易被忽略的是:权限设置后未重启对应服务(Apache/Nginx/IIS),或忘了把 PHP 进程实际运行账户(而非当前登录用户)加入权限列表。Windows 权限不继承、不缓存,但生效有延迟——改完等 30 秒再测。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











