应通过php.ini全局禁用exec等危险函数,配合nginx fastcgi参数覆盖、open_basedir隔离、禁用pcntl等高危扩展及nginx执行层防护,形成五重不可绕过防线。

如果您在PHP环境中发现exec函数仍可被调用,攻击者可能借此执行任意系统命令并写入Web Shell,从而完全控制服务器。以下是多种相互补充、不可绕过的禁用exec函数的具体方法:
一、通过php.ini全局禁用exec及相关危险函数
该方法直接作用于PHP解释器层,是阻断exec调用的第一道硬性屏障。它要求显式列出所有可触发系统执行的函数,避免因遗漏导致绕过。
1、使用命令php --ini(CLI模式)或<?php echo php_ini_loaded_file(); ?>(Web模式)确认实际生效的php.ini路径。
2、用文本编辑器打开该php.ini文件,在配置节中查找disable_functions项;若被注释则删除行首分号。
3、在等号后严格按以下格式填写函数列表:disable_functions = exec,passthru,shell_exec,system,proc_open,popen,pcntl_exec,pcntl_fork,pcntl_waitpid,注意逗号后不得有任何空格。
4、保存文件后,根据运行模式执行对应重启操作:Apache环境执行sudo systemctl restart apache2;PHP-FPM环境执行sudo systemctl reload php-fpm。
二、在Web服务器层强制覆盖disable_functions(Nginx/FastCGI专用)
当无法修改主php.ini(如共享主机、Docker多租户场景),可通过FastCGI参数动态注入禁用规则,该方式优先级高于php.ini,且不依赖服务重启即可热生效。
1、在Nginx的server或location块中,添加fastcgi_param指令:fastcgi_param PHP_ADMIN_VALUE "disable_functions=exec,shell_exec,passthru";。
2、确保该指令位于include fastcgi_params;之后,避免被后续配置覆盖。
3、验证是否生效:创建测试脚本输出ini_get('disable_functions'),结果应包含上述函数名。
4、必须同步配置security.limit_extensions = .php,防止攻击者上传.php5、.phtml等扩展名绕过PHP解析限制。
三、启用open_basedir实现文件操作隔离
即使exec被禁用,攻击者仍可能通过写入临时文件+其他未禁函数(如file_put_contents + include)完成二次利用。open_basedir可切断其落地路径,使payload无法写入可访问目录。
1、在php.ini中设置open_basedir = /var/www/html:/tmp:/var/tmp,其中/var/www/html为网站根目录,/tmp为必需的临时目录。
2、若使用Nginx+PHP-FPM,也可在pool配置中添加php_admin_value[open_basedir] = /var/www/html:/tmp。
3、重启PHP-FPM使配置生效,并测试file_put_contents('/etc/passwd', 'test')是否抛出Warning“failed to open stream: Operation not permitted”。
4、严禁将open_basedir设为空值或/,否则等同于未启用。
四、禁用高危扩展并限制opcode行为
disable_functions对扩展函数(如pcntl、posix、imap)中的系统调用无效。攻击者可借助这些扩展绕过禁用,因此需从源头移除执行能力。
1、检查已启用扩展:php -m | grep -E "(pcntl|posix|imap|curl)",对非业务必需的扩展执行禁用。
2、在php.ini中添加extension=pcntl.so前加;注释,或在FPM pool中添加php_admin_flag[disable_functions] = on(仅限支持版本)。
3、启用OPcache并限制API访问:opcache.enable=1与opcache.restrict_api="/dev/null"(PHP 7.4+),防止通过opcache_get_status()泄露信息或触发JIT漏洞。
4、pcntl扩展默认不应启用,若业务未使用fork/wait机制,必须彻底禁用。
五、Web服务器执行层兜底防护(Nginx关键配置)
所有PHP层防护均可能被上传的恶意PHP文件绕过。必须在Nginx层面阻止用户目录下PHP脚本的解析与执行,形成最后一道防线。
1、在Nginx主配置或server块中添加严格location规则:location ~ ^/uploads/.*\.php$ { return 403; }。
2、校验fastcgi_param SCRIPT_FILENAME的取值是否为$document_root$fastcgi_script_name,严禁使用$request_filename,防止路径遍历构造任意文件执行。
3、对静态资源目录(如/static/、/images/)统一添加location ~ \.(php|phar|phtml|php5)$ { deny all; }。
4、所有上传目录必须配置return 403,且该规则需置于通用PHP location之前,确保优先匹配。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











