文件包含基础

什么是文件包含?

程序开发人员通常会把一些可重复使用的函数写入某个文件中,这样在使用这些函数时,就可以直接调用此文件,,而无须重复编写函数代码,这种调用文件的过程就被称为文件包含。

为了实现代码复用,减少重复的工作量,文件包含在程序开发中被大量使用。如果网站开发人员对允许包含的文件没有严格的控制,就很有可能造成漏洞。

文件包含是 PHP 的一种文件加载机制。

常见:

include(); 如果被包含的文件不存在,会产生错误,,并停止运行脚本。

require(); 如果被包含的文件不存在,只会产生警告,脚本将继续运行。

include_once(); 与include类似,区别是,如果文件中的代码已经被包含。则不会再次包含

require_once(); 与require类似,区别是,如果文件中的代码已经被包含,则不会被再次包含

例如

复制代码
include('header.php');

意思就是:header.php 加载到当前 PHP 程序中。


include() 到底做了什么?

例如:include('test.php');

假设 test.php:<?php echo "Hello";

那么:

复制代码
include()
   ↓
找到 test.php
   ↓
读取文件
   ↓
PHP解析其中的PHP代码
   ↓
执行

所以 include() 和普通读取文件不一样。

例如:file_get_contents('test.php');

主要是:读取文件内容

而:include('test.php');是:加载文件,交给PHP处理


什么是文件包含漏洞?

正常情况下:include('header.php');

程序员自己决定:加载 header.php

但是如果写成:

file = _GET'file';

include($file);

就出现了一个关键问题:

复制代码
用户输入
   ↓
$_GET['file']
   ↓
$file
   ↓
include($file)

也就是说:**用户可以影响 include() 要加载哪个文件。**这就是文件包含漏洞的核心。


文件上传和文件包含到底有什么区别?

文件上传

解决的是:"文件怎么进入服务器?"

复制代码
用户
 ↓
上传文件
 ↓
服务器
 ↓
保存文件

关键:

复制代码
$_FILES
move_uploaded_file()

文件包含

解决的是:"程序加载哪个文件?"

复制代码
用户输入
 ↓
文件路径
 ↓
include()
 ↓
加载文件

关键:

复制代码
include()
require()

文件上传、文件包含为什么可以联系起来?

因为文件上传可以让服务器上出现一个新的文件。

而文件包含可以让 PHP 程序加载一个文件。

因此两者可以形成:

复制代码
文件上传
   ↓
服务器产生文件
   ↓
文件包含
   ↓
PHP加载这个文件

文件包含配合文件上传

虽然这是一个普通的文本文件,但是文件内容确实符号php语法规范,那么这些代码通过文件包含就可以正常被执行。

将txt的后缀名改成jpg,也可以正确显示phpinfo()信息。所以只有文件内容符号php语法规范,那么任何扩展名都可以通过文件包含被php解析。

在渗透测试中,通常会利用文件包含这个特点来配合文件上传,因为通常网站只会允许上传图片,如果网站还同时存在文件包含漏洞,就可以借助文件包含执行图片中的代码。

upload-13

在这里并没有通过扩展名来判断文件类型,而是直接读取了文件中的内容来进行判断。

对于系统中的大多数文件,每种文件类型文件的头部都会有一些固定的信息,用于标识文件的类型。

jpeg:FFD8FFE0

png:89504E47

gif:47494638

第2、、3、4行代码是以二进制的方式打开文件,然后读取文件的前两个字节,并保存到$bin变量中。

第五行代码unpack()函数将bin变量中的数据提取出来并保存到strInfo数组里。Cchars表示以十进制的形式表示数据,并且数组中每个元素的键名都是以chars开头,键名依次为chars1、chars2。。。。。

第6行将$strInfo中的两个数据拼接在一起,并用intval()函数转换成数值型数据。其中扩展名为gif的图片,就会得到7173。

7~21行,在case语句中判断,如果这个数据等于255216,那么就是扩展名为jpg的图片,如果为13780,就是png,7173就是gif

对于扩展名为jpg的图片,文件头部两字节为FFD8,也就是十进制255216。

所以这里只需在webshell的头部添加上图片文件中的头部信息即可。

复制代码
copy /b test.jpg + shell.php shell.jpg

准备1张png图片,2.txt的内容为<?php phpinfo();

/b Binary 二进制模式。制作图片马专用

上传成功,这里对图片进行了改名

使用这里的文件包含漏洞

文件包含利用成功

gif格式

由于gif格式的图片头部47494638正好是对应ASCII字符GIF89a

所以可以直接在记事本中这样编辑

上传成功

利用文件包含漏洞成功

文件包含防御

  • 输入验证与过滤
    • 对用户输入的文件路径进行严格验证,防止用户输入恶意路径。
    • 限制可访问的目录(例如:禁止访问 /etc、/bin 等系统目录)。
  • 使用固定的文件名
    • 通过预定义的文件名来避免动态包含用户提供的文件路径。
  • 避免使用用户提供的路径
    • 如果必须使用用户输入的数据,确保它们仅用于合法的、预定义的路径或文件。
  • 禁用远程文件包含
    • 禁止 PHP 中的 allow_url_fopen 和 allow_url_include 功能,防止远程文件包含漏洞。
  • 目录遍历限制
    • 使用 realpath () 等函数确保路径不包含任何目录遍历字符(如../)。
相关推荐
qq_4480111617 小时前
C语言中的动态内存分配
c语言·开发语言·php
叠层归一研究院19 小时前
AGI 系统(十一):二阶网络 — 二阶递归 × 多主体 (元符号网络)
开发语言·人工智能·算法·php·agi
数据知道20 小时前
反序列化漏洞:Java、PHP、Python 三条线各讲透
java·网络·python·安全·网络安全·php
江畔柳前堤21 小时前
Function Calling 与 Tool Calling:从认知到工程的全景深度解析
开发语言·网络·人工智能·深度学习·算法·机器学习·php
那年窗外下的雪.1 天前
AIDC 学习日志 Day 3:OSPF Underlay 实验、故障排查与深入解析
服务器·网络·php
Hello.Reader1 天前
REALITY 技术深度解析从 TLS 伪装、抗主动探测到 VLESS + XTLS Vision 完整实践
开发语言·php
catchadmin1 天前
Fiber 与 PHP 8.6 Polling API 异步初探
android·开发语言·php
梅菲塔亚1 天前
Keepalived高可用全解析
linux·运维·服务器·开发语言·网络·php
weixin_307779131 天前
PHP 大文件上传:内存占用、超时与最佳实践
linux·服务器·开发语言·nginx·php