简析文件包含漏洞

一、文件包含漏洞简介

1、原理

服务器执行PHP文件时,可以通过文件包含函数加载另一个文件中的PHP代码,并且当PHP来执行,这可以给开发者节省大量的时间。而这也导致客户端可以调用一个恶意文件,造成文件包含漏洞。

2、文件包含漏洞利用的前提条件

1)web 应用采用 include 等文件包含函数,并且需要包含的文件路径是通过用户传输参
数的方式引入。
2)用户能够控制包含文件的参数,被包含的文件可被当前页面访问。

3、文件包含获取 webshell 的条件

1)攻击者需要知道文件存放的物理路径
2)对上传文件所在目录拥有可执行权限
3)存在文件包含漏洞

4、典型特征

变量的值变成一个页面

?page=a.php
?home=b.html
?file=content
...

5、分类

文件包含漏洞共分为两大类,本地文件包含远程文件包含

 

二、文件包含函数

PHP中文件包含函数有以下四种:

require()
include()

require_once()
include_once()

include和require区别主要是,include在包含的过程中如果出现错误,会抛出一个警告,程序继续正常运行;而require函数出现错误的时候,会直接报错并退出程序的执行。

而include_once(),require_once()这两个函数,与前两个的不同之处在于这两个函数只包含一次。适用于在脚本执行期间同一个文件有可能被包括超过一次的情况下,想确保它只被包括一次以避免函数重定义,变量重新赋值等问题。

 

三、本地文件包含漏洞

1、常见的敏感信息路径

1)Windows

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

2)UNIX/Linux

/etc/passwd
/usr/local/app/apache2/conf/httpd.conf //apache2 默认配置文件
/usr/local/app/apache2/conf/extra/httpd-vhosts.conf //虚拟网站设置
/usr/local/app/php5/lib/php.ini //PHP 相关配置
/etc/httpd/conf/httpd.conf //apache
/etc/php5/apache2/php.ini //ubuntu 系统的默认路径

3)日志默认路径

① apache+Linux 日志默认路径
/etc/httpd/logs/access_log
/var/log/httpd/access_log

② apache+win2003 日志默认路径
D:\xampp\apache\logs\access.log
D:\xampp\apache\logs\error.log

③ IIS6.0+win2003 默认日志文件
C:\WINDOWS\system32\Logfiles

④ IIS7.0+win2003 默认日志文件
%SystemDrive%\inetpub\logs\LogFiles

⑤ nginx 日志文件
日志文件在用户安装目录 logs 目录下
如:/usr/local/nginx/logs

 

2、无限制本地包含漏洞

示例简单源码如下:

<?php
    $filename  = $_GET['filename'];
    include($filename);
?>

通过目录遍历漏洞可以获取到系统中其他文件的内容(../../etc/passwd

 

3、session文件包含漏洞

1)利用条件:session存储位置可以获取

  • 通过phpinfo信息获取session存储位置
  • 猜测默认的session存放位置(Linux默认存放在/var/lib/php/session;Windows默认在C:\WINDOWS\Temp或集成环境下的tmp文件夹里)

2)方法

存在本地文件包含漏洞,可通过ctfs写入恶意代码到session文件中,然后通过文件包含漏洞执行此恶意代码getshell。

示例简单源码如下:

<?php
	session_start();
	$ctfs=$_GET['ctfs'];
	$_SESSION["username"]=$ctfs;
?>

此php会将获取到的GET型ctfs变量的值存入到session中。

当访问http://xxx.com/session.php?ctfs=<?php phpinfo();?> 后,会在/var/lib/php/session目录下存储session的值。攻击者通过phpinfo()信息泄露或者猜测能获取到session存放的位置,文件名称通过开发者模式可获取到,然后通过文件包含的漏洞解析恶意代码getshell。

 

4、有限制本地包含漏洞绕过

1)%00截断

条件:magic_quotes_gpc=OFF & PHP版本<5.3.4

