文件上传漏洞实战:从upload-labs靶场到安全防御全解析

发布时间:2026/6/25 15:59:15
文件上传漏洞实战:从upload-labs靶场到安全防御全解析 1. 项目概述从靶场搭建到漏洞原理的深度实践文件上传漏洞这个在Web安全领域几乎与SQL注入、XSS并列的“经典三巨头”之一其危害性往往被低估。很多刚入门安全测试的朋友可能觉得它无非就是找个上传点传个一句话木马然后菜刀连接。但真正深入到实战和代码审计层面你会发现绕过前端校验、服务端MIME类型检查、文件内容检测、目录路径解析、甚至到WAF规则每一步都充满了攻防双方的智慧博弈。单纯看理论文章总有种隔靴搔痒的感觉总觉得懂了一上手就懵。这正是我决定亲手搭建并通关upload-labs-master这个经典文件上传漏洞靶场的初衷——不是为了一键通关脚本而是为了在可控的环境里把每一种绕过手法的原理、限制条件和对抗思路像解剖麻雀一样掰开揉碎了看明白。upload-labs-master是一个用PHP编写的、专门用于学习和练习文件上传漏洞的靶场项目。它设计了从易到难共计21个关卡Pass-01到Pass-21每一关都模拟了一种或多种常见的服务端防御机制。你的任务就是利用不同的技术手段成功上传一个可执行的Webshell通常是PHP文件并最终访问它。这个过程本质上就是一场完整的黑盒与白盒测试结合的训练。通过它你不仅能熟悉各种绕过技巧更能深刻理解开发者在编写上传功能时常犯哪些错误以及应该如何从代码层面进行加固。对于Web开发人员、安全测试工程师、甚至是CTF选手来说这都是一个极佳的、从理论到实践的跳板。2. 靶场环境搭建与核心配置解析动手之前一个稳定、隔离的测试环境是必须的。我强烈建议使用虚拟机或Docker来搭建避免对宿主机环境造成任何意外影响。这里我以最经典的“PHP Apache MySQL”组合为例在本地虚拟机中进行部署。2.1 基础运行环境准备首先你需要一个Web服务器和PHP解析环境。对于Windows用户一键安装包如PHPStudy、XAMPP是最高效的选择。以PHPStudy为例安装后其默认的网站根目录通常是www目录。将下载好的upload-labs-master文件夹解压并整个放入www目录下。此时通过浏览器访问http://localhost/upload-labs-master/应该就能看到靶场的首页界面。对于Linux用户或追求环境纯净度的朋友使用Docker是更优雅的方案。你可以直接使用集成了Apache和PHP的官方镜像。# 这是一个简单的Docker运行命令示例 docker run -d --name upload-labs -p 8080:80 -v /your/local/path/upload-labs-master:/var/www/html php:7.4-apache执行后访问http://localhost:8080即可。Docker方式将环境完全容器化清理起来也异常方便。注意upload-labs-master靶场本身不依赖数据库因此无需单独配置MySQL。这简化了搭建过程让我们能更专注于文件上传逻辑本身。2.2 靶场文件结构与关键配置检查解压后的upload-labs-master目录结构清晰Pass-01.php到Pass-21.php 每个关卡的前端上传页面。upload文件夹 这是服务端指定或默认的上传文件保存目录是攻防的核心焦点。include文件夹 存放一些共享的函数和类例如连接数据库的配置虽然本靶场未使用但结构如此、一些过滤函数等。其他如index.php首页、check.php统一检查文件等。搭建完成后第一件要做的事是检查upload目录的权限。在Linux系统或Docker容器中务必确保Web服务器进程通常是www-data用户或apache用户对该目录有写入权限。你可以通过以下命令修改chmod 755 upload # 或 chmod 777 upload 测试环境可放宽生产环境绝对禁止在Windows下的PHPStudy通常目录权限是继承的如果遇到上传失败请检查www目录及其子目录是否被其他安全软件限制了写入权限。第二个关键点是检查PHP配置文件php.ini中的几个关键选项它们直接影响文件上传的行为file_uploads On 确保文件上传功能是开启的。upload_max_filesize 2M 允许上传的最大文件大小。对于上传小体积的Webshell绰绰有余但如果你的绕过手法涉及上传超大文件以触发某些异常可能需要调整。post_max_size 8M POST请求的最大尺寸必须大于upload_max_filesize。max_execution_time 脚本最大执行时间一般默认即可。修改php.ini后记得重启Apache或PHP-FPM服务使配置生效。在PHPStudy面板中操作非常直观。3. 漏洞原理深度剖析与关卡设计思想在开始闯关之前我们必须建立起对文件上传漏洞本质的认知。漏洞的根源在于服务端对用户上传的文件数据未进行充分、多维度、不可绕过的合法性校验就将其保存到了服务器磁盘的可访问路径下并且该文件能够被Web服务器以脚本语言如PHP、JSP、ASP解析执行。upload-labs-master的21个关卡就是围绕“校验”这个核心层层加码模拟了现实中可能遇到的各种防御场景。我们可以将这些防御点归纳为以下几个层面而关卡则是这些层面的不同组合与实现3.1 客户端校验前端校验这是最薄弱的一环通常指使用JavaScript在浏览器端对文件扩展名、大小等进行的检查。代表关卡Pass-01。绕过方式极其简单禁用浏览器JS、使用Burp Suite等工具拦截修改请求、或者直接使用curl命令发送请求。其设计思想是告诫开发者绝对不要信任客户端传来的任何数据前端校验仅用于提升用户体验和减少无效请求绝不能作为安全依据。3.2 服务端MIME类型检查MIME类型是由客户端在HTTP请求头Content-Type中声明的告诉服务器“我认为这个文件是什么类型”。例如一个图片的MIME可能是image/jpeg一个PHP脚本的MIME是application/x-php或text/php。服务端可能会检查这个值。代表关卡Pass-02、Pass-03。绕过方式使用Burp Suite拦截上传请求将Content-Type修改为允许的类型如image/jpeg。这揭示了攻击者可以完全控制请求头仅检查MIME类型是无效的。3.3 服务端文件扩展名后缀黑名单/白名单校验这是最核心、也最复杂的防御层。黑名单即禁止上传某些危险后缀如.php,.asp,.jsp白名单则只允许上传某些安全后缀如.jpg,.png,.gif。黑名单的绕过方式五花八门Pass-04到Pass-11集中体现例如大小写绕过Pass-04.Php、.pHP。点号绕过Pass-05 利用Windows系统自动去除文件名末尾点号的特性上传shell.php.。空格绕过Pass-06 上传shell.php末尾有空格Windows系统同样会去除。::$DATA流绕过Pass-07 Windows NTFS文件流特性shell.php::$DATA在存储时会变成shell.php。点空格点绕过Pass-08shell.php. .。双写后缀绕过Pass-09 当代码使用str_ireplace等函数删除黑名单后缀时上传shell.pphphp删除中间的php后剩余部分拼接成shell.php。0x00截断绕过Pass-11 在GET参数中利用%00URL编码的空字符截断配合服务端$_GET获取参数后未经过滤的拼接操作如../upload/shell.php%00.jpg最终保存为shell.php。此方法在PHP版本低于5.3.4且magic_quotes_gpcOff时可能生效。白名单校验Pass-12之后成为主流则严格得多它只允许.jpg,.png,.gif等。此时攻击思路必须转变从“欺骗后缀”转向结合文件包含漏洞 上传一个内容为PHP代码的图片马.jpg然后利用网站其他存在的本地文件包含LFI漏洞去包含这个图片使其中的PHP代码被执行。结合服务器解析漏洞 利用Web服务器如Apache、IIS、Nginx在特定配置下对文件路径的解析特性。例如Apache的mod_rewrite规则错误、IIS6.0的/xx.asp;.jpg分号解析漏洞、IIS7.0/7.5的Fast-CGI解析漏洞xx.jpg/.php、Nginx的%00解析漏洞旧版本等。upload-labs的Pass-13IIS6.0解析漏洞、Pass-14.htaccess攻击就属于此类。竞争条件攻击 在文件被上传到临时目录、但尚未被安全检查逻辑移动到最终目录的极短时间窗口内访问或执行该文件。这需要代码逻辑存在“先保存后检查再删除”的不严谨操作。3.4 服务端文件内容校验这是更高级的防御不仅看“文件名”还要看“文件内容”。文件头检查Pass-15, Pass-16 检查文件开头的几个字节魔数例如GIF89a、FF D8 FF E0JPEG。绕过方式是在Webshell代码前添加正确的文件头字节。getimagesize()函数检查Pass-17 PHP的getimagesize()函数会读取图像文件并返回其尺寸等信息如果不是有效图片则返回false。绕过方式是制作一个包含Webshell代码的真图片马使用图像处理库如GD将PHP代码写入图像的EXIF信息如注释中或者直接创建一个最小尺寸的合法图片如1x1像素的GIF再将代码追加其后。copy /b normal.jpg shell.php webshell.jpg命令可以简单拼接。二次渲染绕过Pass-18 这是最难的关卡之一。服务端使用imagecreatefromjpeg()等函数对上传的图片进行“二次渲染”即重新压缩、生成新的图片这会彻底破坏直接追加在文件末尾的代码。绕过需要对图片格式的编码结构有深入理解找到那些在二次渲染后仍能保留数据的“容器”如图片的注释段COM、应用数据段APPn。这通常需要编写专门的脚本在图片的特定位置插入Payload。理解了这些层次我们再去看每一个关卡就不再是盲目尝试各种“骚操作”而是能清晰地定位到“这一关它在哪个或哪几个层次做了校验它的校验逻辑代码可能存在什么缺陷” 带着这种思想去审计每个Pass-xx.php的源代码学习效率会倍增。4. 核心绕过技术实战与代码审计详解接下来我将选取几个有代表性的关卡结合实战操作和代码片段深入讲解绕过手法。我假设你已准备好Burp Suite作为抓包改包工具这是安全测试的标配。4.1 实战Pass-01前端JS校验绕过这是入门关。打开Pass-01页面选择任何一个非图片文件如.php点击上传通常会立刻弹出“文件类型不正确”的警告。我们打开浏览器开发者工具F12查看网页源代码很容易在script标签里找到一段JavaScript校验函数它检查了文件的扩展名。绕过步骤直接打开Burp Suite配置好代理并确保浏览器流量经过Burp。在Pass-01页面先选择一个合法的图片文件如.jpg然后点击上传。此时Burp Suite的Proxy模块会拦截到HTTP POST请求。切换到Proxy - Intercept确保拦截是On状态。在Burp的拦截界面你可以看到完整的HTTP请求。找到代表文件内容的那个部分通常是一个multipart/form-data格式的body你会看到一行类似Content-Disposition: form-data; nameupload_file; filenamenormal.jpg的内容。将filenamenormal.jpg直接修改为filenameshell.php。同时你也可以将文件内容部分在Content-Type: image/jpeg下面替换为你的一句话木马代码例如?php eval($_POST[cmd]);?。点击Forward按钮放行这个被修改的请求。回到浏览器你会发现上传成功了并且页面返回了上传文件的路径如../upload/shell.php。实操心得很多新手会卡在第一步——直接上传.php文件被前端拦截。关键在于前端校验发生在请求发出之前。我们的策略是“先通过前端校验再在传输过程中篡改”。所以先用一个合法文件“骗过”前端JS生成合法的HTTP请求再在Burp中将其“偷梁换柱”。这是Web安全测试中“绕过客户端控制”的基本思维。4.2 实战Pass-05点号与Windows特性绕过查看Pass-05的源码会发现它使用了strtolower()统一转小写然后使用deldot()函数删除末尾的点最后使用黑名单检查后缀。deldot()函数的逻辑是循环删除末尾的点直到最后一个字符不是点为止。function deldot($s){ for($i strlen($s)-1; $i0; $i--) { if($s[$i] .) { $s substr($s, 0, $i); } else { break; } } return $s; } // 调用$file_name deldot($file_name);绕过步骤准备一个名为shell.php. .点空格点的文件。注意最后一个点后面可能有一个空格在Windows资源管理器里可能不显示但在Burp里能看到。直接上传这个文件。服务端逻辑如下strtolower(shell.php. .)-shell.php. .deldot(shell.php. .) 函数从末尾开始删点。它先删掉最后一个点. .的最后一个点字符串变为shell.php.末尾是空格点这里需要仔细分析。实际上deldot函数遇到非点字符就会停止。对于shell.php. .最后一个字符是点删除得到shell.php.末尾是空格。下一个字符是空格不是点循环停止。所以最终返回shell.php.。然后代码用$file_ext strrchr($file_name, .)获取后缀对于shell.php.strrchr会找到最后一个点即.php.但这通常不是有效的扩展名分割。关键在于当这个文件名被保存到Windows系统时系统会自动去除文件名末尾的空格和点。于是磁盘上实际保存的文件名就变成了shell.php。上传成功后访问该文件即可。注意事项这个绕过严重依赖于Windows操作系统的文件命名特性。在Linux服务器上这个手法是无效的因为Linux会严格保留文件名中的空格和点。这提醒我们在测试时了解目标服务器的操作系统至关重要。同时这也暴露了黑名单校验的另一个问题校验逻辑和最终保存文件的系统逻辑不一致。4.3 实战Pass-12白名单校验与%00截断POSTPass-12是一个重要的转折点它开始使用白名单只允许jpg,png,gif。同时它提供了一个“保存路径”的输入框并且代码中使用$_POST来获取这个路径然后与文件名拼接。关键源码如下$file_name $_POST[save_name]; $img_path UPLOAD_PATH . / . $file_name;并且代码在拼接前似乎没有对$file_name进行过滤。这里就存在%00截断漏洞空字符截断的利用条件。在C语言等底层中空字符\0ASCII码为0是字符串的结束符。PHP在某些情况下也会认这个结束符。绕过步骤POST型在Pass-12的上传页面先选择一个内容为PHP代码的图片马例如一个正常的.jpg文件用记事本打开在文件末尾添加?php phpinfo();?。在“保存名称”输入框中填写shell.php%00.jpg。注意这里输入的是字面字符%00。直接上传。你会发现上传失败。这是因为%00在POST请求的Body中默认不会被URL解码。%00只有在URLGET请求的参数中才会被自动解码为空字符。正确做法是使用Burp Suite拦截上传请求。在Burp拦截的请求Raw Body中找到save_name参数。它看起来像save_nameshell.php%2500.jpgBurp可能自动编码了%为%25。你需要将其修改为save_nameshell.php%00.jpg。注意这里的%00必须是原始的十六进制字节而不是字符。在Burp的拦截窗口中切换到Hex视图找到对应s...h...e...l...l... .p...h...p...的ASCII码部分将.jpg前面的字符比如2E是点替换为00。更简单的方法是在Raw视图下直接修改文本为save_nameshell.php .jpg然后在php和.jpg之间右键选择Insert byte输入00。你会看到那个位置变成了一个空格在Raw视图里显示为一个点或乱码。放行请求。如果PHP版本较低5.3.4且magic_quotes_gpc关闭服务端在拼接路径UPLOAD_PATH . / . $file_name时遇到空字符\0就会认为字符串到此结束。因此$img_path的值实际上是../upload/shell.php后续的.jpg被截断。文件最终会以shell.php的名字保存。排查技巧%00截断成功率受PHP版本和配置影响极大。PHP 5.3.4之后该漏洞被基本修复。因此在现代Web环境中此方法已很少奏效。但它仍然是安全测试中一个必须知道的历史经典漏洞并且在代码审计时看到未过滤的用户输入直接拼接进文件路径就要高度警惕路径遍历和截断问题。4.4 实战Pass-17getimagesize()绕过与图片马制作Pass-17使用getimagesize($_FILES[upload_file][tmp_name])来检查文件是否为有效图片。如果不是则拒绝。这意味着简单的文件头欺骗只在文件开头加GIF89a可能不够因为getimagesize()会解析整个图像结构。绕过步骤我们需要制作一个能通过getimagesize()检查的真正的图片马。方法一使用命令拼接Windows这是最简单的方法但生成的图片马可能在某些严格的二次渲染检查中失效。准备一张正常的normal.jpg图片和一个shell.php文本文件内容为?php eval($_POST[cmd]);?。在Windows命令行中执行copy /b normal.jpg shell.php webshell.jpg这个命令将shell.php的内容追加到normal.jpg的末尾生成webshell.jpg。图片查看器仍能正常显示因为图像解码器会忽略文件末尾的额外数据。但getimagesize()函数只读取图像数据部分遇到文件结束标记后就会停止因此能通过检查。上传webshell.jpg会成功。但是直接访问webshell.jpgPHP引擎不会解析追加在后面的代码。我们需要结合文件包含漏洞。假设网站存在include($_GET[file]);这样的漏洞我们就可以访问http://target.com/include.php?file../upload/webshell.jpg从而执行其中的PHP代码。方法二使用GD库将代码写入EXIF数据更隐蔽PHP的GD库可以读取和生成图片并且可以操作EXIF数据拍摄信息、注释等。编写一个PHP脚本create_image.php?php // 创建一个1x1像素的透明PNG图像体积最小 $img imagecreatetruecolor(1, 1); imagesavealpha($img, true); $color imagecolorallocatealpha($img, 0, 0, 0, 127); imagefill($img, 0, 0, $color); // 将一句话木马写入图像文件的注释COM段 // 注意exif_read_data/exif_write_data通常用于JPEG的EXIFPNG的元数据操作更复杂。 // 更通用的方法是直接写入文件内容。这里演示一个简单但可能不适用于所有检查的方法。 $shell_code ?php eval($_POST[\cmd\]);?; // 保存图像 imagepng($img, webshell_with_code.png); imagedestroy($img); // 方法将代码追加到PNG文件末尾PNG文件以IEND块结束之后的数据会被忽略 file_put_contents(webshell_with_code.png, $shell_code, FILE_APPEND); echo 图片马生成成功webshell_with_code.png; ?执行这个脚本生成图片马。这个图片马能通过getimagesize()因为IEND块之后的数据不影响图像解析。上传此文件。同样需要文件包含漏洞来触发。实操心得对抗内容检查核心思路是“构造一个在图像解析器看来是合法图片但同时包含恶意代码的文件”。getimagesize()是较弱的检查它只验证图像结构。更强大的检查如Pass-18的二次渲染需要更精细的构造将代码嵌入到图像文件的特定数据段如PNG的tEXt块或JPEG的COM注释段这些段在图像重构时会被保留。这需要深入研究图像文件格式规范。5. 高阶关卡与组合漏洞利用思路从Pass-13开始靶场引入了服务器解析漏洞和.htaccess攻击这需要我们对Web服务器配置有一定了解。5.1 Pass-13IIS6.0解析漏洞复现此关模拟了旧版本IIS6.0的一个著名漏洞。在IIS6.0下如果目录名包含.asp、.asa、.cer等扩展名则该目录下的所有文件都会被当作ASP脚本来解析。同时对于文件xx.asp;.jpgIIS6.0会忽略分号后的内容将xx.asp;.jpg解析为xx.asp。由于我们的靶场是ApachePHP环境要复现这个漏洞需要手动模拟或理解原理。实际上upload-labs的Pass-13可能简化了场景它可能只是检查了文件名中是否包含php字符串然后利用Windows的特性分号在文件名中允许来绕过。更准确的IIS6.0漏洞利用需要在真实IIS6.0环境中进行。思路延伸在现代开发中虽然IIS6.0已很少见但这种“服务器异常解析”的思想很重要。例如在配置不当的NginxPHP-FPM环境中可能因为PATH_INFO或fastcgi_split_path_info配置问题导致/upload/shell.jpg/xxx.php被解析为PHP文件。这提醒我们安全不仅在于应用代码也在于运行环境配置。5.2 Pass-14.htaccess攻击实战这是Apache服务器特有的、威力巨大的一种攻击手法。.htaccess是Apache的分布式配置文件可以覆盖其所在目录及子目录的服务器配置。如果服务器允许上传目录覆盖.htaccess文件且该目录有执行权限攻击者就可以通过上传一个恶意的.htaccess文件将特定扩展名如.jpg的文件当作PHP来解析。绕过步骤首先需要判断目标上传目录是否允许.htaccess生效。通常如果是一个普通的图片上传目录且AllowOverride指令被设置为All或包含FileInfo就有可能生效。在upload-labs中这个条件是预设的。制作一个.htaccess文件内容如下AddType application/x-httpd-php .jpg这行配置告诉Apache将.jpg后缀的文件当作PHP应用程序来解析。将.htaccess文件上传到靶场的upload目录。注意文件名就是.htaccess没有后缀。在Windows下可能无法直接创建可以在命令行使用echo AddType application/x-httpd-php .jpg .htaccess命令创建或者使用文本编辑器保存时选择“所有文件”类型文件名输入.htaccess。上传成功后再上传一个内容为PHP代码的shell.jpg文件。直接访问http://your-target/upload-labs-master/upload/shell.jpg你会发现原本是图片的文件现在其中的PHP代码被执行了。注意事项与防御.htaccess攻击成功的前提非常苛刻1) 目标服务器是Apache2) 上传目录的AllowOverride配置允许覆盖FileInfo3) 上传目录有执行权限。在生产环境中规范的作法是禁止上传目录有任何脚本执行权限并通过Web服务器配置如php_admin_value engine off直接在该目录禁用PHP引擎。同时严格限制上传文件的类型和重命名上传文件避免用户控制文件名。6. 防御方案与安全开发建议在通关了整个upload-labs-master后我们站在防御者的角度总结一下一个健壮的文件上传功能应该如何设计6.1 使用白名单而非黑名单这是最重要的原则。只允许业务必需的文件类型例如只允许jpg, jpeg, png, gif。白名单应该在服务端用数组硬编码定义。6.2 文件重命名上传的文件不要使用用户提供的原始文件名。应使用随机生成的文件名如UUID、MD5(时间戳随机数)并保留原始扩展名从白名单中获取。例如a1b2c3d4e5f6.jpg。这可以防止路径遍历、截断攻击也避免了文件名冲突。6.3 校验文件内容MIME类型检查 使用PHP的finfo_file(FILEINFO_MIME_TYPE)或mime_content_type()函数检测文件的真实MIME类型而不是信任$_FILES[file][type]。文件头检查 结合白名单读取文件前几个字节进行比对。图像二次渲染 对于图片使用GD库或ImageMagick等库将上传的图片重新生成一张新的图片。这是最有效的防御手段之一可以彻底清除嵌入在图像数据中的恶意代码。注意生成后要删除原始上传的临时文件。6.4 控制文件权限上传目录应位于Web根目录之外避免用户直接通过URL访问。如果必须在Web目录下则通过脚本如download.php?idxxx来读取文件并在脚本中做权限和类型检查。设置上传目录无执行权限。在Apache中可以在.htaccess或虚拟主机配置中添加php_flag engine off。设置正确的文件系统权限遵循最小权限原则。6.5 限制文件大小与频率在php.ini和表单中限制单个文件大小和总上传大小。在应用层面可以对用户单位时间内的上传次数进行限制防止DoS攻击或垃圾文件上传。6.6 使用安全的第三方库或云服务对于复杂的上传需求如文档、视频考虑使用经过严格安全审计的第三方库如Dropzone.js配合服务端严格校验或者直接集成云存储服务如AWS S3、阿里云OSS、腾讯云COS。云服务商通常提供了完善的上传SDK和丰富的安全策略如防盗链、生命周期管理可以将安全风险转移。6.7 定期安全扫描与清理对上传目录进行定期扫描检查是否有异常文件如.htaccess、.user.ini或非白名单类型的文件。设置文件自动清理策略删除超过一定时间的临时文件。7. 常见问题排查与实战心得在搭建和通关过程中你可能会遇到以下问题7.1 上传成功但无法访问/执行权限问题 检查upload目录的权限确保Web服务器用户如www-data有读和执行对于需要包含的图片马目录需要rx权限权限。在Linux下ls -la upload。路径问题 靶场返回的路径可能是相对路径如../upload/shell.php。访问时需要根据你的实际URL进行拼接例如http://localhost/upload-labs-master/upload/shell.php。解析问题 确保你上传的Webshell文件内容是正确的PHP代码并且以?php ... ?包裹。如果上传的是图片马确认你是否利用了文件包含漏洞并且包含路径正确。7.2 Burp Suite拦截不到请求代理未开启或配置错误 确认Burp的Proxy监听端口默认8080是开启的并且浏览器或系统代理正确配置到了该端口。HTTPS问题 如果靶场是HTTPS需要在浏览器中安装并信任Burp Suite的CA证书否则HTTPS流量无法被解密拦截。拦截开关未打开 在Burp的Proxy - Intercept标签页确认Intercept is on按钮是红色的激活状态。7.3%00截断攻击不成功PHP版本过高 确认你的PHP版本。%00截断在PHP 5.3.4及以上版本被修复。magic_quotes_gpc配置 如果该配置为On传入的%00会被转义为\0失去截断作用。但在PHP 5.4.0后此配置已被移除。编码问题 确保在Burp中修改的是十六进制值00而不是字符%00。在POST请求的Body中需要在Hex视图下修改。7.4 图片马上传后包含执行失败代码被破坏 如果服务端有二次渲染简单的文件末尾追加代码会被清除。需要使用更高级的技巧将代码写入图片的元数据段。包含函数限制 确认文件包含漏洞使用的函数是include、require还是include_once等。有些配置如allow_url_includeOff会限制包含远程文件或特定协议。代码被转义 如果图片马中的PHP代码被当作纯文本输出可能是因为包含文件的上下文不是PHP解析环境例如被包含的文件后缀不在Apache的PHP解析规则内。确保包含的路径最终指向一个会被PHP解析的文件或者利用.htaccess攻击改变了解析规则。个人实战体会upload-labs-master的价值远不止于教会你21种绕过方法。它更像一个引子强迫你去思考每一行防御代码可能存在的逻辑缺陷去理解操作系统、Web服务器、编程语言特性与安全之间的微妙关系。我建议在通关后不要满足于“过关”而是去仔细阅读每一关的源代码尝试修改代码加固它然后再尝试攻击自己加固后的版本。这个“攻防角色互换”的过程才是提升安全能力的快车道。最后永远记住在安全的世界里没有一劳永逸的防御只有持续的攻击视角和严谨的代码实践。