测试:?filename=../../../../../../boot.ini%00

2)路径长度截断

条件:windows下目录路径最大长度为256字节,Linux下目录最大长度为4096字节,超出长度将丢弃。

测试:?filename=text.txt././././. 或 ?filename=test.txt.....

 

四、远程文件包含

服务器的php.ini的配置选项allow_url_fopen和allow_url_include为On,则include/require函数式是可加载远程文件的。

allow_url_fopen = On(是否允许打开远程文件)

allow_url_include = On(是否允许include/require远程文件)

1、有限制远程文件包含漏洞绕过

测试简单源码如下:

<?php include($_GET['filename'] . ".html"); ?>

代码中多添加了html后缀,导致远程包含的文件也会多一个html后缀。

1)问号绕过

?filename=http://../../php.txt?

2)#号绕过

?filenamr=http://../../php.txt%23

3)空格绕过

?filename=http://../../php.txt%20

 

五、PHP伪协议使用

1、php://filter(本地磁盘文件读取)

元封装器,设计用于"数据流打开"时的"筛选过滤"应用,对本地磁盘文件进行读写。

1)条件:只是读取,需要开启allow_url_fopen,不需开启allow_url_include

2)用法如下:

?filename=php://filter/convert.base64-encode/resource=xx.php

?filwname=php://filter/read=convert.base64-encode/resource=xx.php

 

2、php://input(读取post数据、写入一句话木马)

  • 可以访问请求的原始数据的只读流。即可以直接读取到POST上没有经过解析的原始数据。 enctype="multipart/form-data" 的时候 php://input 是无效的。
  • 遇到file_get_contents()就要想着用php://input绕过,因为php伪协议也是可以利用http协议的,即可使用post方式传递数据。

 

3、data://伪协议

数据流封装器,和php://相似都是利用了流的概念,将原本的include的文件流重定向到了用户可控制的输入流中,简单来说就是执行文件的包含方法包含了你的输入流,通过你输入payload来实现目的; data://text/plain;base64,dGhlIHVzZXIgaXMgYWRtaW4

 

4、phar://伪协议

这个参数是就是php解压缩包的一个函数,不管后缀是什么,都会当做压缩包来解压。

1)用法:?file=phar://压缩包/内部文件 phar://xxx.png/shell.php

注意: PHP > =5.3.0 压缩包需要是zip协议压缩,rar不行,将木马文件压缩后,改为其他任意格式的文件都可以正常使用。

2)步骤:写一个一句话木马文件shell.php,然后用zip协议压缩为shell.zip,然后将后缀改为png等其他格式。

 

5、zip://伪协议

zip伪协议和phar协议类似,但是用法不一样。

1)用法:?file=zip://[压缩文件绝对路径]#[压缩文件内的子文件名] zip://xxx.png#shell.php。

2)条件: PHP > =5.3.0,注意在windows下测试要5.3.0<PHP<5.4 才可以,#在浏览器中要编码为%23,否则浏览器默认不会传输特殊字符。

 

六、包含apache 日志

一般情况下 apache 会存在两个日志文件,access.log(访问日志)和 error.log(错误日志)。

当访问一个不存在的资源时,Apache日志同样会记录,并写到accsee.log文件中,这时再去包含
Apache的日志文件,就可以利用包含漏洞。即通过在url处制造错误,从而将错误写入错误日志中并且进行包含错误日志操作,达到getshell的效果。

如果在访问URL后一句话木马在日志文件里变形了(PHP代码中的"<,>,空格"都会被浏览器转码),无法利用Apache包含漏洞,可以通过Burpsuite绕过编码。

 

参考

https://www.cnblogs.com/appear001/p/11149996.html

https://blog.csdn.net/qq_39431542/article/details/88628225

https://www.freebuf.com/articles/web/182280.html

https://www.freebuf.com/articles/web/277756.html

 

posted @ 2021-10-04 03:18  kinyoobi  阅读(831)  评论(0编辑  收藏  举报